X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-v850.c;h=5e89473a45ea45b9d56cfa7011a31b8c6b6a6b00;hb=563e308f244b1d6adb9d012a3e11d458400b3ff2;hp=67fede0512c04572f8441facaa6f2d81945aeae9;hpb=b653e1b1521ac68fc398311345fe7df54803f1ec;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 67fede0512..5e89473a45 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -1,5 +1,6 @@ /* V850-specific support for 32-bit ELF - Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -26,8 +27,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "libbfd.h" #include "elf-bfd.h" #include "elf/v850.h" +#include "libiberty.h" -/* sign-extend a 24-bit number */ +/* Sign-extend a 24-bit number. */ #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000) static reloc_howto_type *v850_elf_reloc_type_lookup @@ -80,9 +82,16 @@ static boolean v850_elf_link_output_symbol_hook Elf_Internal_Sym *, asection *)); static boolean v850_elf_section_from_shdr PARAMS ((bfd *, Elf_Internal_Shdr *, char *)); - -/* Note: It is REQUIRED that the 'type' value of each entry in this array - match the index of the entry in the array. */ +static boolean v850_elf_gc_sweep_hook + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); +static asection * v850_elf_gc_mark_hook + PARAMS ((bfd *, struct bfd_link_info *, + Elf_Internal_Rela *, struct elf_link_hash_entry *, + Elf_Internal_Sym *)); + +/* Note: It is REQUIRED that the 'type' value of each entry + in this array match the index of the entry in the array. */ static reloc_howto_type v850_elf_howto_table[] = { /* This reloc does nothing. */ @@ -502,7 +511,8 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] = }; -/* Map a bfd relocation into the appropriate howto structure */ +/* Map a bfd relocation into the appropriate howto structure. */ + static reloc_howto_type * v850_elf_reloc_type_lookup (abfd, code) bfd * abfd ATTRIBUTE_UNUSED; @@ -510,22 +520,21 @@ v850_elf_reloc_type_lookup (abfd, code) { unsigned int i; - for (i = 0; - i < sizeof (v850_elf_reloc_map) / sizeof (struct v850_elf_reloc_map); - i++) - { - if (v850_elf_reloc_map[i].bfd_reloc_val == code) - { - BFD_ASSERT (v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val].type == v850_elf_reloc_map[i].elf_reloc_val); + for (i = ARRAY_SIZE (v850_elf_reloc_map); i --;) + if (v850_elf_reloc_map[i].bfd_reloc_val == code) + { + int elf_reloc_val = v850_elf_reloc_map[i].elf_reloc_val; + + BFD_ASSERT (v850_elf_howto_table[elf_reloc_val].type == elf_reloc_val); - return & v850_elf_howto_table[v850_elf_reloc_map[i].elf_reloc_val]; - } - } + return v850_elf_howto_table + elf_reloc_val; + } return NULL; } /* Set the howto pointer for an V850 ELF reloc. */ + static void v850_elf_info_to_howto_rel (abfd, cache_ptr, dst) bfd * abfd ATTRIBUTE_UNUSED; @@ -625,8 +634,8 @@ v850_elf_check_relocs (abfd, info, sec, relocs) return false; break; - /* This relocation describes which C++ vtable entries are actually - used. Record for later use during GC. */ + /* This relocation describes which C++ vtable entries + are actually used. Record for later use during GC. */ case R_V850_GNU_VTENTRY: if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return false; @@ -661,7 +670,8 @@ v850_elf_check_relocs (abfd, info, sec, relocs) small_data_common: if (h) { - h->other |= other; /* flag which type of relocation was used */ + /* Flag which type of relocation was used. */ + h->other |= other; if ((h->other & V850_OTHER_MASK) != (other & V850_OTHER_MASK) && (h->other & V850_OTHER_ERROR) == 0) { @@ -701,7 +711,9 @@ v850_elf_check_relocs (abfd, info, sec, relocs) && h->root.u.c.p && !strcmp (bfd_get_section_name (abfd, h->root.u.c.p->section), "COMMON")) { - asection *section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common); + asection * section; + + section = h->root.u.c.p->section = bfd_make_section_old_way (abfd, common); section->flags |= SEC_IS_COMMON; } @@ -718,20 +730,18 @@ v850_elf_check_relocs (abfd, info, sec, relocs) return ret; } -/* - * In the old version, when an entry was checked out from the table, - * it was deleted. This produced an error if the entry was needed - * more than once, as the second attempted retry failed. - * - * In the current version, the entry is not deleted, instead we set - * the field 'found' to true. If a second lookup matches the same - * entry, then we know that the hi16s reloc has already been updated - * and does not need to be updated a second time. - * - * TODO - TOFIX: If it is possible that we need to restore 2 different - * addresses from the same table entry, where the first generates an - * overflow, whilst the second do not, then this code will fail. - */ +/* In the old version, when an entry was checked out from the table, + it was deleted. This produced an error if the entry was needed + more than once, as the second attempted retry failed. + + In the current version, the entry is not deleted, instead we set + the field 'found' to true. If a second lookup matches the same + entry, then we know that the hi16s reloc has already been updated + and does not need to be updated a second time. + + TODO - TOFIX: If it is possible that we need to restore 2 different + addresses from the same table entry, where the first generates an + overflow, whilst the second do not, then this code will fail. */ typedef struct hi16s_location { @@ -824,6 +834,7 @@ find_remembered_hi16s_reloc (addend, already_found) /* FIXME: The code here probably ought to be removed and the code in reloc.c allowed to do its stuff instead. At least for most of the relocs, anwyay. */ + static bfd_reloc_status_type v850_elf_perform_relocation (abfd, r_type, addend, address) bfd * abfd; @@ -1028,9 +1039,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address) 0x00000000 + 0x00006fff (bit 15 not set, so the top half is zero) ------------ - 0x00006fff which is wrong (assuming that fred is at 0xffff) - */ - + 0x00006fff which is wrong (assuming that fred is at 0xffff). */ { long result; @@ -1242,6 +1251,7 @@ v850_elf_perform_relocation (abfd, r_type, addend, address) } /* Insert the addend into the instruction. */ + static bfd_reloc_status_type v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) bfd * abfd ATTRIBUTE_UNUSED; @@ -1257,7 +1267,7 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) /* If there is an output BFD, and the symbol is not a section name (which is only defined at final link time), and either we are not putting the addend into the instruction - or the addend is zero, so there is nothing to add into the instruction + or the addend is zero, so there is nothing to add into the instruction then just fixup the address and return. */ if (obfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0 @@ -1269,9 +1279,7 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) } #if 0 else if (obfd != NULL) - { - return bfd_reloc_continue; - } + return bfd_reloc_continue; #endif /* Catch relocs involving undefined symbols. */ @@ -1300,16 +1308,30 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err) relocation += symbol->section->output_offset; relocation += reloc->addend; +#if 0 /* Since this reloc is going to be processed later on, we should + not make it pc-relative here. To test this, try assembling and + linking this program: + + .text + .globl _start + nop + _start: + jr foo + + .section ".foo","ax" + nop + foo: + nop */ if (reloc->howto->pc_relative == true) { /* Here the variable relocation holds the final address of the symbol we are relocating against, plus any addend. */ relocation -= isection->output_section->vma + isection->output_offset; - /* Deal with pcrel_offset */ + /* Deal with pcrel_offset. */ relocation -= reloc->address; } - +#endif reloc->addend = relocation; return bfd_reloc_ok; } @@ -1324,6 +1346,7 @@ v850_elf_is_local_label_name (abfd, name) } /* Perform a relocation as part of a final link. */ + static bfd_reloc_status_type v850_elf_final_link_relocate (howto, input_bfd, output_bfd, input_section, contents, offset, value, @@ -1361,7 +1384,8 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, if (((value & 0xff000000) != 0x0) && ((value & 0xff000000) != 0xff000000)) return bfd_reloc_overflow; - value = SEXT24 (value); /* Only the bottom 24 bits of the PC are valid */ + /* Only the bottom 24 bits of the PC are valid */ + value = SEXT24 (value); break; case R_V850_HI16_S: @@ -1420,7 +1444,8 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - return bfd_reloc_continue; /* Actually this indicates that __ep could not be found. */ + /* Actually this indicates that __ep could not be found. */ + return bfd_reloc_continue; ep = (h->u.def.value + h->u.def.section->output_section->vma @@ -1439,7 +1464,8 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, h = bfd_link_hash_lookup (info->hash, "__ctbp", false, false, true); if (h == (struct bfd_link_hash_entry *) NULL || h->type != bfd_link_hash_defined) - return (bfd_reloc_dangerous + 1); /* Actually this indicates that __ctbp could not be found. */ + /* Actually this indicates that __ctbp could not be found. */ + return bfd_reloc_dangerous + 1; ctbp = (h->u.def.value + h->u.def.section->output_section->vma @@ -1485,6 +1511,7 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd, } /* Relocate an V850 ELF section. */ + static boolean v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) @@ -1573,11 +1600,12 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section, #if 0 { char * name; + name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); name = (name == NULL) ? "" : name; -fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n", - sec->name, name, sym->st_name, - sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend); + fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n", + sec->name, name, sym->st_name, + sec->output_section->vma, sec->output_offset, sym->st_value, rel->r_addend); } #endif } @@ -1597,15 +1625,15 @@ fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n" + sec->output_section->vma + sec->output_offset); #if 0 -fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n", - sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation); + fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n", + sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation); #endif } else if (h->root.type == bfd_link_hash_undefweak) { #if 0 -fprintf (stderr, "undefined: sec: %s, name: %s\n", - sec->name, h->root.root.string); + fprintf (stderr, "undefined: sec: %s, name: %s\n", + sec->name, h->root.root.string); #endif relocation = 0; } @@ -1616,14 +1644,13 @@ fprintf (stderr, "undefined: sec: %s, name: %s\n", input_section, rel->r_offset, true))) return false; #if 0 -fprintf (stderr, "unknown: name: %s\n", h->root.root.string); + fprintf (stderr, "unknown: name: %s\n", h->root.root.string); #endif relocation = 0; } } - /* FIXME: We should use the addend, but the COFF relocations - don't. */ + /* FIXME: We should use the addend, but the COFF relocations don't. */ r = v850_elf_final_link_relocate (howto, input_bfd, output_bfd, input_section, contents, rel->r_offset, @@ -1709,7 +1736,7 @@ v850_elf_gc_sweep_hook (abfd, info, sec, relocs) asection *sec ATTRIBUTE_UNUSED; const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED; { - /* No got and plt entries for v850-elf */ + /* No got and plt entries for v850-elf. */ return true; } @@ -1756,7 +1783,9 @@ v850_elf_gc_mark_hook (abfd, info, rel, h, sym) } return NULL; } + /* Set the right machine number. */ + static boolean v850_elf_object_p (abfd) bfd *abfd; @@ -1772,6 +1801,7 @@ v850_elf_object_p (abfd) } /* Store the machine number in the flags field. */ + static void v850_elf_final_write_processing (abfd, linker) bfd * abfd; @@ -1792,6 +1822,7 @@ v850_elf_final_write_processing (abfd, linker) } /* Function to keep V850 specific file flags. */ + static boolean v850_elf_set_private_flags (abfd, flags) bfd * abfd; @@ -1805,7 +1836,8 @@ v850_elf_set_private_flags (abfd, flags) return true; } -/* Copy backend specific data from one object module to another */ +/* Copy backend specific data from one object module to another. */ + static boolean v850_elf_copy_private_bfd_data (ibfd, obfd) bfd * ibfd; @@ -1822,11 +1854,12 @@ v850_elf_copy_private_bfd_data (ibfd, obfd) elf_gp (obfd) = elf_gp (ibfd); elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; elf_flags_init (obfd) = true; + return true; } -/* Merge backend specific data from an object file to the output - object file when linking. */ +/* Merge backend specific data from an object file + to the output object file when linking. */ static boolean v850_elf_merge_private_bfd_data (ibfd, obfd) bfd * ibfd; @@ -1858,9 +1891,7 @@ v850_elf_merge_private_bfd_data (ibfd, obfd) if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) && bfd_get_arch_info (obfd)->the_default) - { - return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); - } + return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); return true; } @@ -1876,7 +1907,8 @@ v850_elf_merge_private_bfd_data (ibfd, obfd) return true; } -/* Display the flags field */ + +/* Display the flags field. */ static boolean v850_elf_print_private_bfd_data (abfd, ptr) @@ -1922,8 +1954,8 @@ static asection v850_elf_zcom_section; static asymbol v850_elf_zcom_symbol; static asymbol * v850_elf_zcom_symbol_ptr; -/* Given a BFD section, try to locate the corresponding ELF section - index. */ +/* Given a BFD section, try to locate the + corresponding ELF section index. */ static boolean v850_elf_section_from_bfd_section (abfd, hdr, sec, retval) @@ -2103,7 +2135,6 @@ v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) return true; } -/*ARGSIGNORED*/ static boolean v850_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec) bfd * abfd ATTRIBUTE_UNUSED; @@ -2157,8 +2188,9 @@ v850_elf_section_from_shdr (abfd, hdr, name) return true; } -/* Set the correct type for a V850 ELF section. We do this by the - section name, which is a hack, but ought to work. */ +/* Set the correct type for a V850 ELF section. We do this + by the section name, which is a hack, but ought to work. */ + static boolean v850_elf_fake_sections (abfd, hdr, sec) bfd * abfd ATTRIBUTE_UNUSED;