aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2005-08-04 06:22:14 +0000
committerAlan Modra <amodra@gmail.com>2005-08-04 06:22:14 +0000
commit046183de0ebe379c1ec11188000bb6e0f64a9e0e (patch)
tree3eb7034b61e33a4305933aeca12fda76ab10f662 /bfd
parentfa498e09475dc0fc2d6e12f440f3f38df470100a (diff)
downloadgdb-046183de0ebe379c1ec11188000bb6e0f64a9e0e.zip
gdb-046183de0ebe379c1ec11188000bb6e0f64a9e0e.tar.gz
gdb-046183de0ebe379c1ec11188000bb6e0f64a9e0e.tar.bz2
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')
-rw-r--r--bfd/ChangeLog20
-rw-r--r--bfd/bfd-in.h6
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/elf32-ppc.c171
-rw-r--r--bfd/elflink.c59
5 files changed, 122 insertions, 140 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 98fb936..3854c21 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,25 @@
2005-08-04 Alan Modra <amodra@bigpond.net.au>
+ * 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.
+
+2005-08-04 Alan Modra <amodra@bigpond.net.au>
+
* elflink.c (fix_syms, _bfd_elf_fix_excluded_sec_syms): Move to..
* linker.c (fix_syms, _bfd_fix_excluded_sec_syms): ..here.
* bfd-in.h (_bfd_fix_excluded_sec_syms): Rename.
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 39a82cb..cd3bc76 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -702,12 +702,6 @@ extern int bfd_get_sign_extend_vma
extern struct bfd_section *_bfd_elf_tls_setup
(bfd *, struct bfd_link_info *);
-extern void _bfd_elf_provide_symbol
- (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *);
-
-extern void _bfd_elf_provide_section_bound_symbols
- (struct bfd_link_info *, struct bfd_section *, const char *, const char *);
-
extern void _bfd_fix_excluded_sec_syms
(bfd *, struct bfd_link_info *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 50ac263..8ca1d6f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -709,12 +709,6 @@ extern int bfd_get_sign_extend_vma
extern struct bfd_section *_bfd_elf_tls_setup
(bfd *, struct bfd_link_info *);
-extern void _bfd_elf_provide_symbol
- (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *);
-
-extern void _bfd_elf_provide_section_bound_symbols
- (struct bfd_link_info *, struct bfd_section *, const char *, const char *);
-
extern void _bfd_fix_excluded_sec_syms
(bfd *, struct bfd_link_info *);
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5f51a3a..168e58c 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
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 457ba8e..7b7cddd 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5032,6 +5032,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
asection *dynstr;
struct bfd_elf_version_tree *t;
struct bfd_elf_version_expr *d;
+ asection *s;
bfd_boolean all_defined;
*sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
@@ -5235,7 +5236,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
return FALSE;
}
- if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL)
+ s = bfd_get_section_by_name (output_bfd, ".preinit_array");
+ if (s != NULL && s->linker_has_input)
{
/* DT_PREINIT_ARRAY is not allowed in shared library. */
if (! info->executable)
@@ -5263,13 +5265,15 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|| !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
return FALSE;
}
- if (bfd_get_section_by_name (output_bfd, ".init_array") != NULL)
+ s = bfd_get_section_by_name (output_bfd, ".init_array");
+ if (s != NULL && s->linker_has_input)
{
if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
|| !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
return FALSE;
}
- if (bfd_get_section_by_name (output_bfd, ".fini_array") != NULL)
+ s = bfd_get_section_by_name (output_bfd, ".fini_array");
+ if (s != NULL && s->linker_has_input)
{
if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
|| !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
@@ -9841,55 +9845,6 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
bfd_section_already_linked_table_insert (already_linked_list, sec);
}
-static void
-bfd_elf_set_symbol (struct elf_link_hash_entry *h, bfd_vma val,
- struct bfd_section *s)
-{
- h->root.type = bfd_link_hash_defined;
- h->root.u.def.section = s ? s : bfd_abs_section_ptr;
- h->root.u.def.value = val;
- h->def_regular = 1;
- h->type = STT_OBJECT;
- h->other = STV_HIDDEN | (h->other & ~ ELF_ST_VISIBILITY (-1));
- h->forced_local = 1;
-}
-
-/* Set NAME to VAL if the symbol exists and is not defined in a regular
- object file. If S is NULL it is an absolute symbol, otherwise it is
- relative to that section. */
-
-void
-_bfd_elf_provide_symbol (struct bfd_link_info *info, const char *name,
- bfd_vma val, struct bfd_section *s)
-{
- struct elf_link_hash_entry *h;
-
- bfd_elf_record_link_assignment (info, name, TRUE);
-
- h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
- if (h != NULL
- && !(h->root.type == bfd_link_hash_defined
- && h->root.u.def.section != NULL
- && h->root.u.def.section != h->root.u.def.section->output_section))
- bfd_elf_set_symbol (h, val, s);
-}
-
-/* Set START and END to boundaries of SEC if they exist and are not
- defined in regular object files. */
-
-void
-_bfd_elf_provide_section_bound_symbols (struct bfd_link_info *info,
- asection *sec,
- const char *start,
- const char *end)
-{
- bfd_vma val = 0;
- _bfd_elf_provide_symbol (info, start, val, sec);
- if (sec != NULL)
- val = sec->size;
- _bfd_elf_provide_symbol (info, end, val, sec);
-}
-
bfd_boolean
_bfd_elf_common_definition (Elf_Internal_Sym *sym)
{