int do_debug_lines;
int do_debug_pubnames;
int do_debug_aranges;
+int do_debug_frames;
int do_arch;
int do_notes;
int is_32bit_elf;
static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
static int process_extended_line_op PARAMS ((unsigned char *, int, int));
case FULL_HEX:
printf ("0x");
/* drop through */
-
+
case LONG_HEX:
printf_vma (vma);
break;
-
+
case PREFIX_HEX:
printf ("0x");
/* drop through */
-
+
case HEX:
#if BFD_HOST_64BIT_LONG
printf ("%lx", vma);
printf ("++%ld", _bfd_int64_low (vma));
else
printf ("%ld", _bfd_int64_low (vma));
-#endif
+#endif
break;
case DEC_5:
printf ("++%ld", _bfd_int64_low (vma));
else
printf ("%5ld", _bfd_int64_low (vma));
-#endif
+#endif
break;
-
+
case UNSIGNED:
#if BFD_HOST_64BIT_LONG
printf ("%lu", vma);
-#else
+#else
if (_bfd_int64_high (vma))
/* ugg */
printf ("++%lu", _bfd_int64_low (vma));
case EM_VAX: return "Digital VAX";
case EM_AVR: return "Atmel AVR 8-bit microcontroller";
case EM_CRIS: return "Axis Communications 32-bit embedded processor";
+ case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
+ case EM_FIREPATH: return "Element 14 64-bit DSP processor";
+ case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
+ case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
+ case EM_HUANY: return "Harvard Universitys's machine-independent object format";
+ case EM_PRISM: return "SiTera Prism";
+
default:
sprintf (buff, _("<unknown>: %x"), e_machine);
return buff;
strcat (buf, ", relocatable executable");
e_flags &= ~ EF_ARM_RELEXEC;
}
-
+
if (e_flags & EF_ARM_HASENTRY)
{
strcat (buf, ", has entry point");
e_flags &= ~ EF_ARM_HASENTRY;
}
-
+
/* Now handle EABI specific flags. */
switch (eabi)
{
while (e_flags)
{
unsigned flag;
-
+
/* Process flags one bit at a time. */
flag = e_flags & - e_flags;
e_flags &= ~ flag;
-
+
switch (flag)
{
case EF_ARM_SYMSARESORTED: /* Conflicts with EF_INTERWORK. */
strcat (buf, ", sorted symbol tables");
break;
-
+
default:
unknown = 1;
break;
}
}
break;
-
+
case EF_ARM_EABI_UNKNOWN:
while (e_flags)
{
unsigned flag;
-
+
/* Process flags one bit at a time. */
flag = e_flags & - e_flags;
e_flags &= ~ flag;
-
+
switch (flag)
{
case EF_INTERWORK:
strcat (buf, ", interworking enabled");
break;
-
+
case EF_APCS_26:
strcat (buf, ", uses APCS/26");
break;
-
+
case EF_APCS_FLOAT:
strcat (buf, ", uses APCS/float");
break;
-
+
case EF_PIC:
strcat (buf, ", position independent");
break;
-
+
case EF_ALIGN8:
strcat (buf, ", 8 bit structure alignment");
break;
-
+
case EF_NEW_ABI:
strcat (buf, ", uses new ABI");
break;
-
+
case EF_OLD_ABI:
strcat (buf, ", uses old ABI");
break;
-
+
case EF_SOFT_FLOAT:
strcat (buf, ", software FP");
break;
-
+
default:
unknown = 1;
break;
static char buf [1024];
buf[0] = '\0';
-
+
if (e_flags)
{
switch (e_machine)
case EM_ARM:
decode_ARM_machine_flags (e_flags, buf);
break;
-
+
case EM_68K:
if (e_flags & EF_CPU32)
strcat (buf, ", cpu32");
if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
strcat (buf, ", mips4");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_5)
+ strcat (buf, ", mips5");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32)
+ strcat (buf, ", mips32");
+
+ if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64)
+ strcat (buf, ", mips64");
+
+ switch ((e_flags & EF_MIPS_MACH))
+ {
+ case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
+ case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
+ case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
+ case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
+ case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
+ case E_MIPS_MACH_MIPS32_4K: strcat (buf, ", mips32-4k"); break;
+ default: strcat (buf, " UNKNOWN"); break;
+ }
break;
case EM_SPARCV9:
if (e_flags & EF_PARISC_LAZYSWAP)
strcat (buf, ", lazyswap");
break;
-
+
case EM_PJ:
if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
strcat (buf, ", new calling convention");
case SHT_INIT_ARRAY: return "INIT_ARRAY";
case SHT_FINI_ARRAY: return "FINI_ARRAY";
case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
+ case SHT_GROUP: return "GROUP";
+ case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
case SHT_GNU_verdef: return "VERDEF";
case SHT_GNU_verneed: return "VERNEED";
case SHT_GNU_versym: return "VERSYM";
fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
fprintf (stdout, _(" Dump the contents of section <number>\n"));
- fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
+ fprintf (stdout, _(" -w[liaprf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=frames]\n"));
fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
#ifdef SUPPORT_DISASSEMBLY
fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
do_debug_aranges = 1;
break;
+ case 'f':
+ case 'F':
+ do_debug_frames = 1;
+ break;
+
default:
warn (_("Unrecognised debug option '%s'\n"), optarg);
break;
case ELFOSABI_LINUX: return _("UNIX - Linux");
case ELFOSABI_HURD: return _("GNU/Hurd");
case ELFOSABI_SOLARIS: return _("UNIX - Solaris");
- case ELFOSABI_MONTEREY: return _("UNIX - Monterey");
+ case ELFOSABI_AIX: return _("UNIX - AIX");
case ELFOSABI_IRIX: return _("UNIX - IRIX");
case ELFOSABI_FREEBSD: return _("UNIX - FreeBSD");
case ELFOSABI_TRU64: return _("UNIX - TRU64");
get_machine_name (elf_header.e_machine));
printf (_(" Version: 0x%lx\n"),
(unsigned long) elf_header.e_version);
-
+
printf (_(" Entry point address: "));
print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
printf (_("\n Start of program headers: "));
printf (_(" (bytes into file)\n Start of section headers: "));
print_vma ((bfd_vma) elf_header.e_shoff, DEC);
printf (_(" (bytes into file)\n"));
-
+
printf (_(" Flags: 0x%lx%s\n"),
(unsigned long) elf_header.e_flags,
get_machine_flags (elf_header.e_flags, elf_header.e_machine));
{
printf
(_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
-
+
if (is_32bit_elf)
printf
(_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
static char buff [32];
* buff = 0;
-
+
while (sh_flags)
{
bfd_vma flag;
flag = sh_flags & - sh_flags;
sh_flags &= ~ flag;
-
+
switch (flag)
{
case SHF_WRITE: strcat (buff, "W"); break;
case SHF_INFO_LINK: strcat (buff, "I"); break;
case SHF_LINK_ORDER: strcat (buff, "L"); break;
case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
-
+ case SHF_GROUP: strcat (buff, "G"); break;
+
default:
if (flag & SHF_MASKOS)
{
break;
}
}
-
+
return buff;
}
dynamic_strings, char *, "dynamic strings");
}
else if ((do_debugging || do_debug_info || do_debug_abbrevs
- || do_debug_lines || do_debug_pubnames || do_debug_aranges)
+ || do_debug_lines || do_debug_pubnames || do_debug_aranges || do_debug_frames)
&& strncmp (name, ".debug_", 7) == 0)
{
name += 7;
|| (do_debug_lines && (strcmp (name, "line") == 0))
|| (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
|| (do_debug_aranges && (strcmp (name, "aranges") == 0))
+ || (do_debug_frames && (strcmp (name, "frame") == 0))
)
request_dump (i, DEBUG_DUMP);
}
+ else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
+ request_dump (i, DEBUG_DUMP);
}
if (! do_sections)
return 1;
printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
-
+
if (is_32bit_elf)
printf
(_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
if (is_32bit_elf)
{
print_vma (section->sh_addr, LONG_HEX);
-
+
printf ( " %6.6lx %6.6lx %2.2lx",
(unsigned long) section->sh_offset,
(unsigned long) section->sh_size,
(unsigned long) section->sh_entsize);
printf (" %3s ", get_elf_section_flags (section->sh_flags));
-
- printf (" %2ld %3lx %ld\n",
+
+ printf ("%2ld %3lx %2ld\n",
(unsigned long) section->sh_link,
(unsigned long) section->sh_info,
(unsigned long) section->sh_addralign);
print_vma (section->sh_size, LONG_HEX);
printf (" ");
print_vma (section->sh_entsize, LONG_HEX);
-
+
printf (" %3s ", get_elf_section_flags (section->sh_flags));
-
+
printf (" %2ld %3lx %ld\n",
(unsigned long) section->sh_link,
(unsigned long) section->sh_info,
}
}
- printf (_("Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings)\n"));
- printf (_(" I (info), L (link order), O (extra OS processing required)\n"));
- printf (_(" o (os specific), p (processor specific) x (unknown)\n"));
+ printf (_("Key to Flags:\n"));
+ printf (_(" W (write), A (alloc), X (execute), M (merge), S (strings)\n"));
+ printf (_(" I (info), L (link order), G (group), x (unknown)\n"));
+ printf (_(" O (extra OS processing required) o (OS specific), p (processor specific)\n"));
return 1;
}
first = 0;
val ^= flags[cnt].bit;
}
-
+
if (val != 0 || first)
{
if (! first)
}
}
break;
-
+
default:
print_vma (entry->d_un.d_ptr, PREFIX_HEX);
break;
if (do_dynamic)
printf ("%s", get_dynamic_flags (entry->d_un.d_val));
break;
-
+
case DT_AUXILIARY:
case DT_FILTER:
case DT_CONFIG:
print_vma (psym->st_value, LONG_HEX);
putchar (' ' );
print_vma (psym->st_size, DEC_5);
-
+
printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
/* Check the length of the block. */
info.li_length = BYTE_GET (external->li_length);
- if (info.li_length > section->sh_size)
+ if (info.li_length + sizeof (external->li_length) > section->sh_size)
{
warn
(_("The line info appears to be corrupt - the section is too small\n"));
printf (_(" Line Range: %d\n"), info.li_line_range);
printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
- end_of_sequence = data + info.li_length + sizeof (info.li_length);
+ end_of_sequence = data + info.li_length + sizeof (external->li_length);
reset_state_machine (info.li_default_is_stmt);
warn (_("Only DWARF 2 pubnames are currently supported\n"));
warned = 1;
}
-
+
continue;
}
{
default:
break;
-
+
case DW_FORM_ref_addr:
case DW_FORM_addr:
uvalue = byte_get (data, pointer_size);
case DW_FORM_ref_addr:
printf (" <#%lx>", uvalue);
break;
-
+
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
return 1;
}
+typedef struct Frame_Chunk
+{
+ struct Frame_Chunk *next;
+ unsigned char *chunk_start;
+ int ncols;
+ /* DW_CFA_{undefined,same_value,offset,register} */
+ unsigned char *col_type;
+ int *col_offset;
+ char *augmentation;
+ unsigned int code_factor;
+ unsigned int data_factor;
+ unsigned long pc_begin;
+ unsigned long pc_range;
+ int cfa_reg;
+ int cfa_offset;
+ int ra;
+}
+Frame_Chunk;
+
+static void
+frame_need_space (fc, reg)
+ Frame_Chunk *fc;
+ int reg;
+{
+ int prev = fc->ncols;
+
+ if (reg < fc->ncols)
+ return;
+ fc->ncols = reg + 1;
+ fc->col_type = (unsigned char *) xrealloc (fc->col_type,
+ fc->ncols * sizeof (unsigned char));
+ fc->col_offset = (int *) xrealloc (fc->col_offset,
+ fc->ncols * sizeof (int));
+
+ while (prev < fc->ncols)
+ {
+ fc->col_type[prev] = DW_CFA_undefined;
+ fc->col_offset[prev] = 0;
+ prev++;
+ }
+}
+
+static void
+frame_display_row (fc, need_col_headers, max_regs)
+ Frame_Chunk *fc;
+ int *need_col_headers;
+ int *max_regs;
+{
+ int r;
+ char tmp[100];
+
+ if (*max_regs < fc->ncols)
+ *max_regs = fc->ncols;
+ if (*need_col_headers)
+ {
+ *need_col_headers = 0;
+ printf (" LOC CFA ");
+ for (r=0; r<*max_regs; r++)
+ if (r == fc->ra)
+ printf ("ra ");
+ else
+ printf ("r%-4d", r);
+ printf ("\n");
+ }
+ printf ("%08x ", (unsigned int) fc->pc_begin);
+ sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
+ printf ("%-8s ", tmp);
+ for (r=0; r<fc->ncols; r++)
+ {
+ switch (fc->col_type[r])
+ {
+ case DW_CFA_undefined:
+ strcpy (tmp, "u");
+ break;
+ case DW_CFA_same_value:
+ strcpy (tmp, "s");
+ break;
+ case DW_CFA_offset:
+ sprintf (tmp, "c%+d", fc->col_offset[r]);
+ break;
+ case DW_CFA_register:
+ sprintf (tmp, "r%d", fc->col_offset[r]);
+ break;
+ default:
+ strcpy (tmp, "n/a");
+ break;
+ }
+ printf ("%-5s", tmp);
+ }
+ printf ("\n");
+}
+
+#define GET(N) byte_get (start, N); start += N
+#define LEB() read_leb128 (start, &length_return, 0); start += length_return
+#define SLEB() read_leb128 (start, &length_return, 1); start += length_return
+
+static int
+display_debug_frames (section, start, file)
+ Elf32_Internal_Shdr * section;
+ unsigned char * start;
+ FILE * file ATTRIBUTE_UNUSED;
+{
+ unsigned char * end = start + section->sh_size;
+ unsigned char *section_start = start;
+ Frame_Chunk *chunks = 0;
+ Frame_Chunk *remembered_state = 0, *rs;
+ int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
+ int length_return;
+ int max_regs = 0;
+
+ printf (_("The section %s contains:\n"), SECTION_NAME (section));
+
+ while (start < end)
+ {
+ unsigned char *saved_start, *block_end;
+ unsigned long length, cie_id;
+ Frame_Chunk *fc, *cie;
+ int need_col_headers = 1;
+
+ saved_start = start;
+ length = byte_get (start, 4); start += 4;
+
+ if (length == 0)
+ return 1;
+
+ block_end = saved_start + length + 4;
+ cie_id = byte_get (start, 4); start += 4;
+
+ printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
+
+ if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
+ {
+ fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+ memset (fc, 0, sizeof (Frame_Chunk));
+
+ fc->next = chunks;
+ chunks = fc;
+ fc->chunk_start = saved_start;
+ fc->ncols = 0;
+ fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
+ fc->col_offset = (int *) xmalloc (sizeof (int));
+ frame_need_space (fc, max_regs-1);
+
+ start ++; /* version */
+ fc->augmentation = start;
+ while (*start) start++; start++; /* skip past NUL */
+ if (fc->augmentation[0] == 'z')
+ {
+ int xtra;
+ fc->code_factor = LEB ();
+ fc->data_factor = SLEB ();
+ fc->ra = byte_get (start, 1); start += 1;
+ xtra = LEB ();
+ printf ("skipping %d extra bytes\n", xtra);
+ start += xtra;
+ }
+ else if (strcmp (fc->augmentation, "eh") == 0)
+ {
+ start += 4;
+ fc->code_factor = LEB ();
+ fc->data_factor = SLEB ();
+ fc->ra = byte_get (start, 1); start += 1;
+ }
+ else
+ {
+ fc->code_factor = LEB ();
+ fc->data_factor = SLEB ();
+ fc->ra = byte_get (start, 1); start += 1;
+ }
+ cie = fc;
+ printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
+ fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
+
+ frame_need_space (fc, fc->ra);
+ }
+ else
+ {
+ unsigned char *look_for;
+ static Frame_Chunk fde_fc;
+ fc = &fde_fc;
+ memset (fc, 0, sizeof (Frame_Chunk));
+
+ look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
+
+ fc->pc_begin = byte_get (start, 4); start += 4;
+ fc->pc_range = byte_get (start, 4); start += 4;
+
+ for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
+ if (!cie)
+ {
+ warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
+ start = block_end;
+ fc->ncols = 0;
+ fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
+ fc->col_offset = (int *) xmalloc (sizeof (int));
+ frame_need_space (fc, max_regs-1);
+ cie = fc;
+ fc->augmentation = "";
+ }
+ else
+ {
+ fc->ncols = cie->ncols;
+ fc->col_type = (unsigned char *) xmalloc (fc->ncols * sizeof (unsigned char));
+ fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
+ memcpy (fc->col_type, cie->col_type, fc->ncols);
+ memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
+ fc->augmentation = cie->augmentation;
+ fc->code_factor = cie->code_factor;
+ fc->data_factor = cie->data_factor;
+ fc->cfa_reg = cie->cfa_reg;
+ fc->cfa_offset = cie->cfa_offset;
+ fc->ra = cie->ra;
+ frame_need_space (fc, max_regs-1);
+ }
+
+ if (cie->augmentation[0] == 'z')
+ {
+ unsigned long l = LEB ();
+ start += l;
+ }
+
+ printf ("FDE cie=%08x pc=%08lx..%08lx\n",
+ cie->chunk_start-section_start, fc->pc_begin,
+ fc->pc_begin + fc->pc_range);
+ }
+
+ /* At this point, fc is the current chunk, cie (if any) is set, and we're
+ about to interpret instructions for the chunk. */
+
+ /* This exists for readelf maintainers. */
+#define FDEBUG 0
+
+ while (start < block_end)
+ {
+ unsigned op, opa;
+ unsigned long ul, reg, roffs;
+ long l, ofs;
+ bfd_vma vma;
+
+ op = * start ++;
+ opa = op & 0x3f;
+ if (op & 0xc0)
+ op &= 0xc0;
+
+ switch (op)
+ {
+ case DW_CFA_advance_loc:
+ frame_display_row (fc, &need_col_headers, &max_regs);
+#if FDEBUG
+ printf (" DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
+ fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
+#endif
+ fc->pc_begin += opa * fc->code_factor;
+ break;
+
+ case DW_CFA_offset:
+ frame_need_space (fc, opa);
+ roffs = LEB ();
+#if FDEBUG
+ printf (" DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
+#endif
+ fc->col_type[opa] = DW_CFA_offset;
+ fc->col_offset[opa] = roffs * fc->data_factor;
+ break;
+
+ case DW_CFA_restore:
+ frame_need_space (fc, opa);
+#if FDEBUG
+ printf (" DW_CFA_restore: r%d\n", opa);
+#endif
+ fc->col_type[opa] = cie->col_type[opa];
+ fc->col_offset[opa] = cie->col_offset[opa];
+ break;
+
+ case DW_CFA_set_loc:
+ frame_display_row (fc, &need_col_headers, &max_regs);
+ vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
+#if FDEBUG
+ printf (" DW_CFA_set_loc: %08x\n", vma);
+#endif
+ fc->pc_begin = vma;
+ break;
+
+ case DW_CFA_advance_loc1:
+ frame_display_row (fc, &need_col_headers, &max_regs);
+ ofs = byte_get (start, 1); start += 1;
+#if FDEBUG
+ printf (" DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
+ fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+#endif
+ fc->pc_begin += ofs * fc->code_factor;
+ break;
+
+ case DW_CFA_advance_loc2:
+ frame_display_row (fc, &need_col_headers, &max_regs);
+ ofs = byte_get (start, 2); start += 2;
+#if FDEBUG
+ printf (" DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
+ fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+#endif
+ fc->pc_begin += ofs * fc->code_factor;
+ break;
+
+ case DW_CFA_advance_loc4:
+ frame_display_row (fc, &need_col_headers, &max_regs);
+ ofs = byte_get (start, 4); start += 4;
+#if FDEBUG
+ printf (" DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
+ fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
+#endif
+ fc->pc_begin += ofs * fc->code_factor;
+ break;
+
+ case DW_CFA_offset_extended:
+ reg = LEB ();
+ roffs = LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
+#endif
+ fc->col_type[reg] = DW_CFA_offset;
+ fc->col_offset[reg] = roffs * fc->data_factor;
+ break;
+
+ case DW_CFA_restore_extended:
+ reg = LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_restore_extended: r%d\n", reg);
+#endif
+ fc->col_type[reg] = cie->col_type[reg];
+ fc->col_offset[reg] = cie->col_offset[reg];
+ break;
+
+ case DW_CFA_undefined:
+ reg = LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_undefined: r%d\n", reg);
+#endif
+ fc->col_type[reg] = DW_CFA_undefined;
+ fc->col_offset[reg] = 0;
+ break;
+
+ case DW_CFA_same_value:
+ reg = LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_same_value: r%d\n", reg);
+#endif
+ fc->col_type[reg] = DW_CFA_same_value;
+ fc->col_offset[reg] = 0;
+ break;
+
+ case DW_CFA_register:
+ reg = LEB ();
+ roffs = LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_ame_value: r%d\n", reg);
+#endif
+ fc->col_type[reg] = DW_CFA_register;
+ fc->col_offset[reg] = roffs;
+ break;
+
+ case DW_CFA_remember_state:
+#if FDEBUG
+ printf (" DW_CFA_remember_state\n");
+#endif
+ rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
+ rs->ncols = fc->ncols;
+ rs->col_type = (unsigned char *) xmalloc (rs->ncols);
+ rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
+ memcpy (rs->col_type, fc->col_type, rs->ncols);
+ memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
+ rs->next = remembered_state;
+ remembered_state = rs;
+ break;
+
+ case DW_CFA_restore_state:
+#if FDEBUG
+ printf (" DW_CFA_restore_state\n");
+#endif
+ rs = remembered_state;
+ remembered_state = rs->next;
+ frame_need_space (fc, rs->ncols-1);
+ memcpy (fc->col_type, rs->col_type, rs->ncols);
+ memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
+ free (rs->col_type);
+ free (rs->col_offset);
+ free (rs);
+ break;
+
+ case DW_CFA_def_cfa:
+ fc->cfa_reg = LEB ();
+ fc->cfa_offset = LEB ();
+#if FDEBUG
+ printf (" DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
+#endif
+ break;
+
+ case DW_CFA_def_cfa_register:
+ fc->cfa_reg = LEB ();
+#if FDEBUG
+ printf (" DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
+#endif
+ break;
+
+ case DW_CFA_def_cfa_offset:
+ fc->cfa_offset = LEB ();
+#if FDEBUG
+ printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
+#endif
+ break;
+
+ case DW_CFA_nop:
+#if FDEBUG
+ printf (" DW_CFA_nop\n");
+#endif
+ break;
+
+#ifndef DW_CFA_GNU_window_save
+#define DW_CFA_GNU_window_save 0x2d
+#endif
+ case DW_CFA_GNU_window_save:
+#if FDEBUG
+ printf (" DW_CFA_GNU_window_save\n");
+#endif
+ break;
+
+#ifndef DW_CFA_GNU_args_size
+#define DW_CFA_GNU_args_size 0x2e
+#endif
+ case DW_CFA_GNU_args_size:
+ ul = LEB ();
+#if FDEBUG
+ printf (" DW_CFA_GNU_args_size: %d\n", ul);
+#endif
+ break;
+
+#ifndef DW_CFA_GNU_negative_offset_extended
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+#endif
+ case DW_CFA_GNU_negative_offset_extended:
+ reg = LEB ();
+ l = - LEB ();
+ frame_need_space (fc, reg);
+#if FDEBUG
+ printf (" DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
+#endif
+ fc->col_type[reg] = DW_CFA_offset;
+ fc->col_offset[reg] = l * fc->data_factor;
+ break;
+
+ default:
+ fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
+ start = block_end;
+ }
+ }
+
+ frame_display_row (fc, &need_col_headers, &max_regs);
+
+ start = block_end;
+ }
+
+ printf ("\n");
+
+ return 1;
+}
+
+#undef GET
+#undef LEB
+#undef SLEB
static int
display_debug_not_supported (section, start, file)
{ ".debug_line", display_debug_lines, NULL },
{ ".debug_aranges", display_debug_aranges, NULL },
{ ".debug_pubnames", display_debug_pubnames, NULL },
+ { ".debug_frame", display_debug_frames, NULL },
+ { ".eh_frame", display_debug_frames, NULL },
{ ".debug_macinfo", display_debug_not_supported, NULL },
{ ".debug_frame", display_debug_not_supported, NULL },
{ ".debug_str", display_debug_not_supported, NULL },
offset = cnt = 0;
option = iopt;
-
+
while (offset < sect->sh_size)
{
Elf_External_Options * eoption;
option->info = BYTE_GET (eoption->info);
offset += option->size;
-
+
++option;
++cnt;
}
string_table + sect->sh_name, cnt);
option = iopt;
-
+
while (cnt-- > 0)
{
size_t len;
inote.descsz = BYTE_GET (external->descsz);
inote.descdata = inote.namedata + align_power (inote.namesz, 2);
inote.descpos = offset + (inote.descdata - (char *) pnotes);
-
+
external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
/* Verify that name is null terminated. It appears that at least
if (inote.namedata[inote.namesz] != '\0')
{
temp = malloc (inote.namesz + 1);
-
+
if (temp == NULL)
{
error (_("Out of memory\n"));
res = 0;
break;
}
-
+
strncpy (temp, inote.namedata, inote.namesz);
temp[inote.namesz] = 0;
-
+
/* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
inote.namedata = temp;
}