int is_32bit_elf;
int have_frame_base;
int need_base_address;
+bfd_vma eh_addr_size;
struct group_list
{
}
}
+/* Return a pointer to section NAME, or NULL if no such section exists. */
+
+static Elf_Internal_Shdr *
+find_section (const char *name)
+{
+ unsigned int i;
+
+ for (i = 0; i < elf_header.e_shnum; i++)
+ if (streq (SECTION_NAME (section_headers + i), name))
+ return section_headers + i;
+
+ return NULL;
+}
+
/* Guess the relocation size commonly used by the specific machines. */
static int
if (section_headers != NULL)
{
Elf_Internal_Shdr *sec;
- unsigned int j;
- for (j = 0, sec = section_headers;
- j < elf_header.e_shnum;
- j++, sec++)
- if (streq (SECTION_NAME (sec), ".dynamic"))
- break;
-
- if (j == elf_header.e_shnum || sec->sh_size == 0)
+ sec = find_section (".dynamic");
+ if (sec == NULL || sec->sh_size == 0)
{
error (_("no .dynamic section in the dynamic segment"));
break;
dynamic_syminfo = NULL;
symtab_shndx_hdr = NULL;
+ eh_addr_size = is_32bit_elf ? 4 : 8;
+ switch (elf_header.e_machine)
+ {
+ case EM_MIPS:
+ case EM_MIPS_RS3_LE:
+ /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
+ FDE addresses. However, the ABI also has a semi-official ILP32
+ variant for which the normal FDE address size rules apply.
+
+ GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
+ section, where XX is the size of longs in bits. Unfortunately,
+ earlier compilers provided no way of distinguishing ILP32 objects
+ from LP64 objects, so if there's any doubt, we should assume that
+ the official LP64 form is being used. */
+ if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
+ && find_section (".gcc_compiled_long32") == NULL)
+ eh_addr_size = 8;
+ break;
+ }
+
for (i = 0, section = section_headers;
i < elf_header.e_shnum;
i++, section++)
static void
dump_ia64_unwind (struct ia64_unw_aux_info *aux)
{
- bfd_vma addr_size;
struct ia64_unw_table_entry *tp;
int in_body;
- addr_size = is_32bit_elf ? 4 : 8;
-
for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
{
bfd_vma stamp;
(unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
- (unsigned long) (addr_size * UNW_LENGTH (stamp)));
+ (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
if (UNW_VER (stamp) != 1)
{
}
in_body = 0;
- for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
+ for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
dp = unw_decode (dp, in_body, & in_body);
}
}
struct ia64_unw_aux_info *aux,
Elf_Internal_Shdr *sec)
{
- unsigned long size, addr_size, nrelas, i;
+ unsigned long size, nrelas, i;
Elf_Internal_Phdr *seg;
struct ia64_unw_table_entry *tep;
Elf_Internal_Shdr *relsec;
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 (!table)
return 0;
- tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
- for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
+ aux->table = xmalloc (size / (3 * eh_addr_size) * sizeof (aux->table[0]));
+ tep = aux->table;
+ for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
{
tep->start.section = SHN_UNDEF;
tep->end.section = SHN_UNDEF;
continue;
}
- i = rp->r_offset / (3 * addr_size);
+ i = rp->r_offset / (3 * eh_addr_size);
- switch (rp->r_offset/addr_size % 3)
+ switch (rp->r_offset/eh_addr_size % 3)
{
case 0:
aux->table[i].start.section = sym->st_shndx;
free (rela);
}
- aux->table_len = size / (3 * addr_size);
+ aux->table_len = size / (3 * eh_addr_size);
return 1;
}
ia64_process_unwind (FILE *file)
{
Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
- unsigned long i, addr_size, unwcount = 0, unwstart = 0;
+ unsigned long i, unwcount = 0, unwstart = 0;
struct ia64_unw_aux_info aux;
memset (& aux, 0, sizeof (aux));
- 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)
printf (_(" at offset 0x%lx contains %lu entries:\n"),
(unsigned long) unwsec->sh_offset,
- (unsigned long) (unwsec->sh_size / (3 * addr_size)));
+ (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
(void) slurp_ia64_unwind_table (file, & aux, unwsec);
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;
struct hppa_unw_aux_info *aux,
Elf_Internal_Shdr *sec)
{
- unsigned long size, unw_ent_size, addr_size, nrelas, i;
+ unsigned long size, unw_ent_size, nrelas, i;
Elf_Internal_Phdr *seg;
struct hppa_unw_table_entry *tep;
Elf_Internal_Shdr *relsec;
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 (!table)
return 0;
- unw_ent_size = 2 * addr_size + 8;
+ unw_ent_size = 2 * eh_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)
+ for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
{
unsigned int tmp1, tmp2;
i = rp->r_offset / unw_ent_size;
- switch ((rp->r_offset % unw_ent_size) / addr_size)
+ switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
{
case 0:
aux->table[i].start.section = sym->st_shndx;
Elf_Internal_Shdr *unwsec = NULL;
Elf_Internal_Shdr *strsec;
Elf_Internal_Shdr *sec;
- unsigned long addr_size;
unsigned long i;
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)
{
printf (_(" at offset 0x%lx contains %lu entries:\n"),
(unsigned long) sec->sh_offset,
- (unsigned long) (sec->sh_size / (2 * addr_size + 8)));
+ (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
slurp_hppa_unwind_table (file, &aux, sec);
if (aux.table_len > 0)
return len;
}
-/* Finds section NAME inside FILE and returns a
- pointer to it, or NULL upon failure. */
-
-static Elf_Internal_Shdr *
-find_section (const char * name)
-{
- Elf_Internal_Shdr *sec;
- unsigned int i;
-
- for (i = elf_header.e_shnum, sec = section_headers + i - 1;
- i; --i, --sec)
- if (streq (SECTION_NAME (sec), name))
- break;
-
- if (i && sec && sec->sh_size != 0)
- return sec;
-
- return NULL;
-}
-
static const char *debug_str_contents;
static bfd_vma debug_str_size;
switch (encoding & 0x7)
{
default: /* ??? */
- case 0: return is_32bit_elf ? 4 : 8;
+ case 0: return eh_addr_size;
case 2: return 2;
case 3: return 4;
case 4: return 8;
int is_eh = streq (SECTION_NAME (section), ".eh_frame");
int length_return;
int max_regs = 0;
- int addr_size = is_32bit_elf ? 4 : 8;
printf (_("The section %s contains:\n"), SECTION_NAME (section));
int need_col_headers = 1;
unsigned char *augmentation_data = NULL;
unsigned long augmentation_data_len = 0;
- int encoded_ptr_size = addr_size;
+ int encoded_ptr_size = eh_addr_size;
int offset_size;
int initial_length_size;
}
else if (streq (fc->augmentation, "eh"))
{
- start += addr_size;
+ start += eh_addr_size;
fc->code_factor = LEB ();
fc->data_factor = SLEB ();
if (version == 1)
if (! do_debug_frames_interp)
{
printf (" DW_CFA_def_cfa_expression (");
- decode_location_expression (start, addr_size, ul, 0);
+ decode_location_expression (start, eh_addr_size, ul, 0);
printf (")\n");
}
fc->cfa_exp = 1;
if (! do_debug_frames_interp)
{
printf (" DW_CFA_expression: r%ld (", reg);
- decode_location_expression (start, addr_size, ul, 0);
+ decode_location_expression (start, eh_addr_size, ul, 0);
printf (")\n");
}
fc->col_type[reg] = DW_CFA_expression;