diff options
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 16 | ||||
-rw-r--r-- | binutils/dwarf.c | 10 | ||||
-rw-r--r-- | binutils/dwarf.h | 1 | ||||
-rw-r--r-- | binutils/objdump.c | 2 | ||||
-rw-r--r-- | binutils/readelf.c | 131 |
5 files changed, 104 insertions, 56 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index abd9a96..137b373 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,19 @@ +2007-10-31 Nick Clifton <nickc@redhat.com> + + * dwarf.c (is_relocatable): Remove definition. + (display_debug_frames): Remove check in is_relocatable. + * dwarf.h (is_relocatable): Remove declaration. + * objdump.c (is_relocatable): New static definition. + * readelf.c (dump_relocations): Make the function void. + (is_32bit_abs_reloc): Add support for x86, Arc, Arm, D10V, Dlx, + OR32 and Score. + (is_32bit_pcrel_reloc): Add support for x86 and Arm. + (is_16bit_abs_reloc): Add support for D10V. + (debug_apply_rela_addends): Rename to debug_apply_relocations. + Add code to support rel relocations. + (load_debug_section): Fix call to debug_apply_relocations. + (get_file_header): Remove setting of is_relocatable. + 2007-10-31 Alan Modra <amodra@bigpond.net.au> * readelf.c (debug_apply_rela_addends): Clarify FIXME. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index e3231d8..9a021c5 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -36,7 +36,6 @@ static unsigned int num_debug_info_entries = 0; static debug_info *debug_information = NULL; dwarf_vma eh_addr_size; -int is_relocatable; int do_debug_info; int do_debug_abbrevs; @@ -3184,11 +3183,7 @@ display_debug_frames (struct dwarf_section *section, encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); fc->pc_begin = get_encoded_value (start, fc->fde_encoding); - if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel - /* Don't adjust for relocatable file since there's - invariably a pcrel reloc here, which we haven't - applied. */ - && !is_relocatable) + if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel) fc->pc_begin += section->address + (start - section_start); start += encoded_ptr_size; fc->pc_range = byte_get (start, encoded_ptr_size); @@ -3391,8 +3386,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_set_loc: vma = get_encoded_value (start, fc->fde_encoding); - if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel - && !is_relocatable) + if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel) vma += section->address + (start - section_start); start += encoded_ptr_size; if (do_debug_frames_interp) diff --git a/binutils/dwarf.h b/binutils/dwarf.h index 7f815c8..113a8f9 100644 --- a/binutils/dwarf.h +++ b/binutils/dwarf.h @@ -92,7 +92,6 @@ extern dwarf_vma byte_get_little_endian (unsigned char *, int); extern dwarf_vma byte_get_big_endian (unsigned char *, int); extern dwarf_vma eh_addr_size; -extern int is_relocatable; extern int do_debug_info; extern int do_debug_abbrevs; diff --git a/binutils/objdump.c b/binutils/objdump.c index ee5530b..5a2ea6d 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -171,6 +171,8 @@ static bfd_size_type stab_size; static char *strtab; static bfd_size_type stabstr_size; + +static bfd_boolean is_relocatable = FALSE; static void usage (FILE *stream, int status) diff --git a/binutils/readelf.c b/binutils/readelf.c index 9ae0779..b64f775 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -879,7 +879,7 @@ get_reloc_symindex (bfd_vma reloc_info) /* Display the contents of the relocation data found at the specified offset. */ -static int +static void dump_relocations (FILE *file, unsigned long rel_offset, unsigned long rel_size, @@ -899,12 +899,12 @@ dump_relocations (FILE *file, if (is_rela) { if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size)) - return 0; + return; } else { if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size)) - return 0; + return; } if (is_32bit_elf) @@ -1367,8 +1367,6 @@ dump_relocations (FILE *file, } free (rels); - - return 1; } static const char * @@ -5034,8 +5032,7 @@ slurp_ia64_unwind_table (FILE *file, } free (table); - /* Third, apply any relocations to the unwind table: */ - + /* Third, apply any relocations to the unwind table: */ for (relsec = section_headers; relsec < section_headers + elf_header.e_shnum; ++relsec) @@ -5439,7 +5436,6 @@ slurp_hppa_unwind_table (FILE *file, free (table); /* Third, apply any relocations to the unwind table. */ - for (relsec = section_headers; relsec < section_headers + elf_header.e_shnum; ++relsec) @@ -7946,12 +7942,19 @@ is_32bit_abs_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) { + case EM_386: + case EM_486: + return reloc_type == 1; /* R_386_32. */ case EM_68K: return reloc_type == 1; /* R_68K_32. */ case EM_860: return reloc_type == 1; /* R_860_32. */ case EM_ALPHA: return reloc_type == 1; /* XXX Is this right ? */ + case EM_ARC: + return reloc_type == 1; /* R_ARC_32. */ + case EM_ARM: + return reloc_type == 2; /* R_ARM_ABS32 */ case EM_AVR_OLD: case EM_AVR: return reloc_type == 1; @@ -7965,9 +7968,14 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 15; /* R_CRX_NUM32. */ case EM_CYGNUS_FRV: return reloc_type == 1; + case EM_CYGNUS_D10V: + case EM_D10V: + return reloc_type == 6; /* R_D10V_32. */ case EM_CYGNUS_D30V: case EM_D30V: return reloc_type == 12; /* R_D30V_32_NORMAL. */ + case EM_DLX: + return reloc_type == 3; /* R_DLX_RELOC_32. */ case EM_CYGNUS_FR30: case EM_FR30: return reloc_type == 3; /* R_FR30_32. */ @@ -8005,6 +8013,9 @@ is_32bit_abs_reloc (unsigned int reloc_type) return reloc_type == 1; /* R_MSP43_32. */ case EM_MT: return reloc_type == 2; /* R_MT_32. */ + case EM_OPENRISC: + case EM_OR32: + return reloc_type == 1; /* R_OR32_32. */ case EM_PARISC: return reloc_type == 1; /* R_PARISC_DIR32. */ case EM_PJ: @@ -8019,6 +8030,8 @@ is_32bit_abs_reloc (unsigned int reloc_type) case EM_S390_OLD: case EM_S390: return reloc_type == 4; /* R_S390_32. */ + case EM_SCORE: + return reloc_type == 8; /* R_SCORE_ABS32. */ case EM_SH: return reloc_type == 1; /* R_SH_DIR32. */ case EM_SPARC32PLUS: @@ -8058,10 +8071,15 @@ is_32bit_pcrel_reloc (unsigned int reloc_type) { switch (elf_header.e_machine) { + case EM_386: + case EM_486: + return reloc_type == 2; /* R_386_PC32. */ case EM_68K: return reloc_type == 4; /* R_68K_PC32. */ case EM_ALPHA: return reloc_type == 10; /* R_ALPHA_SREL32. */ + case EM_ARM: + return reloc_type == 3; /* R_ARM_REL32 */ case EM_PARISC: return reloc_type == 0; /* R_PARISC_NONE. *//* FIXME: This reloc is generated, but it may be a bug. */ case EM_PPC: @@ -8083,8 +8101,8 @@ is_32bit_pcrel_reloc (unsigned int reloc_type) /* Do not abort or issue an error message here. Not all targets use pc-relative 32-bit relocs in their DWARF debug information and we have already tested for target coverage in is_32bit_abs_reloc. A - more helpful warning message will be generated by debug_apply_rela_addends - anyway, so just return. */ + more helpful warning message will be generated by + debug_apply_relocations anyway, so just return. */ return FALSE; } } @@ -8125,6 +8143,9 @@ is_16bit_abs_reloc (unsigned int reloc_type) case EM_AVR_OLD: case EM_AVR: return reloc_type == 4; /* R_AVR_16. */ + case EM_CYGNUS_D10V: + case EM_D10V: + return reloc_type == 3; /* R_D10V_16. */ case EM_H8S: case EM_H8_300: case EM_H8_300H: @@ -8140,52 +8161,66 @@ is_16bit_abs_reloc (unsigned int reloc_type) } } -/* Apply addends of RELA relocations. */ +/* Apply relocations to a debug section. */ -static int -debug_apply_rela_addends (void *file, - Elf_Internal_Shdr *section, - unsigned char *start) +static void +debug_apply_relocations (void *file, + Elf_Internal_Shdr *section, + unsigned char *start) { Elf_Internal_Shdr *relsec; unsigned char *end = start + section->sh_size; - if (!is_relocatable) - return 1; - - /* SH uses RELA but uses in place value instead of the addend field. */ - if (elf_header.e_machine == EM_SH) - return 0; + if (elf_header.e_type != ET_REL) + return; + /* Find the reloc section associated with the debug section. */ for (relsec = section_headers; relsec < section_headers + elf_header.e_shnum; ++relsec) { - unsigned long nrelas; - Elf_Internal_Rela *rela, *rp; + bfd_boolean is_rela; + unsigned long num_relocs; + Elf_Internal_Rela *relocs, *rp; Elf_Internal_Shdr *symsec; Elf_Internal_Sym *symtab; Elf_Internal_Sym *sym; - if (relsec->sh_type != SHT_RELA + if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL) || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum || SECTION_HEADER (relsec->sh_info) != section || relsec->sh_size == 0 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum) continue; - if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, - &rela, &nrelas)) - return 0; + is_rela = relsec->sh_type == SHT_RELA; + + if (is_rela) + { + if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size, + & relocs, & num_relocs)) + return; + } + else + { + if (!slurp_rel_relocs (file, relsec->sh_offset, relsec->sh_size, + & relocs, & num_relocs)) + return; + } + + /* SH uses RELA but uses in place value instead of the addend field. */ + if (elf_header.e_machine == EM_SH) + is_rela = FALSE; symsec = SECTION_HEADER (relsec->sh_link); symtab = GET_ELF_SYMBOLS (file, symsec); - for (rp = rela; rp < rela + nrelas; ++rp) + for (rp = relocs; rp < relocs + num_relocs; ++rp) { - unsigned int reloc_type; - unsigned int reloc_size; - unsigned char *loc; + bfd_vma addend; + unsigned int reloc_type; + unsigned int reloc_size; + unsigned char * loc; /* In MIPS little-endian objects, r_info isn't really a 64-bit little-endian value: it has a 32-bit little-endian @@ -8200,8 +8235,8 @@ debug_apply_rela_addends (void *file, | ((rp->r_info >> 24) & 0xff0000) | ((rp->r_info >> 8) & 0xff000000)); - sym = symtab + get_reloc_symindex (rp->r_info); reloc_type = get_reloc_type (rp->r_info); + if (is_32bit_abs_reloc (reloc_type) || is_32bit_pcrel_reloc (reloc_type)) reloc_size = 4; @@ -8211,7 +8246,7 @@ debug_apply_rela_addends (void *file, reloc_size = 2; else { - warn (_("skipping unsupported reloc type %d in section .rela%s\n"), + warn (_("unable to apply unsupported reloc type %d to section %s\n"), reloc_type, SECTION_NAME (section)); continue; } @@ -8225,6 +8260,10 @@ debug_apply_rela_addends (void *file, continue; } + sym = symtab + get_reloc_symindex (rp->r_info); + + /* If the reloc has a symbol associated with it, + make sure that it is of an appropriate type. */ if (sym != symtab && ELF_ST_TYPE (sym->st_info) != STT_SECTION /* Relocations against symbols without type can happen. @@ -8236,26 +8275,26 @@ debug_apply_rela_addends (void *file, example of this see the _clz.o binary in libgcc.a. */ && ELF_ST_TYPE (sym->st_info) != STT_OBJECT) { - warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"), + warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"), get_symbol_type (ELF_ST_TYPE (sym->st_info)), - SECTION_NAME (section)); + rp - relocs, + SECTION_NAME (relsec)); continue; } - /* FIXME. We apply pcrel relocs as if they were absolute, - ie. without subtracting the pc. This is to suit - display_debug_frames which does not add the pc even - though it ought to for DW_EH_PE_pcrel FDEs. Removing - the hack in display_debug_frames will require that we - apply rel relocs too. */ - byte_put (loc, rp->r_addend + sym->st_value, reloc_size); + addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size); + + if (is_32bit_pcrel_reloc (reloc_type)) + byte_put (loc, (addend + sym->st_value) - rp->r_offset, + reloc_size); + else + byte_put (loc, addend + sym->st_value, reloc_size); } free (symtab); - free (rela); + free (relocs); break; } - return 1; } int @@ -8281,7 +8320,7 @@ load_debug_section (enum dwarf_section_display_enum debug, void *file) sec->sh_size, buf); if (debug_displays [debug].relocate) - debug_apply_rela_addends (file, sec, section->start); + debug_apply_relocations (file, sec, section->start); return section->start != NULL; } @@ -9886,8 +9925,6 @@ get_file_header (FILE *file) get_64bit_section_headers (file, 1); } - is_relocatable = elf_header.e_type == ET_REL; - return 1; } |