* readelf.c (ia64_unw_aux_info, ia64_unw_table_entry): Rename from
unw_aux_info and unw_table_entry. (find_symbol_for_address): Pass symtab and strtab info explicitly. (dump_ia64_unwind): Rename unw_{aux_info,table_entry} with ia64_ prefix. (slurp_ia64_unwind_table): Likewise. (ia64_process_unwind): Rename from old process_unwind. (hppa_unw_aux_info): New. (dump_hppa_unwind): New. (slurp_hppa_unwind_table): New. (hppa_process_unwind): New. (process_unwind): Factor out common unwinding checks; dispatch to unwind handler based on machine type.
This commit is contained in:
parent
2b4f075ada
commit
57346661b5
2 changed files with 420 additions and 38 deletions
|
@ -1,3 +1,19 @@
|
||||||
|
2004-11-03 Randolph Chung <tausq@debian.org>
|
||||||
|
|
||||||
|
* readelf.c (ia64_unw_aux_info, ia64_unw_table_entry): Rename from
|
||||||
|
unw_aux_info and unw_table_entry.
|
||||||
|
(find_symbol_for_address): Pass symtab and strtab info explicitly.
|
||||||
|
(dump_ia64_unwind): Rename unw_{aux_info,table_entry} with ia64_
|
||||||
|
prefix.
|
||||||
|
(slurp_ia64_unwind_table): Likewise.
|
||||||
|
(ia64_process_unwind): Rename from old process_unwind.
|
||||||
|
(hppa_unw_aux_info): New.
|
||||||
|
(dump_hppa_unwind): New.
|
||||||
|
(slurp_hppa_unwind_table): New.
|
||||||
|
(hppa_process_unwind): New.
|
||||||
|
(process_unwind): Factor out common unwinding checks; dispatch to
|
||||||
|
unwind handler based on machine type.
|
||||||
|
|
||||||
2004-11-02 Nick Clifton <nickc@redhat.com>
|
2004-11-02 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* readelf.c (display_debug_lines): Fix typo in error message.
|
* readelf.c (display_debug_lines): Fix typo in error message.
|
||||||
|
|
|
@ -1894,7 +1894,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
|
||||||
default:
|
default:
|
||||||
strcat (buf, ", fr???");
|
strcat (buf, ", fr???");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EF_FRV_CPU_FR300:
|
case EF_FRV_CPU_FR300:
|
||||||
strcat (buf, ", fr300");
|
strcat (buf, ", fr300");
|
||||||
break;
|
break;
|
||||||
|
@ -2071,7 +2071,7 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EM_SPARCV9:
|
case EM_SPARCV9:
|
||||||
if (e_flags & EF_SPARC_32PLUS)
|
if (e_flags & EF_SPARC_32PLUS)
|
||||||
strcat (buf, ", v8+");
|
strcat (buf, ", v8+");
|
||||||
|
@ -4171,7 +4171,7 @@ process_relocs (FILE *file)
|
||||||
unsigned long nsyms;
|
unsigned long nsyms;
|
||||||
unsigned long strtablen;
|
unsigned long strtablen;
|
||||||
char *strtab = NULL;
|
char *strtab = NULL;
|
||||||
|
|
||||||
symsec = SECTION_HEADER (section->sh_link);
|
symsec = SECTION_HEADER (section->sh_link);
|
||||||
nsyms = symsec->sh_size / symsec->sh_entsize;
|
nsyms = symsec->sh_size / symsec->sh_entsize;
|
||||||
symtab = GET_ELF_SYMBOLS (file, symsec);
|
symtab = GET_ELF_SYMBOLS (file, symsec);
|
||||||
|
@ -4206,6 +4206,8 @@ process_relocs (FILE *file)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process the unwind section. */
|
||||||
|
|
||||||
#include "unwind-ia64.h"
|
#include "unwind-ia64.h"
|
||||||
|
|
||||||
/* An absolute address consists of a section and an offset. If the
|
/* An absolute address consists of a section and an offset. If the
|
||||||
|
@ -4218,9 +4220,9 @@ struct absaddr
|
||||||
bfd_vma offset;
|
bfd_vma offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct unw_aux_info
|
struct ia64_unw_aux_info
|
||||||
{
|
{
|
||||||
struct unw_table_entry
|
struct ia64_unw_table_entry
|
||||||
{
|
{
|
||||||
struct absaddr start;
|
struct absaddr start;
|
||||||
struct absaddr end;
|
struct absaddr end;
|
||||||
|
@ -4239,7 +4241,10 @@ struct unw_aux_info
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_symbol_for_address (struct unw_aux_info *aux,
|
find_symbol_for_address (Elf_Internal_Sym *symtab,
|
||||||
|
unsigned long nsyms,
|
||||||
|
const char *strtab,
|
||||||
|
unsigned long strtab_size,
|
||||||
struct absaddr addr,
|
struct absaddr addr,
|
||||||
const char **symname,
|
const char **symname,
|
||||||
bfd_vma *offset)
|
bfd_vma *offset)
|
||||||
|
@ -4248,7 +4253,7 @@ find_symbol_for_address (struct unw_aux_info *aux,
|
||||||
Elf_Internal_Sym *sym, *best = NULL;
|
Elf_Internal_Sym *sym, *best = NULL;
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
|
for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
|
||||||
{
|
{
|
||||||
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
|
if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
|
||||||
&& sym->st_name != 0
|
&& sym->st_name != 0
|
||||||
|
@ -4264,8 +4269,8 @@ find_symbol_for_address (struct unw_aux_info *aux,
|
||||||
}
|
}
|
||||||
if (best)
|
if (best)
|
||||||
{
|
{
|
||||||
*symname = (best->st_name >= aux->strtab_size
|
*symname = (best->st_name >= strtab_size
|
||||||
? "<corrupt>" : aux->strtab + best->st_name);
|
? "<corrupt>" : strtab + best->st_name);
|
||||||
*offset = dist;
|
*offset = dist;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4274,10 +4279,10 @@ find_symbol_for_address (struct unw_aux_info *aux,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_ia64_unwind (struct unw_aux_info *aux)
|
dump_ia64_unwind (struct ia64_unw_aux_info *aux)
|
||||||
{
|
{
|
||||||
bfd_vma addr_size;
|
bfd_vma addr_size;
|
||||||
struct unw_table_entry *tp;
|
struct ia64_unw_table_entry *tp;
|
||||||
int in_body;
|
int in_body;
|
||||||
|
|
||||||
addr_size = is_32bit_elf ? 4 : 8;
|
addr_size = is_32bit_elf ? 4 : 8;
|
||||||
|
@ -4290,7 +4295,8 @@ dump_ia64_unwind (struct unw_aux_info *aux)
|
||||||
const unsigned char *head;
|
const unsigned char *head;
|
||||||
const char *procname;
|
const char *procname;
|
||||||
|
|
||||||
find_symbol_for_address (aux, tp->start, &procname, &offset);
|
find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
|
||||||
|
aux->strtab_size, tp->start, &procname, &offset);
|
||||||
|
|
||||||
fputs ("\n<", stdout);
|
fputs ("\n<", stdout);
|
||||||
|
|
||||||
|
@ -4333,12 +4339,12 @@ dump_ia64_unwind (struct unw_aux_info *aux)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
slurp_ia64_unwind_table (FILE *file,
|
slurp_ia64_unwind_table (FILE *file,
|
||||||
struct unw_aux_info *aux,
|
struct ia64_unw_aux_info *aux,
|
||||||
Elf_Internal_Shdr *sec)
|
Elf_Internal_Shdr *sec)
|
||||||
{
|
{
|
||||||
unsigned long size, addr_size, nrelas, i;
|
unsigned long size, addr_size, nrelas, i;
|
||||||
Elf_Internal_Phdr *seg;
|
Elf_Internal_Phdr *seg;
|
||||||
struct unw_table_entry *tep;
|
struct ia64_unw_table_entry *tep;
|
||||||
Elf_Internal_Shdr *relsec;
|
Elf_Internal_Shdr *relsec;
|
||||||
Elf_Internal_Rela *rela, *rp;
|
Elf_Internal_Rela *rela, *rp;
|
||||||
unsigned char *table, *tp;
|
unsigned char *table, *tp;
|
||||||
|
@ -4463,20 +4469,11 @@ slurp_ia64_unwind_table (FILE *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
process_unwind (FILE *file)
|
ia64_process_unwind (FILE *file)
|
||||||
{
|
{
|
||||||
Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
|
Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
|
||||||
unsigned long i, addr_size, unwcount = 0, unwstart = 0;
|
unsigned long i, addr_size, unwcount = 0, unwstart = 0;
|
||||||
struct unw_aux_info aux;
|
struct ia64_unw_aux_info aux;
|
||||||
|
|
||||||
if (!do_unwind)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (elf_header.e_machine != EM_IA_64)
|
|
||||||
{
|
|
||||||
printf (_("\nThere are no unwind sections in this file.\n"));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (& aux, 0, sizeof (aux));
|
memset (& aux, 0, sizeof (aux));
|
||||||
|
|
||||||
|
@ -4527,7 +4524,7 @@ process_unwind (FILE *file)
|
||||||
sec = SECTION_HEADER (g->section_index);
|
sec = SECTION_HEADER (g->section_index);
|
||||||
if (strcmp (SECTION_NAME (sec),
|
if (strcmp (SECTION_NAME (sec),
|
||||||
ELF_STRING_ia64_unwind_info) == 0)
|
ELF_STRING_ia64_unwind_info) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g == NULL)
|
if (g == NULL)
|
||||||
|
@ -4613,6 +4610,375 @@ process_unwind (FILE *file)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct hppa_unw_aux_info
|
||||||
|
{
|
||||||
|
struct hppa_unw_table_entry
|
||||||
|
{
|
||||||
|
struct absaddr start;
|
||||||
|
struct absaddr end;
|
||||||
|
unsigned int Cannot_unwind:1; /* 0 */
|
||||||
|
unsigned int Millicode:1; /* 1 */
|
||||||
|
unsigned int Millicode_save_sr0:1; /* 2 */
|
||||||
|
unsigned int Region_description:2; /* 3..4 */
|
||||||
|
unsigned int reserved1:1; /* 5 */
|
||||||
|
unsigned int Entry_SR:1; /* 6 */
|
||||||
|
unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
|
||||||
|
unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
|
||||||
|
unsigned int Args_stored:1; /* 16 */
|
||||||
|
unsigned int Variable_Frame:1; /* 17 */
|
||||||
|
unsigned int Separate_Package_Body:1; /* 18 */
|
||||||
|
unsigned int Frame_Extension_Millicode:1; /* 19 */
|
||||||
|
unsigned int Stack_Overflow_Check:1; /* 20 */
|
||||||
|
unsigned int Two_Instruction_SP_Increment:1; /* 21 */
|
||||||
|
unsigned int Ada_Region:1; /* 22 */
|
||||||
|
unsigned int cxx_info:1; /* 23 */
|
||||||
|
unsigned int cxx_try_catch:1; /* 24 */
|
||||||
|
unsigned int sched_entry_seq:1; /* 25 */
|
||||||
|
unsigned int reserved2:1; /* 26 */
|
||||||
|
unsigned int Save_SP:1; /* 27 */
|
||||||
|
unsigned int Save_RP:1; /* 28 */
|
||||||
|
unsigned int Save_MRP_in_frame:1; /* 29 */
|
||||||
|
unsigned int extn_ptr_defined:1; /* 30 */
|
||||||
|
unsigned int Cleanup_defined:1; /* 31 */
|
||||||
|
|
||||||
|
unsigned int MPE_XL_interrupt_marker:1; /* 0 */
|
||||||
|
unsigned int HP_UX_interrupt_marker:1; /* 1 */
|
||||||
|
unsigned int Large_frame:1; /* 2 */
|
||||||
|
unsigned int Pseudo_SP_Set:1; /* 3 */
|
||||||
|
unsigned int reserved4:1; /* 4 */
|
||||||
|
unsigned int Total_frame_size:27; /* 5..31 */
|
||||||
|
}
|
||||||
|
*table; /* Unwind table. */
|
||||||
|
unsigned long table_len; /* Length of unwind table. */
|
||||||
|
bfd_vma seg_base; /* Starting address of segment. */
|
||||||
|
Elf_Internal_Sym *symtab; /* The symbol table. */
|
||||||
|
unsigned long nsyms; /* Number of symbols. */
|
||||||
|
char *strtab; /* The string table. */
|
||||||
|
unsigned long strtab_size; /* Size of string table. */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_hppa_unwind (struct hppa_unw_aux_info *aux)
|
||||||
|
{
|
||||||
|
bfd_vma addr_size;
|
||||||
|
struct hppa_unw_table_entry *tp;
|
||||||
|
|
||||||
|
addr_size = is_32bit_elf ? 4 : 8;
|
||||||
|
for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
|
||||||
|
{
|
||||||
|
bfd_vma offset;
|
||||||
|
const char *procname;
|
||||||
|
|
||||||
|
find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
|
||||||
|
aux->strtab_size, tp->start, &procname,
|
||||||
|
&offset);
|
||||||
|
|
||||||
|
fputs ("\n<", stdout);
|
||||||
|
|
||||||
|
if (procname)
|
||||||
|
{
|
||||||
|
fputs (procname, stdout);
|
||||||
|
|
||||||
|
if (offset)
|
||||||
|
printf ("+%lx", (unsigned long) offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs (">: [", stdout);
|
||||||
|
print_vma (tp->start.offset, PREFIX_HEX);
|
||||||
|
fputc ('-', stdout);
|
||||||
|
print_vma (tp->end.offset, PREFIX_HEX);
|
||||||
|
printf ("]\n\t");
|
||||||
|
|
||||||
|
#define PF(_m) if (tp->_m) printf(#_m " ");
|
||||||
|
#define PV(_m) if (tp->_m) printf(#_m "=%d ", tp->_m);
|
||||||
|
PF(Cannot_unwind);
|
||||||
|
PF(Millicode);
|
||||||
|
PF(Millicode_save_sr0);
|
||||||
|
/* PV(Region_description); */
|
||||||
|
PF(Entry_SR);
|
||||||
|
PV(Entry_FR);
|
||||||
|
PV(Entry_GR);
|
||||||
|
PF(Args_stored);
|
||||||
|
PF(Variable_Frame);
|
||||||
|
PF(Separate_Package_Body);
|
||||||
|
PF(Frame_Extension_Millicode);
|
||||||
|
PF(Stack_Overflow_Check);
|
||||||
|
PF(Two_Instruction_SP_Increment);
|
||||||
|
PF(Ada_Region);
|
||||||
|
PF(cxx_info);
|
||||||
|
PF(cxx_try_catch);
|
||||||
|
PF(sched_entry_seq);
|
||||||
|
PF(Save_SP);
|
||||||
|
PF(Save_RP);
|
||||||
|
PF(Save_MRP_in_frame);
|
||||||
|
PF(extn_ptr_defined);
|
||||||
|
PF(Cleanup_defined);
|
||||||
|
PF(MPE_XL_interrupt_marker);
|
||||||
|
PF(HP_UX_interrupt_marker);
|
||||||
|
PF(Large_frame);
|
||||||
|
PF(Pseudo_SP_Set);
|
||||||
|
PV(Total_frame_size);
|
||||||
|
#undef PF
|
||||||
|
#undef PV
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slurp_hppa_unwind_table (FILE *file,
|
||||||
|
struct hppa_unw_aux_info *aux,
|
||||||
|
Elf_Internal_Shdr *sec)
|
||||||
|
{
|
||||||
|
unsigned long size, unw_ent_size, addr_size, nrelas, i;
|
||||||
|
Elf_Internal_Phdr *seg;
|
||||||
|
struct hppa_unw_table_entry *tep;
|
||||||
|
Elf_Internal_Shdr *relsec;
|
||||||
|
Elf_Internal_Rela *rela, *rp;
|
||||||
|
unsigned char *table, *tp;
|
||||||
|
Elf_Internal_Sym *sym;
|
||||||
|
const char *relname;
|
||||||
|
|
||||||
|
addr_size = is_32bit_elf ? 4 : 8;
|
||||||
|
|
||||||
|
/* First, find the starting address of the segment that includes
|
||||||
|
this section. */
|
||||||
|
|
||||||
|
if (elf_header.e_phnum)
|
||||||
|
{
|
||||||
|
if (! get_program_headers (file))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (seg = program_headers;
|
||||||
|
seg < program_headers + elf_header.e_phnum;
|
||||||
|
++seg)
|
||||||
|
{
|
||||||
|
if (seg->p_type != PT_LOAD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sec->sh_addr >= seg->p_vaddr
|
||||||
|
&& (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
|
||||||
|
{
|
||||||
|
aux->seg_base = seg->p_vaddr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second, build the unwind table from the contents of the unwind
|
||||||
|
section. */
|
||||||
|
size = sec->sh_size;
|
||||||
|
table = get_data (NULL, file, sec->sh_offset, size, _("unwind table"));
|
||||||
|
if (!table)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unw_ent_size = 2 * addr_size + 8;
|
||||||
|
|
||||||
|
tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
|
||||||
|
|
||||||
|
for (tp = table; tp < table + size; tp += (2 * addr_size + 8), ++tep)
|
||||||
|
{
|
||||||
|
unsigned int tmp1, tmp2;
|
||||||
|
|
||||||
|
tep->start.section = SHN_UNDEF;
|
||||||
|
tep->end.section = SHN_UNDEF;
|
||||||
|
|
||||||
|
if (is_32bit_elf)
|
||||||
|
{
|
||||||
|
tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
|
||||||
|
tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
|
||||||
|
tmp1 = byte_get ((unsigned char *) tp + 8, 4);
|
||||||
|
tmp2 = byte_get ((unsigned char *) tp + 12, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tep->start.offset = BYTE_GET8 ((unsigned char *) tp + 0);
|
||||||
|
tep->end.offset = BYTE_GET8 ((unsigned char *) tp + 8);
|
||||||
|
tmp1 = byte_get ((unsigned char *) tp + 16, 4);
|
||||||
|
tmp2 = byte_get ((unsigned char *) tp + 20, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
|
||||||
|
tep->Millicode = (tmp1 >> 30) & 0x1;
|
||||||
|
tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
|
||||||
|
tep->Region_description = (tmp1 >> 27) & 0x3;
|
||||||
|
tep->reserved1 = (tmp1 >> 26) & 0x1;
|
||||||
|
tep->Entry_SR = (tmp1 >> 25) & 0x1;
|
||||||
|
tep->Entry_FR = (tmp1 >> 21) & 0xf;
|
||||||
|
tep->Entry_GR = (tmp1 >> 16) & 0x1f;
|
||||||
|
tep->Args_stored = (tmp1 >> 15) & 0x1;
|
||||||
|
tep->Variable_Frame = (tmp1 >> 14) & 0x1;
|
||||||
|
tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
|
||||||
|
tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
|
||||||
|
tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
|
||||||
|
tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
|
||||||
|
tep->Ada_Region = (tmp1 >> 9) & 0x1;
|
||||||
|
tep->cxx_info = (tmp1 >> 8) & 0x1;
|
||||||
|
tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
|
||||||
|
tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
|
||||||
|
tep->reserved2 = (tmp1 >> 5) & 0x1;
|
||||||
|
tep->Save_SP = (tmp1 >> 4) & 0x1;
|
||||||
|
tep->Save_RP = (tmp1 >> 3) & 0x1;
|
||||||
|
tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
|
||||||
|
tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
|
||||||
|
tep->Cleanup_defined = tmp1 & 0x1;
|
||||||
|
|
||||||
|
tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
|
||||||
|
tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
|
||||||
|
tep->Large_frame = (tmp2 >> 29) & 0x1;
|
||||||
|
tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
|
||||||
|
tep->reserved4 = (tmp2 >> 27) & 0x1;
|
||||||
|
tep->Total_frame_size = tmp2 & 0x7ffffff;
|
||||||
|
|
||||||
|
tep->start.offset += aux->seg_base;
|
||||||
|
tep->end.offset += aux->seg_base;
|
||||||
|
}
|
||||||
|
free (table);
|
||||||
|
|
||||||
|
/* Third, apply any relocations to the unwind table. */
|
||||||
|
|
||||||
|
for (relsec = section_headers;
|
||||||
|
relsec < section_headers + elf_header.e_shnum;
|
||||||
|
++relsec)
|
||||||
|
{
|
||||||
|
if (relsec->sh_type != SHT_RELA
|
||||||
|
|| SECTION_HEADER (relsec->sh_info) != sec)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
|
||||||
|
& rela, & nrelas))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (rp = rela; rp < rela + nrelas; ++rp)
|
||||||
|
{
|
||||||
|
if (is_32bit_elf)
|
||||||
|
{
|
||||||
|
relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
|
||||||
|
sym = aux->symtab + ELF32_R_SYM (rp->r_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
|
||||||
|
sym = aux->symtab + ELF64_R_SYM (rp->r_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
|
||||||
|
if (strncmp (relname, "R_PARISC_SEGREL", 15) != 0)
|
||||||
|
{
|
||||||
|
warn (_("Skipping unexpected relocation type %s\n"), relname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = rp->r_offset / unw_ent_size;
|
||||||
|
|
||||||
|
switch ((rp->r_offset % unw_ent_size) / addr_size)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
aux->table[i].start.section = sym->st_shndx;
|
||||||
|
aux->table[i].start.offset += sym->st_value + rp->r_addend;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
aux->table[i].end.section = sym->st_shndx;
|
||||||
|
aux->table[i].end.offset += sym->st_value + rp->r_addend;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free (rela);
|
||||||
|
}
|
||||||
|
|
||||||
|
aux->table_len = size / unw_ent_size;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hppa_process_unwind (FILE *file)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
|
||||||
|
unsigned long i, addr_size;
|
||||||
|
struct hppa_unw_aux_info aux;
|
||||||
|
|
||||||
|
memset (& aux, 0, sizeof (aux));
|
||||||
|
|
||||||
|
assert (string_table != NULL);
|
||||||
|
addr_size = is_32bit_elf ? 4 : 8;
|
||||||
|
|
||||||
|
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
||||||
|
{
|
||||||
|
if (sec->sh_type == SHT_SYMTAB)
|
||||||
|
{
|
||||||
|
aux.nsyms = sec->sh_size / sec->sh_entsize;
|
||||||
|
aux.symtab = GET_ELF_SYMBOLS (file, sec);
|
||||||
|
|
||||||
|
strsec = SECTION_HEADER (sec->sh_link);
|
||||||
|
aux.strtab_size = strsec->sh_size;
|
||||||
|
aux.strtab = get_data (NULL, file, strsec->sh_offset,
|
||||||
|
aux.strtab_size, _("string table"));
|
||||||
|
}
|
||||||
|
else if (strcmp (SECTION_NAME(sec), ".PARISC.unwind") == 0)
|
||||||
|
unwsec = sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unwsec)
|
||||||
|
printf (_("\nThere are no unwind sections in this file.\n"));
|
||||||
|
|
||||||
|
for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
|
||||||
|
{
|
||||||
|
if (strcmp (SECTION_NAME(sec), ".PARISC.unwind") == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf (_("\nUnwind section "));
|
||||||
|
printf (_("'%s'"), SECTION_NAME (sec));
|
||||||
|
|
||||||
|
printf (_(" at offset 0x%lx contains %lu entries:\n"),
|
||||||
|
(unsigned long) sec->sh_offset,
|
||||||
|
(unsigned long) (sec->sh_size / (2 * addr_size + 8)));
|
||||||
|
|
||||||
|
slurp_hppa_unwind_table (file, &aux, sec);
|
||||||
|
if (aux.table_len > 0)
|
||||||
|
dump_hppa_unwind (&aux);
|
||||||
|
|
||||||
|
if (aux.table)
|
||||||
|
free ((char *) aux.table);
|
||||||
|
aux.table = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aux.symtab)
|
||||||
|
free (aux.symtab);
|
||||||
|
if (aux.strtab)
|
||||||
|
free ((char *) aux.strtab);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
process_unwind (FILE *file)
|
||||||
|
{
|
||||||
|
struct unwind_handler {
|
||||||
|
int machtype;
|
||||||
|
int (*handler)(FILE *file);
|
||||||
|
} handlers[] = {
|
||||||
|
{ EM_IA_64, ia64_process_unwind },
|
||||||
|
{ EM_PARISC, hppa_process_unwind },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!do_unwind)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (i = 0; handlers[i].handler != NULL; i++)
|
||||||
|
if (elf_header.e_machine == handlers[i].machtype)
|
||||||
|
return handlers[i].handler(file);
|
||||||
|
|
||||||
|
printf (_("\nThere are no unwind sections in this file.\n"));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dynamic_section_mips_val (Elf_Internal_Dyn *entry)
|
dynamic_section_mips_val (Elf_Internal_Dyn *entry)
|
||||||
{
|
{
|
||||||
|
@ -10351,29 +10717,29 @@ get_note_type (unsigned e_type)
|
||||||
if (elf_header.e_type == ET_CORE)
|
if (elf_header.e_type == ET_CORE)
|
||||||
switch (e_type)
|
switch (e_type)
|
||||||
{
|
{
|
||||||
case NT_AUXV:
|
case NT_AUXV:
|
||||||
return _("NT_AUXV (auxiliary vector)");
|
return _("NT_AUXV (auxiliary vector)");
|
||||||
case NT_PRSTATUS:
|
case NT_PRSTATUS:
|
||||||
return _("NT_PRSTATUS (prstatus structure)");
|
return _("NT_PRSTATUS (prstatus structure)");
|
||||||
case NT_FPREGSET:
|
case NT_FPREGSET:
|
||||||
return _("NT_FPREGSET (floating point registers)");
|
return _("NT_FPREGSET (floating point registers)");
|
||||||
case NT_PRPSINFO:
|
case NT_PRPSINFO:
|
||||||
return _("NT_PRPSINFO (prpsinfo structure)");
|
return _("NT_PRPSINFO (prpsinfo structure)");
|
||||||
case NT_TASKSTRUCT:
|
case NT_TASKSTRUCT:
|
||||||
return _("NT_TASKSTRUCT (task structure)");
|
return _("NT_TASKSTRUCT (task structure)");
|
||||||
case NT_PRXFPREG:
|
case NT_PRXFPREG:
|
||||||
return _("NT_PRXFPREG (user_xfpregs structure)");
|
return _("NT_PRXFPREG (user_xfpregs structure)");
|
||||||
case NT_PSTATUS:
|
case NT_PSTATUS:
|
||||||
return _("NT_PSTATUS (pstatus structure)");
|
return _("NT_PSTATUS (pstatus structure)");
|
||||||
case NT_FPREGS:
|
case NT_FPREGS:
|
||||||
return _("NT_FPREGS (floating point registers)");
|
return _("NT_FPREGS (floating point registers)");
|
||||||
case NT_PSINFO:
|
case NT_PSINFO:
|
||||||
return _("NT_PSINFO (psinfo structure)");
|
return _("NT_PSINFO (psinfo structure)");
|
||||||
case NT_LWPSTATUS:
|
case NT_LWPSTATUS:
|
||||||
return _("NT_LWPSTATUS (lwpstatus_t structure)");
|
return _("NT_LWPSTATUS (lwpstatus_t structure)");
|
||||||
case NT_LWPSINFO:
|
case NT_LWPSINFO:
|
||||||
return _("NT_LWPSINFO (lwpsinfo_t structure)");
|
return _("NT_LWPSINFO (lwpsinfo_t structure)");
|
||||||
case NT_WIN32PSTATUS:
|
case NT_WIN32PSTATUS:
|
||||||
return _("NT_WIN32PSTATUS (win32_pstatus structure)");
|
return _("NT_WIN32PSTATUS (win32_pstatus structure)");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue