diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 52 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 23 | ||||
-rw-r--r-- | bfd/elf-m10300.c | 2 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 28 | ||||
-rw-r--r-- | bfd/elf32-cris.c | 19 | ||||
-rw-r--r-- | bfd/elf32-hppa.c | 18 | ||||
-rw-r--r-- | bfd/elf32-i370.c | 15 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 2 | ||||
-rw-r--r-- | bfd/elf32-m32r.c | 2 | ||||
-rw-r--r-- | bfd/elf32-m68k.c | 19 | ||||
-rw-r--r-- | bfd/elf32-mips.c | 1 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 10 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 9 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 2 | ||||
-rw-r--r-- | bfd/elf32-sparc.c | 1 | ||||
-rw-r--r-- | bfd/elf32-vax.c | 15 | ||||
-rw-r--r-- | bfd/elf32-xstormy16.c | 2 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 2 | ||||
-rw-r--r-- | bfd/elf64-alpha.c | 2 | ||||
-rw-r--r-- | bfd/elf64-hppa.c | 2 | ||||
-rw-r--r-- | bfd/elf64-mips.c | 1 | ||||
-rw-r--r-- | bfd/elf64-mmix.c | 2 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 12 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 10 | ||||
-rw-r--r-- | bfd/elf64-sh64.c | 2 | ||||
-rw-r--r-- | bfd/elf64-sparc.c | 2 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 13 | ||||
-rw-r--r-- | bfd/elflink.c | 86 | ||||
-rw-r--r-- | bfd/elfn32-mips.c | 1 | ||||
-rw-r--r-- | bfd/elfxx-ia64.c | 2 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 5 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 17 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 5 | ||||
-rw-r--r-- | bfd/linker.c | 23 |
34 files changed, 369 insertions, 38 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index eba1f15..03cff6c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,55 @@ +2006-10-17 Alan Modra <amodra@bigpond.net.au> + + * elf-bfd.h (struct elf_link_hash_table): Reorder. Add + text_index_section and data_index_section. + (struct elf_backend_data): Add elf_backend_init_index_section. + (_bfd_elf_init_1_index_section): Declare. + (_bfd_elf_init_2_index_sections): Declare. + * elfxx-target.h (elf_backend_init_index_section): Define. + (elfNN_bed): Init new field. + * elflink.c (_bfd_elf_link_omit_section_dynsym): Keep first tls + section and text_index_section plus data_index_section. + (_bfd_elf_link_renumber_dynsyms): Clear dynindx on omitted sections. + (_bfd_elf_init_1_index_section): New function. + (_bfd_elf_init_2_index_sections): New function. + (bfd_elf_size_dynsym_hash_dynstr): Call elf_backend_init_index_section. + (elf_link_input_bfd): When emitting relocs, use text_index_section + and data_index_section for removed sections. + * elf-m10300.c (elf_backend_omit_section_dynsym): Define. + * elf32-i386.c: Likewise. + * elf32-m32r.c: Likewise. + * elf32-sh.c: Likewise. + * elf32-xstormy16.c: Likewise. + * elf32-xtensa.c: Likewise. + * elf64-alpha.c: Likewise. + * elf64-hppa.c: Likewise. + * elf64-mmix.c: Likewise. + * elf64-sh64.c: Likewise. + * elfxx-ia64.c: Likewise. + * elf32-arm.c (elf32_arm_final_link_relocate): Use text_index_section + and data_index_section sym for relocs against sections with no dynamic + section sym. + (elf_backend_init_index_section): Define. + * elf32-cris.c: Similarly. + * elf32-hppa.c: Similarly. + * elf32-i370.c: Similarly. + * elf32-m68k.c: Similarly. + * elf32-mips.c: Similarly. + * elf32-ppc.c: Similarly. + * elf32-s390.c: Similarly. + * elf32-sparc.c: Similarly. + * elf32-vax.c: Similarly. + * elf64-mips.c: Similarly. + * elf64-ppc.c: Similarly. + * elf64-s390.c: Similarly. + * elf64-sparc.c: Similarly. + * elf64-x86-64.c: Similarly. + * elfn32-mips.c: Similarly. + * elfxx-mips.c: Similarly. + * elfxx-sparc.c: Similarly. + * linker.c (fix_syms): Base symbols in removed sections on + previous section in preference to using absolute section. + 2006-10-16 Andreas Schwab <schwab@suse.de> * elfxx-ia64.c (addend_compare): Properly compute return value. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 1e541da..bb86c4e 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -345,6 +345,10 @@ struct elf_link_hash_table when linking against or generating a shared object. */ bfd_boolean dynamic_sections_created; + /* True if this target has relocatable executables, so needs dynamic + section symbols. */ + bfd_boolean is_relocatable_executable; + /* The BFD used to hold special sections created by the linker. This will be the first BFD found which requires these sections to be created. */ @@ -378,6 +382,12 @@ struct elf_link_hash_table included in the link. */ struct bfd_link_needed_list *needed; + /* Sections in the output bfd that provides a section symbol + to be used by relocations emitted against local symbols. + Most targets will not use data_index_section. */ + asection *text_index_section; + asection *data_index_section; + /* The _GLOBAL_OFFSET_TABLE_ symbol. */ struct elf_link_hash_entry *hgot; @@ -406,10 +416,6 @@ struct elf_link_hash_table /* A linked list of BFD's loaded in the link. */ struct elf_link_loaded_list *loaded; - - /* True if this target has relocatable executables, so needs dynamic - section symbols. */ - bfd_boolean is_relocatable_executable; }; /* Look up an entry in an ELF linker hash table. */ @@ -766,6 +772,11 @@ struct elf_backend_data bfd_boolean (*elf_backend_size_dynamic_sections) (bfd *output_bfd, struct bfd_link_info *info); + /* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections + we keep to use as a base for relocs and symbols. */ + void (*elf_backend_init_index_section) + (bfd *output_bfd, struct bfd_link_info *info); + /* The RELOCATE_SECTION function is called by the ELF backend linker to handle the relocations for a section. @@ -1697,6 +1708,10 @@ extern bfd_boolean _bfd_elf_create_got_section (bfd *, struct bfd_link_info *); extern struct elf_link_hash_entry *_bfd_elf_define_linkage_sym (bfd *, struct bfd_link_info *, asection *, const char *); +extern void _bfd_elf_init_1_index_section + (bfd *, struct bfd_link_info *); +extern void _bfd_elf_init_2_index_sections + (bfd *, struct bfd_link_info *); extern bfd_boolean _bfd_elfcore_make_pseudosection (bfd *, char *, size_t, ufile_ptr); diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 423ec52..7a72925 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -4756,6 +4756,8 @@ _bfd_mn10300_elf_reloc_type_class (const Elf_Internal_Rela *rela) _bfd_mn10300_elf_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ _bfd_mn10300_elf_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_symbol \ _bfd_mn10300_elf_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index bdbdd6a..f4342b6 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3731,6 +3731,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, value |= 1; if (globals->symbian_p) { + asection *osec; + /* On Symbian OS, the data segment and text segement can be relocated independently. Therefore, we must indicate the segment to which this @@ -3738,11 +3740,27 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, use any symbol in the right segment; we just use the section symbol as it is convenient. (We cannot use the symbol given by "h" directly as it - will not appear in the dynamic symbol table.) */ + will not appear in the dynamic symbol table.) + + Note that the dynamic linker ignores the section + symbol value, so we don't subtract osec->vma + from the emitted reloc addend. */ if (sym_sec) - symbol = elf_section_data (sym_sec->output_section)->dynindx; + osec = sym_sec->output_section; else - symbol = elf_section_data (input_section->output_section)->dynindx; + osec = input_section->output_section; + symbol = elf_section_data (osec)->dynindx; + if (symbol == 0) + { + struct elf_link_hash_table *htab = elf_hash_table (info); + + if ((osec->flags & SEC_READONLY) == 0 + && htab->data_index_section != NULL) + osec = htab->data_index_section; + else + osec = htab->text_index_section; + symbol = elf_section_data (osec)->dynindx; + } BFD_ASSERT (symbol != 0); } else @@ -8551,7 +8569,8 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info /* UnixWare sets the entsize of .plt to 4, although that doesn't really seem like the right value. */ - elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; + if (splt->output_section->owner == output_bfd) + elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; if (htab->vxworks_p && !info->shared && htab->splt->size > 0) { @@ -9494,6 +9513,7 @@ const struct elf_size_info elf32_arm_size_info = { #define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections #define elf_backend_link_output_symbol_hook elf32_arm_output_symbol_hook #define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_2_index_sections #define elf_backend_post_process_headers elf32_arm_post_process_headers #define elf_backend_reloc_type_class elf32_arm_reloc_type_class #define elf_backend_object_p elf32_arm_object_p diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index 66c8219..199ee1b 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1430,11 +1430,12 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { + outrel.r_addend = relocation + rel->r_addend; + if (r_type == R_CRIS_32) { relocate = TRUE; outrel.r_info = ELF32_R_INFO (0, R_CRIS_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; } else { @@ -1451,13 +1452,24 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; - BFD_ASSERT (indx > 0); + if (indx == 0) + { + struct elf_cris_link_hash_table *htab; + htab = elf_cris_hash_table (info); + osec = htab->root.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); } outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; } } @@ -3390,6 +3402,7 @@ elf_cris_reloc_type_class (rela) elf_cris_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ elf_cris_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_finish_dynamic_symbol \ elf_cris_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 0a8b3b1..db6e842 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -4024,17 +4024,22 @@ elf32_hppa_relocate_section (bfd *output_bfd, && sym_sec->output_section != NULL && ! bfd_is_abs_section (sym_sec)) { - /* Skip this relocation if the output section has - been discarded. */ - if (bfd_is_abs_section (sym_sec->output_section)) - break; + asection *osec; + + osec = sym_sec->output_section; + indx = elf_section_data (osec)->dynindx; + if (indx == 0) + { + osec = htab->etab.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); - indx = elf_section_data (sym_sec->output_section)->dynindx; /* We are turning this relocation into one against a section symbol, so subtract out the output section's address but not the offset of the input section in the output section. */ - outrel.r_addend -= sym_sec->output_section->vma; + outrel.r_addend -= osec->vma; } outrel.r_info = ELF32_R_INFO (indx, r_type); @@ -4642,6 +4647,7 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type) #define elf_backend_finish_dynamic_symbol elf32_hppa_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections elf32_hppa_finish_dynamic_sections #define elf_backend_size_dynamic_sections elf32_hppa_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_gc_mark_hook elf32_hppa_gc_mark_hook #define elf_backend_gc_sweep_hook elf32_hppa_gc_sweep_hook #define elf_backend_grok_prstatus elf32_hppa_grok_prstatus diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 3c7c372..4930581 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1290,9 +1290,21 @@ i370_elf_relocate_section (bfd *output_bfd, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; - BFD_ASSERT(indx > 0); + if (indx == 0) + { + struct elf_link_hash_table *htab; + htab = elf_hash_table (info); + osec = htab->text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); #ifdef DEBUG if (indx <= 0) { @@ -1427,6 +1439,7 @@ i370_elf_post_process_headers (bfd * abfd, link glibc's ld.so without errors. */ #define elf_backend_create_dynamic_sections i370_elf_create_dynamic_sections #define elf_backend_size_dynamic_sections i370_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_finish_dynamic_sections i370_elf_finish_dynamic_sections #define elf_backend_fake_sections i370_elf_fake_sections #define elf_backend_section_from_shdr i370_elf_section_from_shdr diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 227bc9e..97054a5 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3872,6 +3872,8 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h) #define elf_backend_relocate_section elf_i386_relocate_section #define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections #define elf_backend_always_size_sections elf_i386_always_size_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_plt_sym_val elf_i386_plt_sym_val #define elf_backend_hash_symbol elf_i386_hash_symbol diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 7456c1c..30674f3 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -4141,6 +4141,8 @@ m32r_elf_reloc_type_class (const Elf_Internal_Rela *rela) #define elf_backend_create_dynamic_sections m32r_elf_create_dynamic_sections #define bfd_elf32_bfd_link_hash_table_create m32r_elf_link_hash_table_create #define elf_backend_size_dynamic_sections m32r_elf_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_sections m32r_elf_finish_dynamic_sections #define elf_backend_adjust_dynamic_symbol m32r_elf_adjust_dynamic_symbol #define elf_backend_finish_dynamic_symbol m32r_elf_finish_dynamic_symbol diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 50b962d..81d219d 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1833,11 +1833,12 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, else { /* This symbol is local, or marked to become local. */ + outrel.r_addend = relocation + rel->r_addend; + if (r_type == R_68K_32) { relocate = TRUE; outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; } else { @@ -1854,13 +1855,24 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; - BFD_ASSERT (indx > 0); + if (indx == 0) + { + struct elf_link_hash_table *htab; + htab = elf_hash_table (info); + osec = htab->text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); } outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; } } @@ -2418,6 +2430,7 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt, elf_m68k_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ elf_m68k_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section elf_m68k_relocate_section #define elf_backend_finish_dynamic_symbol \ elf_m68k_finish_dynamic_symbol diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 1a293a0..c5e7dd4 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1513,6 +1513,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { _bfd_mips_elf_always_size_sections #define elf_backend_size_dynamic_sections \ _bfd_mips_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section _bfd_mips_elf_relocate_section #define elf_backend_finish_dynamic_symbol \ _bfd_mips_elf_finish_dynamic_symbol diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 7b3e722..59bac50 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6280,9 +6280,14 @@ ppc_elf_relocate_section (bfd *output_bfd, but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; - BFD_ASSERT (indx > 0); + if (indx == 0) + { + osec = htab->elf.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); #ifdef DEBUG - if (indx <= 0) + if (indx == 0) printf ("indx=%ld section=%s flags=%08x name=%s\n", indx, osec->name, osec->flags, h->root.root.string); @@ -7472,6 +7477,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, #define elf_backend_get_sec_type_attr ppc_elf_get_sec_type_attr #define elf_backend_plt_sym_val ppc_elf_plt_sym_val #define elf_backend_action_discarded ppc_elf_action_discarded +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #include "elf32-target.h" diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 287e683..83bf5e1 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2630,14 +2630,18 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, osec = sec->output_section; sindx = elf_section_data (osec)->dynindx; - BFD_ASSERT (sindx > 0); + if (sindx == 0) + { + osec = htab->elf.text_index_section; + sindx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (sindx != 0); /* We are turning this relocation into one against a section symbol, so subtract out the output section's address but not the offset of the input section in the output section. */ - outrel.r_addend -= osec->vma; } outrel.r_info = ELF32_R_INFO (sindx, r_type); @@ -3542,6 +3546,7 @@ elf_s390_plt_sym_val (bfd_vma i, const asection *plt, #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_relocate_section elf_s390_relocate_section #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_grok_prstatus elf_s390_grok_prstatus #define elf_backend_plt_sym_val elf_s390_plt_sym_val diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 02093cf..85f3d8f 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -6028,6 +6028,8 @@ sh_elf_plt_sym_val (bfd_vma i, const asection *plt, sh_elf_always_size_sections #define elf_backend_size_dynamic_sections \ sh_elf_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_symbol \ sh_elf_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 3f0c7d6..5f13b96 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -207,6 +207,7 @@ elf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela) #define elf_backend_gc_mark_hook _bfd_sparc_elf_gc_mark_hook #define elf_backend_gc_sweep_hook _bfd_sparc_elf_gc_sweep_hook #define elf_backend_plt_sym_val _bfd_sparc_elf_plt_sym_val +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index fe8ea03..2572b68 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1680,9 +1680,21 @@ elf_vax_relocate_section (bfd *output_bfd, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; - BFD_ASSERT (indx > 0); + if (indx == 0) + { + struct elf_link_hash_table *htab; + htab = elf_hash_table (info); + osec = htab->text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); } outrel.r_info = ELF32_R_INFO (indx, r_type); @@ -2062,6 +2074,7 @@ elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) elf_vax_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ elf_vax_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section elf_vax_relocate_section #define elf_backend_finish_dynamic_symbol \ elf_vax_finish_dynamic_symbol diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index 818b62d..c5c88c7 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -999,6 +999,8 @@ xstormy16_elf_gc_mark_hook (asection *sec, #define elf_backend_check_relocs xstormy16_elf_check_relocs #define elf_backend_always_size_sections \ xstormy16_elf_always_size_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_sections \ xstormy16_elf_finish_dynamic_sections diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 2a6c695..34f7f47 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -9844,6 +9844,8 @@ static const struct bfd_elf_special_section elf_xtensa_special_sections[] = #define elf_backend_reloc_type_class elf_xtensa_reloc_type_class #define elf_backend_relocate_section elf_xtensa_relocate_section #define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_special_sections elf_xtensa_special_sections #define elf_backend_action_discarded elf_xtensa_action_discarded diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index f37a317..1f7e546 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -5275,6 +5275,8 @@ static const struct elf_size_info alpha_elf_size_info = elf64_alpha_always_size_sections #define elf_backend_size_dynamic_sections \ elf64_alpha_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_relocate_section \ elf64_alpha_relocate_section #define elf_backend_finish_dynamic_symbol \ diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 4ff7e6a..4b5e95d 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -2820,6 +2820,8 @@ const struct elf_size_info hppa64_elf_size_info = elf64_hppa_create_dynamic_sections #define elf_backend_post_process_headers elf64_hppa_post_process_headers +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_adjust_dynamic_symbol \ elf64_hppa_adjust_dynamic_symbol diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 09d13e8..408c352 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -3034,6 +3034,7 @@ const struct elf_size_info mips_elf64_size_info = _bfd_mips_elf_always_size_sections #define elf_backend_size_dynamic_sections \ _bfd_mips_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section _bfd_mips_elf_relocate_section #define elf_backend_finish_dynamic_symbol \ _bfd_mips_elf_finish_dynamic_symbol diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 63176eb..e18f4a1 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -2916,6 +2916,8 @@ mmix_elf_relax_section (abfd, sec, link_info, again) #define elf_backend_check_relocs mmix_elf_check_relocs #define elf_backend_symbol_processing mmix_elf_symbol_processing +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define bfd_elf64_bfd_is_local_label_name \ mmix_elf_is_local_label_name diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index d87a1b2..fcbc71e 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -97,6 +97,7 @@ static bfd_vma opd_entry_value #define elf_backend_hide_symbol ppc64_elf_hide_symbol #define elf_backend_always_size_sections ppc64_elf_func_desc_adjust #define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_2_index_sections #define elf_backend_action_discarded ppc64_elf_action_discarded #define elf_backend_relocate_section ppc64_elf_relocate_section #define elf_backend_finish_dynamic_symbol ppc64_elf_finish_dynamic_symbol @@ -10840,6 +10841,17 @@ ppc64_elf_relocate_section (bfd *output_bfd, osec = sec->output_section; indx = elf_section_data (osec)->dynindx; + if (indx == 0) + { + if ((osec->flags & SEC_READONLY) == 0 + && htab->elf.data_index_section != NULL) + osec = htab->elf.data_index_section; + else + osec = htab->elf.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (indx != 0); + /* We are turning this relocation into one against a section symbol, so subtract out the output section's address but not the diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 59151d8..1d86820 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2611,14 +2611,19 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, osec = sec->output_section; sindx = elf_section_data (osec)->dynindx; - BFD_ASSERT (sindx > 0); + + if (sindx == 0) + { + osec = htab->elf.text_index_section; + sindx = elf_section_data (osec)->dynindx; + } + BFD_ASSERT (sindx != 0); /* We are turning this relocation into one against a section symbol, so subtract out the output section's address but not the offset of the input section in the output section. */ - outrel.r_addend -= osec->vma; } outrel.r_info = ELF64_R_INFO (sindx, r_type); @@ -3449,6 +3454,7 @@ const struct elf_size_info s390_elf64_size_info = #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_relocate_section elf_s390_relocate_section #define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_reloc_type_class elf_s390_reloc_type_class #define elf_backend_plt_sym_val elf_s390_plt_sym_val diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index e55c19a..5ebea96 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -4094,6 +4094,8 @@ static const struct bfd_elf_special_section sh64_elf64_special_sections[]= sh64_elf64_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ sh64_elf64_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_finish_dynamic_symbol \ sh64_elf64_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections \ diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index 5c928e2..1185553 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -889,6 +889,8 @@ const struct elf_size_info elf64_sparc_size_info = _bfd_sparc_elf_gc_mark_hook #define elf_backend_gc_sweep_hook \ _bfd_sparc_elf_gc_sweep_hook +#define elf_backend_init_index_section \ + _bfd_elf_init_1_index_section #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 23dee16..2556fdc 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2457,9 +2457,19 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; sindx = elf_section_data (osec)->dynindx; - BFD_ASSERT (sindx > 0); + if (sindx == 0) + { + asection *oi = htab->elf.text_index_section; + sindx = elf_section_data (oi)->dynindx; + } + BFD_ASSERT (sindx != 0); } outrel.r_info = ELF64_R_INFO (sindx, r_type); @@ -3657,6 +3667,7 @@ static const struct bfd_elf_special_section #define elf_backend_relocate_section elf64_x86_64_relocate_section #define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections #define elf_backend_always_size_sections elf64_x86_64_always_size_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_plt_sym_val elf64_x86_64_plt_sym_val #define elf_backend_object_p elf64_x86_64_elf_object_p #define bfd_elf64_mkobject elf64_x86_64_mkobject diff --git a/bfd/elflink.c b/bfd/elflink.c index 1df583f..63cac8e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -712,6 +712,8 @@ _bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info, asection *p) { + struct elf_link_hash_table *htab; + switch (elf_section_data (p)->this_hdr.sh_type) { case SHT_PROGBITS: @@ -719,15 +721,21 @@ _bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, /* If sh_type is yet undecided, assume it could be SHT_PROGBITS/SHT_NOBITS. */ case SHT_NULL: + htab = elf_hash_table (info); + if (p == htab->tls_sec) + return FALSE; + + if (htab->text_index_section != NULL) + return p != htab->text_index_section && p != htab->data_index_section; + if (strcmp (p->name, ".got") == 0 || strcmp (p->name, ".got.plt") == 0 || strcmp (p->name, ".plt") == 0) { asection *ip; - bfd *dynobj = elf_hash_table (info)->dynobj; - if (dynobj != NULL - && (ip = bfd_get_section_by_name (dynobj, p->name)) != NULL + if (htab->dynobj != NULL + && (ip = bfd_get_section_by_name (htab->dynobj, p->name)) != NULL && (ip->flags & SEC_LINKER_CREATED) && ip->output_section == p) return TRUE; @@ -763,6 +771,8 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, && (p->flags & SEC_ALLOC) != 0 && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) elf_section_data (p)->dynindx = ++dynsymcount; + else + elf_section_data (p)->dynindx = 0; } *section_sym_count = dynsymcount; @@ -5932,16 +5942,65 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, return TRUE; } +/* Find the first non-excluded output section. We'll use its + section symbol for some emitted relocs. */ +void +_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info) +{ + asection *s; + + for (s = output_bfd->sections; s != NULL; s = s->next) + if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC + && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) + { + elf_hash_table (info)->text_index_section = s; + break; + } +} + +/* Find two non-excluded output sections, one for code, one for data. + We'll use their section symbols for some emitted relocs. */ +void +_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info) +{ + asection *s; + + for (s = output_bfd->sections; s != NULL; s = s->next) + if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) + == (SEC_ALLOC | SEC_READONLY)) + && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) + { + elf_hash_table (info)->text_index_section = s; + break; + } + + for (s = output_bfd->sections; s != NULL; s = s->next) + if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) + && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) + { + elf_hash_table (info)->data_index_section = s; + break; + } + + if (elf_hash_table (info)->text_index_section == NULL) + elf_hash_table (info)->text_index_section + = elf_hash_table (info)->data_index_section; +} + bfd_boolean bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) { + const struct elf_backend_data *bed; + if (!is_elf_hash_table (info->hash)) return TRUE; + bed = get_elf_backend_data (output_bfd); + (*bed->elf_backend_init_index_section) (output_bfd, info); + if (elf_hash_table (info)->dynamic_sections_created) { bfd *dynobj; - const struct elf_backend_data *bed; asection *s; bfd_size_type dynsymcount; unsigned long section_sym_count; @@ -5980,7 +6039,6 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) section as we went along in elf_link_add_object_symbols. */ s = bfd_get_section_by_name (dynobj, ".dynsym"); BFD_ASSERT (s != NULL); - bed = get_elf_backend_data (output_bfd); s->size = dynsymcount * bed->s->sizeof_sym; if (dynsymcount != 0) @@ -7769,6 +7827,24 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) if (!bfd_is_abs_section (osec)) { r_symndx = osec->target_index; + if (r_symndx == 0) + { + struct elf_link_hash_table *htab; + asection *oi; + + htab = elf_hash_table (finfo->info); + oi = htab->text_index_section; + if ((osec->flags & SEC_READONLY) == 0 + && htab->data_index_section != NULL) + oi = htab->data_index_section; + + if (oi != NULL) + { + irela->r_addend += osec->vma - oi->vma; + r_symndx = oi->target_index; + } + } + BFD_ASSERT (r_symndx != 0); } } diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 1e42faa..21cf4af 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -2301,6 +2301,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { _bfd_mips_elf_always_size_sections #define elf_backend_size_dynamic_sections \ _bfd_mips_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section _bfd_mips_elf_relocate_section #define elf_backend_finish_dynamic_symbol \ _bfd_mips_elf_finish_dynamic_symbol diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 89271ea..dbea35b 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -5762,6 +5762,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, elfNN_ia64_adjust_dynamic_symbol #define elf_backend_size_dynamic_sections \ elfNN_ia64_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_relocate_section \ elfNN_ia64_relocate_section #define elf_backend_finish_dynamic_symbol \ diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 83d6258..66cdf14 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -4801,6 +4801,11 @@ mips_elf_create_dynamic_relocation (bfd *output_bfd, { indx = elf_section_data (sec->output_section)->dynindx; if (indx == 0) + { + asection *osec = htab->root.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + if (indx == 0) abort (); } diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index ccbd272..77ffbfe 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2864,6 +2864,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { long indx; + outrel.r_addend = relocation + rel->r_addend; + if (is_plt) sec = htab->splt; @@ -2878,9 +2880,20 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { asection *osec; + /* We are turning this relocation into one + against a section symbol. It would be + proper to subtract the symbol's value, + osec->vma, from the emitted reloc addend, + but ld.so expects buggy relocs. */ osec = sec->output_section; indx = elf_section_data (osec)->dynindx; + if (indx == 0) + { + osec = htab->elf.text_index_section; + indx = elf_section_data (osec)->dynindx; + } + /* FIXME: we really should be able to link non-pic shared libraries. */ if (indx == 0) @@ -2894,8 +2907,8 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } } - outrel.r_info = SPARC_ELF_R_INFO (htab, rel, indx, r_type); - outrel.r_addend = relocation + rel->r_addend; + outrel.r_info = SPARC_ELF_R_INFO (htab, rel, indx, + r_type); } } diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 537cc3b..9e8ceca 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -381,6 +381,10 @@ #ifndef elf_backend_size_dynamic_sections #define elf_backend_size_dynamic_sections 0 #endif +#ifndef elf_backend_init_index_section +#define elf_backend_init_index_section \ + ((void (*) (bfd *, struct bfd_link_info *)) bfd_void) +#endif #ifndef elf_backend_relocate_section #define elf_backend_relocate_section 0 #endif @@ -603,6 +607,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_adjust_dynamic_symbol, elf_backend_always_size_sections, elf_backend_size_dynamic_sections, + elf_backend_init_index_section, elf_backend_relocate_section, elf_backend_finish_dynamic_symbol, elf_backend_finish_dynamic_sections, diff --git a/bfd/linker.c b/bfd/linker.c index ea14d76..257a585 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -3073,7 +3073,7 @@ _bfd_generic_section_already_linked (bfd *abfd, asection *sec) bfd_section_already_linked_table_insert (already_linked_list, sec); } -/* Convert symbols in excluded output sections to absolute. */ +/* Convert symbols in excluded output sections to use a kept section. */ static bfd_boolean fix_syms (struct bfd_link_hash_entry *h, void *data) @@ -3092,8 +3092,27 @@ fix_syms (struct bfd_link_hash_entry *h, void *data) && (s->output_section->flags & SEC_EXCLUDE) != 0 && bfd_section_removed_from_list (obfd, s->output_section)) { + asection *op; + for (op = s->output_section->prev; op != NULL; op = op->prev) + if ((op->flags & SEC_EXCLUDE) == 0 + && !bfd_section_removed_from_list (obfd, op)) + break; + if (op == NULL) + { + if (s->output_section->prev != NULL) + op = s->output_section->prev->next; + else + op = s->output_section->owner->sections; + for (; op != NULL; op = op->next) + if ((op->flags & SEC_EXCLUDE) == 0 + && !bfd_section_removed_from_list (obfd, op)) + break; + if (op == NULL) + op = bfd_abs_section_ptr; + } h->u.def.value += s->output_offset + s->output_section->vma; - h->u.def.section = bfd_abs_section_ptr; + h->u.def.value -= op->vma; + h->u.def.section = op; } } |