mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
* readelf.c (ia64_process_unwind): Turn into a void funtion.
(hppa_process_unwind): Likewise. (arm_process_unwind): Likewise. (process_unwind): Likewise. (arm_get_section_word): Rename to get_unwind_section_word. Add sym_name parameter to return the offset into the string table of the symbol associated with the reloc applied to the word. (decode_tic6x_unwind_regmask): Add NULL argument to invocation of get_unwind_section_word. (dump_arm_unwind): Likewise. (decode_arm_unwind_bytecode): Prepend a comma when *not* the first register in a list. (decode_arm_unwind): If the returned function address is 0 and a valid symname offset is provided use that to compute the name associated with the entry. Add extra checks of the compact model index entry.
This commit is contained in:
@ -1,3 +1,22 @@
|
|||||||
|
2011-12-02 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* readelf.c (ia64_process_unwind): Turn into a void funtion.
|
||||||
|
(hppa_process_unwind): Likewise.
|
||||||
|
(arm_process_unwind): Likewise.
|
||||||
|
(process_unwind): Likewise.
|
||||||
|
(arm_get_section_word): Rename to get_unwind_section_word.
|
||||||
|
Add sym_name parameter to return the offset into the string table
|
||||||
|
of the symbol associated with the reloc applied to the word.
|
||||||
|
(decode_tic6x_unwind_regmask): Add NULL argument to invocation of
|
||||||
|
get_unwind_section_word.
|
||||||
|
(dump_arm_unwind): Likewise.
|
||||||
|
(decode_arm_unwind_bytecode): Prepend a comma when *not* the first
|
||||||
|
register in a list.
|
||||||
|
(decode_arm_unwind): If the returned function address is 0 and a
|
||||||
|
valid symname offset is provided use that to compute the name
|
||||||
|
associated with the entry.
|
||||||
|
Add extra checks of the compact model index entry.
|
||||||
|
|
||||||
2011-11-29 Roland McGrath <mcgrathr@google.com>
|
2011-11-29 Roland McGrath <mcgrathr@google.com>
|
||||||
|
|
||||||
* ar.c (ranlib_usage): Describe -D.
|
* ar.c (ranlib_usage): Describe -D.
|
||||||
|
@ -3187,7 +3187,7 @@ usage (FILE * stream)
|
|||||||
-u --unwind Display the unwind info (if present)\n\
|
-u --unwind Display the unwind info (if present)\n\
|
||||||
-d --dynamic Display the dynamic section (if present)\n\
|
-d --dynamic Display the dynamic section (if present)\n\
|
||||||
-V --version-info Display the version sections (if present)\n\
|
-V --version-info Display the version sections (if present)\n\
|
||||||
-A --arch-specific Display architecture specific information (if any).\n\
|
-A --arch-specific Display architecture specific information (if any)\n\
|
||||||
-c --archive-index Display the symbol/file index in an archive\n\
|
-c --archive-index Display the symbol/file index in an archive\n\
|
||||||
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
||||||
-x --hex-dump=<number|name>\n\
|
-x --hex-dump=<number|name>\n\
|
||||||
@ -5595,6 +5595,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best)
|
if (best)
|
||||||
{
|
{
|
||||||
*symname = (best->st_name >= strtab_size
|
*symname = (best->st_name >= strtab_size
|
||||||
@ -5602,6 +5603,7 @@ find_symbol_for_address (Elf_Internal_Sym * symtab,
|
|||||||
*offset = dist;
|
*offset = dist;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*symname = NULL;
|
*symname = NULL;
|
||||||
*offset = addr.offset;
|
*offset = addr.offset;
|
||||||
}
|
}
|
||||||
@ -5779,7 +5781,7 @@ slurp_ia64_unwind_table (FILE * file,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
ia64_process_unwind (FILE * file)
|
ia64_process_unwind (FILE * file)
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr * sec;
|
Elf_Internal_Shdr * sec;
|
||||||
@ -5916,8 +5918,6 @@ ia64_process_unwind (FILE * file)
|
|||||||
free (aux.symtab);
|
free (aux.symtab);
|
||||||
if (aux.strtab)
|
if (aux.strtab)
|
||||||
free ((char *) aux.strtab);
|
free ((char *) aux.strtab);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hppa_unw_table_entry
|
struct hppa_unw_table_entry
|
||||||
@ -6189,7 +6189,7 @@ slurp_hppa_unwind_table (FILE * file,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
hppa_process_unwind (FILE * file)
|
hppa_process_unwind (FILE * file)
|
||||||
{
|
{
|
||||||
struct hppa_unw_aux_info aux;
|
struct hppa_unw_aux_info aux;
|
||||||
@ -6198,10 +6198,10 @@ hppa_process_unwind (FILE * file)
|
|||||||
Elf_Internal_Shdr * sec;
|
Elf_Internal_Shdr * sec;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
memset (& aux, 0, sizeof (aux));
|
|
||||||
|
|
||||||
if (string_table == NULL)
|
if (string_table == NULL)
|
||||||
return 1;
|
return;
|
||||||
|
|
||||||
|
memset (& aux, 0, sizeof (aux));
|
||||||
|
|
||||||
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
@ -6249,8 +6249,6 @@ hppa_process_unwind (FILE * file)
|
|||||||
free (aux.symtab);
|
free (aux.symtab);
|
||||||
if (aux.strtab)
|
if (aux.strtab)
|
||||||
free ((char *) aux.strtab);
|
free ((char *) aux.strtab);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct arm_section
|
struct arm_section
|
||||||
@ -6315,17 +6313,21 @@ arm_free_section (struct arm_section *arm_sec)
|
|||||||
cached section and install SEC instead.
|
cached section and install SEC instead.
|
||||||
2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
|
2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
|
||||||
and return its valued in * WORDP, relocating if necessary.
|
and return its valued in * WORDP, relocating if necessary.
|
||||||
3) Update the NEXT_RELA field in ARM_SEC and stores the section index and
|
3) Update the NEXT_RELA field in ARM_SEC and store the section index and
|
||||||
relocation's offset in ADDR.
|
relocation's offset in ADDR.
|
||||||
4) Return TRUE upon success, FALSE otherwise. */
|
4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
|
||||||
|
into the string table of the symbol associated with the reloc. If no
|
||||||
|
reloc was applied store -1 there.
|
||||||
|
5) Return TRUE upon success, FALSE otherwise. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
arm_section_get_word (struct arm_unw_aux_info * aux,
|
get_unwind_section_word (struct arm_unw_aux_info * aux,
|
||||||
struct arm_section * arm_sec,
|
struct arm_section * arm_sec,
|
||||||
Elf_Internal_Shdr * sec,
|
Elf_Internal_Shdr * sec,
|
||||||
bfd_vma word_offset,
|
bfd_vma word_offset,
|
||||||
unsigned int * wordp,
|
unsigned int * wordp,
|
||||||
struct absaddr * addr)
|
struct absaddr * addr,
|
||||||
|
bfd_vma * sym_name)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela *rp;
|
Elf_Internal_Rela *rp;
|
||||||
Elf_Internal_Sym *sym;
|
Elf_Internal_Sym *sym;
|
||||||
@ -6336,6 +6338,9 @@ arm_section_get_word (struct arm_unw_aux_info * aux,
|
|||||||
addr->section = SHN_UNDEF;
|
addr->section = SHN_UNDEF;
|
||||||
addr->offset = 0;
|
addr->offset = 0;
|
||||||
|
|
||||||
|
if (sym_name != NULL)
|
||||||
|
*sym_name = (bfd_vma) -1;
|
||||||
|
|
||||||
/* If necessary, update the section cache. */
|
/* If necessary, update the section cache. */
|
||||||
if (sec != arm_sec->sec)
|
if (sec != arm_sec->sec)
|
||||||
{
|
{
|
||||||
@ -6465,6 +6470,8 @@ arm_section_get_word (struct arm_unw_aux_info * aux,
|
|||||||
word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
|
word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
|
||||||
addr->section = sym->st_shndx;
|
addr->section = sym->st_shndx;
|
||||||
addr->offset = offset;
|
addr->offset = offset;
|
||||||
|
if (sym_name)
|
||||||
|
* sym_name = sym->st_name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6501,8 +6508,8 @@ decode_tic6x_unwind_regmask (unsigned int mask)
|
|||||||
if (remaining == 0 && more_words) \
|
if (remaining == 0 && more_words) \
|
||||||
{ \
|
{ \
|
||||||
data_offset += 4; \
|
data_offset += 4; \
|
||||||
if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
|
if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
|
||||||
data_offset, &word, &addr)) \
|
data_offset, & word, & addr, NULL)) \
|
||||||
return; \
|
return; \
|
||||||
remaining = 4; \
|
remaining = 4; \
|
||||||
more_words--; \
|
more_words--; \
|
||||||
@ -6606,7 +6613,7 @@ decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
|
|||||||
}
|
}
|
||||||
if (op & 0x08)
|
if (op & 0x08)
|
||||||
{
|
{
|
||||||
if (first)
|
if (!first)
|
||||||
printf (", ");
|
printf (", ");
|
||||||
printf ("r14");
|
printf ("r14");
|
||||||
}
|
}
|
||||||
@ -6884,20 +6891,28 @@ arm_expand_prel31 (bfd_vma word, bfd_vma where)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
decode_arm_unwind (struct arm_unw_aux_info * aux,
|
decode_arm_unwind (struct arm_unw_aux_info * aux,
|
||||||
unsigned int word, unsigned int remaining,
|
unsigned int word,
|
||||||
bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
|
unsigned int remaining,
|
||||||
|
bfd_vma data_offset,
|
||||||
|
Elf_Internal_Shdr * data_sec,
|
||||||
struct arm_section * data_arm_sec)
|
struct arm_section * data_arm_sec)
|
||||||
{
|
{
|
||||||
int per_index;
|
int per_index;
|
||||||
unsigned int more_words = 0;
|
unsigned int more_words = 0;
|
||||||
struct absaddr addr;
|
struct absaddr addr;
|
||||||
|
bfd_vma sym_name = (bfd_vma) -1;
|
||||||
|
|
||||||
if (remaining == 0)
|
if (remaining == 0)
|
||||||
{
|
{
|
||||||
/* Fetch the first word. */
|
/* Fetch the first word.
|
||||||
if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
|
Note - when decoding an object file the address extracted
|
||||||
&word, &addr))
|
here will always be 0. So we also pass in the sym_name
|
||||||
|
parameter so that we can find the symbol associated with
|
||||||
|
the personality routine. */
|
||||||
|
if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
|
||||||
|
& word, & addr, & sym_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
remaining = 4;
|
remaining = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6909,6 +6924,20 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
|
|||||||
|
|
||||||
fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
|
fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
|
||||||
printf (_(" Personality routine: "));
|
printf (_(" Personality routine: "));
|
||||||
|
if (fn == 0
|
||||||
|
&& addr.section == SHN_UNDEF && addr.offset == 0
|
||||||
|
&& sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
|
||||||
|
{
|
||||||
|
procname = aux->strtab + sym_name;
|
||||||
|
print_vma (fn, PREFIX_HEX);
|
||||||
|
if (procname)
|
||||||
|
{
|
||||||
|
fputs (" <", stdout);
|
||||||
|
fputs (procname, stdout);
|
||||||
|
fputc ('>', stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
procname = arm_print_vma_and_name (aux, fn, addr);
|
procname = arm_print_vma_and_name (aux, fn, addr);
|
||||||
fputc ('\n', stdout);
|
fputc ('\n', stdout);
|
||||||
|
|
||||||
@ -6939,9 +6968,20 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* ARM EHABI Section 6.3:
|
||||||
|
|
||||||
|
An exception-handling table entry for the compact model looks like:
|
||||||
|
|
||||||
|
31 30-28 27-24 23-0
|
||||||
|
-- ----- ----- ----
|
||||||
|
1 0 index Data for personalityRoutine[index] */
|
||||||
|
|
||||||
|
if (elf_header.e_machine == EM_ARM
|
||||||
|
&& (word & 0x70000000))
|
||||||
|
warn (_("Corrupt ARM compact model table entry (%08x)\n"), word);
|
||||||
|
|
||||||
per_index = (word >> 24) & 0x7f;
|
per_index = (word >> 24) & 0x7f;
|
||||||
printf (_(" Compact model %d\n"), per_index);
|
printf (_(" Compact model index: %d\n"), per_index);
|
||||||
if (per_index == 0)
|
if (per_index == 0)
|
||||||
{
|
{
|
||||||
more_words = 0;
|
more_words = 0;
|
||||||
@ -6965,7 +7005,10 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
|
|||||||
data_offset, data_sec, data_arm_sec);
|
data_offset, data_sec, data_arm_sec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf (" [reserved]\n");
|
{
|
||||||
|
warn (_("Unknown ARM compact model index encountered\n"));
|
||||||
|
printf (_(" [reserved]\n"));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM_TI_C6000:
|
case EM_TI_C6000:
|
||||||
@ -6989,11 +7032,12 @@ decode_arm_unwind (struct arm_unw_aux_info *aux,
|
|||||||
tic6x_unwind_regnames[word & 0xf]);
|
tic6x_unwind_regnames[word & 0xf]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf (" [reserved]\n");
|
printf (_(" [reserved (%d)]\n"), per_index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
error (_("Unsupported architecture type %d encountered when decoding unwind table"),
|
||||||
|
elf_header.e_machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode the descriptors. Not implemented. */
|
/* Decode the descriptors. Not implemented. */
|
||||||
@ -7017,10 +7061,10 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
|
|||||||
|
|
||||||
fputc ('\n', stdout);
|
fputc ('\n', stdout);
|
||||||
|
|
||||||
if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
|
if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
|
||||||
8 * i, &exidx_fn, &fn_addr)
|
8 * i, & exidx_fn, & fn_addr, NULL)
|
||||||
|| !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
|
|| ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
|
||||||
8 * i + 4, &exidx_entry, &entry_addr))
|
8 * i + 4, & exidx_entry, & entry_addr, NULL))
|
||||||
{
|
{
|
||||||
arm_free_section (& exidx_arm_sec);
|
arm_free_section (& exidx_arm_sec);
|
||||||
arm_free_section (& extab_arm_sec);
|
arm_free_section (& extab_arm_sec);
|
||||||
@ -7084,7 +7128,8 @@ dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Used for both ARM and C6X unwinding tables. */
|
/* Used for both ARM and C6X unwinding tables. */
|
||||||
static int
|
|
||||||
|
static void
|
||||||
arm_process_unwind (FILE *file)
|
arm_process_unwind (FILE *file)
|
||||||
{
|
{
|
||||||
struct arm_unw_aux_info aux;
|
struct arm_unw_aux_info aux;
|
||||||
@ -7094,9 +7139,6 @@ arm_process_unwind (FILE *file)
|
|||||||
unsigned long i;
|
unsigned long i;
|
||||||
unsigned int sec_type;
|
unsigned int sec_type;
|
||||||
|
|
||||||
memset (& aux, 0, sizeof (aux));
|
|
||||||
aux.file = file;
|
|
||||||
|
|
||||||
switch (elf_header.e_machine)
|
switch (elf_header.e_machine)
|
||||||
{
|
{
|
||||||
case EM_ARM:
|
case EM_ARM:
|
||||||
@ -7108,11 +7150,16 @@ arm_process_unwind (FILE *file)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort();
|
error (_("Unsupported architecture type %d encountered when processing unwind table"),
|
||||||
|
elf_header.e_machine);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_table == NULL)
|
if (string_table == NULL)
|
||||||
return 1;
|
return;
|
||||||
|
|
||||||
|
memset (& aux, 0, sizeof (aux));
|
||||||
|
aux.file = file;
|
||||||
|
|
||||||
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
@ -7130,9 +7177,9 @@ arm_process_unwind (FILE *file)
|
|||||||
unwsec = sec;
|
unwsec = sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unwsec)
|
if (unwsec == NULL)
|
||||||
printf (_("\nThere are no unwind sections in this file.\n"));
|
printf (_("\nThere are no unwind sections in this file.\n"));
|
||||||
|
else
|
||||||
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
||||||
{
|
{
|
||||||
if (sec->sh_type == sec_type)
|
if (sec->sh_type == sec_type)
|
||||||
@ -7150,17 +7197,15 @@ arm_process_unwind (FILE *file)
|
|||||||
free (aux.symtab);
|
free (aux.symtab);
|
||||||
if (aux.strtab)
|
if (aux.strtab)
|
||||||
free ((char *) aux.strtab);
|
free ((char *) aux.strtab);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
process_unwind (FILE * file)
|
process_unwind (FILE * file)
|
||||||
{
|
{
|
||||||
struct unwind_handler
|
struct unwind_handler
|
||||||
{
|
{
|
||||||
int machtype;
|
int machtype;
|
||||||
int (* handler)(FILE *);
|
void (* handler)(FILE *);
|
||||||
} handlers[] =
|
} handlers[] =
|
||||||
{
|
{
|
||||||
{ EM_ARM, arm_process_unwind },
|
{ EM_ARM, arm_process_unwind },
|
||||||
@ -7172,14 +7217,14 @@ process_unwind (FILE * file)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!do_unwind)
|
if (!do_unwind)
|
||||||
return 1;
|
return;
|
||||||
|
|
||||||
for (i = 0; handlers[i].handler != NULL; i++)
|
for (i = 0; handlers[i].handler != NULL; i++)
|
||||||
if (elf_header.e_machine == handlers[i].machtype)
|
if (elf_header.e_machine == handlers[i].machtype)
|
||||||
return handlers[i].handler (file);
|
return handlers[i].handler (file);
|
||||||
|
|
||||||
printf (_("\nThere are no unwind sections in this file.\n"));
|
printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
|
||||||
return 1;
|
get_machine_name (elf_header.e_machine));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user