diff options
author | Alan Modra <amodra@gmail.com> | 2005-08-04 06:22:14 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2005-08-04 06:22:14 +0000 |
commit | 046183de0ebe379c1ec11188000bb6e0f64a9e0e (patch) | |
tree | 3eb7034b61e33a4305933aeca12fda76ab10f662 /bfd/elf32-ppc.c | |
parent | fa498e09475dc0fc2d6e12f440f3f38df470100a (diff) | |
download | ppe42-binutils-046183de0ebe379c1ec11188000bb6e0f64a9e0e.tar.gz ppe42-binutils-046183de0ebe379c1ec11188000bb6e0f64a9e0e.zip |
bfd/
* elf32-ppc.c (struct elf_linker_section): Replace sym_val field
with sym.
(ppc_elf_relocate_section): Adjust for above.
(create_sdata_sym): New function.
(ppc_elf_create_linker_section): Call it.
(ppc_elf_check_relocs): Correct has_sda_refs and non_got_refs.
Create sdata syms for all SDA relocs.
(ppc_elf_adjust_dynamic_symbol): Don't special case _SDA_BASE_
and _SDA2_BASE_.
(ppc_elf_set_sdata_syms): Delete.
* elflink.c (bfd_elf_size_dynamic_sections): Don't create DT_INIT
and DT_FINI tags unless associated section has input.
(bfd_elf_set_symbol, _bfd_elf_provide_symbol): Delete.
(_bfd_elf_provide_section_bound_symbols): Delete.
* bfd-in.h (_bfd_elf_provide_symbol): Delete.
(_bfd_elf_provide_section_bound_symbols): Delete.
* bfd-in2.h: Regenerate.
ld/
* ldemul.c (ldemul_do_assignments, do_assignments_default): Delete.
* ldemul.h (ldemul_do_assignments, do_assignments_default): Delete.
(struct ld_emulation_xfer_struct): Remove do_assignments field.
* ldlang.c (lang_do_assignments): Don't call ldemul_do_assignments.
* emulparams/elf32ppc.sh (SDATA_START_SYMBOLS): New.
(SDATA2_START_SYMBOLS, SBSS_START_SYMBOLS, SBSS_END_SYMBOLS): New.
* emultempl/aix.em (ld_*_emulation): Delete do_assignments init.
* emultempl/armcoff.em: Likewise.
* emultempl/beos.em: Likewise.
* emultempl/generic.em: Likewise.
* emultempl/gld960.em: Likewise.
* emultempl/gld960c.em: Likewise.
* emultempl/linux.em: Likewise.
* emultempl/lnk960.em: Likewise.
* emultempl/m68kcoff.em: Likewise.
* emultempl/pe.em: Likewise.
* emultempl/sunos.em: Likewise.
* emultempl/ticoff.em: Likewise.
* emultempl/vanilla.em: Likewise.
* emultempl/elf32.em: Likewise.
(gld*_provide_bound_symbols): Delete.
(gld*_provide_init_fini_syms): Delete.
(gld*_before_allocation): Don't call ldemul_do_assignments.
* emultempl/ppc32elf.em (ppc_do_assignments): Delete.
(LDEMUL_DO_ASSIGNMENTS): Delete.
* scripttempl/elf.sc: Provide init/fini syms. Add SBSS_START_SYMBOLS,
SBSS_END_SYMBOLS, SDATA2_START_SYMBOLS.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r-- | bfd/elf32-ppc.c | 171 |
1 files changed, 95 insertions, 76 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 5f51a3a7fb..168e58cdaf 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -1668,8 +1668,8 @@ typedef struct elf_linker_section const char *bss_name; /* Associated symbol name. */ const char *sym_name; - /* Value of symbol. */ - bfd_vma sym_val; + /* Associated symbol. */ + struct elf_link_hash_entry *sym; } elf_linker_section_t; /* Linked list of allocated pointer entries. This hangs off of the @@ -2734,6 +2734,20 @@ ppc_elf_add_symbol_hook (bfd *abfd, return TRUE; } +static bfd_boolean +create_sdata_sym (struct ppc_elf_link_hash_table *htab, + elf_linker_section_t *lsect) +{ + lsect->sym = elf_link_hash_lookup (&htab->elf, lsect->sym_name, + TRUE, FALSE, TRUE); + if (lsect->sym == NULL) + return FALSE; + if (lsect->sym->root.type == bfd_link_hash_new) + lsect->sym->non_elf = 0; + lsect->sym->ref_regular = 1; + return TRUE; +} + /* Create a special linker section. */ static bfd_boolean @@ -2760,7 +2774,7 @@ ppc_elf_create_linker_section (bfd *abfd, return FALSE; lsect->section = s; - return TRUE; + return create_sdata_sym (htab, lsect); } /* Find a linker generated pointer with a given addend and type. */ @@ -3090,6 +3104,11 @@ ppc_elf_check_relocs (bfd *abfd, if (!elf_create_pointer_linker_section (abfd, &htab->sdata[0], h, rel)) return FALSE; + if (h != NULL) + { + ppc_elf_hash_entry (h)->has_sda_refs = TRUE; + h->non_got_ref = TRUE; + } break; /* Indirect .sdata2 relocation. */ @@ -3106,12 +3125,65 @@ ppc_elf_check_relocs (bfd *abfd, if (!elf_create_pointer_linker_section (abfd, &htab->sdata[1], h, rel)) return FALSE; + if (h != NULL) + { + ppc_elf_hash_entry (h)->has_sda_refs = TRUE; + h->non_got_ref = TRUE; + } break; case R_PPC_SDAREL16: + if (info->shared) + { + bad_shared_reloc (abfd, r_type); + return FALSE; + } + if (htab->sdata[0].sym == NULL + && !create_sdata_sym (htab, &htab->sdata[0])) + return FALSE; + if (h != NULL) + { + ppc_elf_hash_entry (h)->has_sda_refs = TRUE; + h->non_got_ref = TRUE; + } + break; + case R_PPC_EMB_SDA2REL: + if (info->shared) + { + bad_shared_reloc (abfd, r_type); + return FALSE; + } + if (htab->sdata[1].sym == NULL + && !create_sdata_sym (htab, &htab->sdata[1])) + return FALSE; + if (h != NULL) + { + ppc_elf_hash_entry (h)->has_sda_refs = TRUE; + h->non_got_ref = TRUE; + } + break; + case R_PPC_EMB_SDA21: case R_PPC_EMB_RELSDA: + if (info->shared) + { + bad_shared_reloc (abfd, r_type); + return FALSE; + } + if (htab->sdata[0].sym == NULL + && !create_sdata_sym (htab, &htab->sdata[0])) + return FALSE; + if (htab->sdata[1].sym == NULL + && !create_sdata_sym (htab, &htab->sdata[1])) + return FALSE; + if (h != NULL) + { + ppc_elf_hash_entry (h)->has_sda_refs = TRUE; + h->non_got_ref = TRUE; + } + break; + case R_PPC_EMB_NADDR32: case R_PPC_EMB_NADDR16: case R_PPC_EMB_NADDR16_LO: @@ -3123,11 +3195,7 @@ ppc_elf_check_relocs (bfd *abfd, return FALSE; } if (h != NULL) - { - ppc_elf_hash_entry (h)->has_sda_refs = TRUE; - /* We may need a copy reloc. */ - h->non_got_ref = TRUE; - } + h->non_got_ref = TRUE; break; case R_PPC_PLT32: @@ -4046,24 +4114,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, /* This is a reference to a symbol defined by a dynamic object which is not a function. */ - /* First, a fudge for old shared libs that export some symbols they - should not. */ - if (!h->def_regular - && (strcmp (h->root.root.string, "_SDA_BASE_") == 0 - || strcmp (h->root.root.string, "_SDA2_BASE_") == 0)) - { - /* These symbols will be defined later, as if they were defined in - a linker script. We don't want to use a definition in a shared - object. */ - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (htab->elf.dynobj); - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = htab->elf.dynobj; - return TRUE; - } - /* If we are creating a shared library, we must presume that the only references to the symbol are via the global offset table. For such cases we need not do anything here; the relocations will @@ -5259,52 +5309,6 @@ ppc_elf_relax_section (bfd *abfd, return FALSE; } -/* Set _SDA_BASE_, _SDA2_BASE, and sbss start and end syms. They are - set here rather than via PROVIDE in the default linker script, - because using PROVIDE inside an output section statement results in - unnecessary output sections. Using PROVIDE outside an output section - statement runs the risk of section alignment affecting where the - section starts. */ - -void -ppc_elf_set_sdata_syms (bfd *obfd, struct bfd_link_info *info) -{ - struct ppc_elf_link_hash_table *htab; - unsigned i; - asection *s; - bfd_vma val; - - htab = ppc_elf_hash_table (info); - - for (i = 0; i < 2; i++) - { - elf_linker_section_t *lsect = &htab->sdata[i]; - - s = lsect->section; - if (s != NULL) - s = s->output_section; - if (s == NULL) - s = bfd_get_section_by_name (obfd, lsect->name); - if (s == NULL) - s = bfd_get_section_by_name (obfd, lsect->bss_name); - - if (s) - { - /* VxWorks executables are relocatable, so the sdata base symbols - must be section-relative. */ - val = 32768; - lsect->sym_val = val + s->vma; - } - else - { - val = 0; - lsect->sym_val = 0; - } - - _bfd_elf_provide_symbol (info, lsect->sym_name, val, s); - } -} - /* What to do when ld finds relocations against symbols defined in discarded sections. */ @@ -6348,6 +6352,7 @@ ppc_elf_relocate_section (bfd *output_bfd, case R_PPC_SDAREL16: { const char *name; + struct elf_link_hash_entry *sh; BFD_ASSERT (sec != NULL); name = bfd_get_section_name (abfd, sec->output_section); @@ -6364,7 +6369,10 @@ ppc_elf_relocate_section (bfd *output_bfd, howto->name, name); } - addend -= htab->sdata[0].sym_val; + sh = htab->sdata[0].sym; + addend -= (sh->root.u.def.value + + sh->root.u.def.section->output_offset + + sh->root.u.def.section->output_section->vma); } break; @@ -6372,6 +6380,7 @@ ppc_elf_relocate_section (bfd *output_bfd, case R_PPC_EMB_SDA2REL: { const char *name; + struct elf_link_hash_entry *sh; BFD_ASSERT (sec != NULL); name = bfd_get_section_name (abfd, sec->output_section); @@ -6390,7 +6399,10 @@ ppc_elf_relocate_section (bfd *output_bfd, ret = FALSE; continue; } - addend -= htab->sdata[1].sym_val; + sh = htab->sdata[1].sym; + addend -= (sh->root.u.def.value + + sh->root.u.def.section->output_offset + + sh->root.u.def.section->output_section->vma); } break; @@ -6400,6 +6412,7 @@ ppc_elf_relocate_section (bfd *output_bfd, { const char *name; int reg; + struct elf_link_hash_entry *sh; BFD_ASSERT (sec != NULL); name = bfd_get_section_name (abfd, sec->output_section); @@ -6409,14 +6422,20 @@ ppc_elf_relocate_section (bfd *output_bfd, && (name[5] == 0 || name[5] == '.')))) { reg = 13; - addend -= htab->sdata[0].sym_val; + sh = htab->sdata[0].sym; + addend -= (sh->root.u.def.value + + sh->root.u.def.section->output_offset + + sh->root.u.def.section->output_section->vma); } else if (strncmp (name, ".sdata2", 7) == 0 || strncmp (name, ".sbss2", 6) == 0) { reg = 2; - addend -= htab->sdata[1].sym_val; + sh = htab->sdata[1].sym; + addend -= (sh->root.u.def.value + + sh->root.u.def.section->output_offset + + sh->root.u.def.section->output_section->vma); } else if (strcmp (name, ".PPC.EMB.sdata0") == 0 |