PowerPC64 dot-symbol compatibility bugfixes

Lots of fixes for the compatibility code that handles linking of
-mcall-aixdesc code (or that generated by 12 year old gcc) with
current ELFv1 ABI code.

1) A reference to a dot-symbol in an object file wasn't satisfied by a
   function descriptor in later object files.
2) The as-needed code had bit-rotted;  Shared libs now need a strong
   reference to be counted as needed.
3) --gc-sections involving dot-symbols was broken, needing
   func_desc_adjust to be run early and lots of other fixes.

bfd/
	* elf64-ppc.c (struct ppc_link_hash_entry): Delete "was_undefined".
	(struct ppc_link_hash_table): Delete "twiddled_syms".  Add
	"need_func_desc_adj".
	(lookup_fdh): Link direct fdh sym via oh field and set flags.
	(make_fdh): Make strong and weak undefined function descriptor
	symbols.
	(ppc64_elf_merge_symbol): New function.
	(elf_backend_merge_symbol): Define.
	(ppc64_elf_archive_symbol_lookup): Don't test undefweak for fake
	function descriptors.
	(add_symbol_adjust): Don't twiddle symbols to undefweak.
	Propagate more ref flags to function descriptor symbol.  Make
	some function descriptor symbols dynamic.
	(ppc64_elf_before_check_relocs): Only run add_symbol_adjust for
	ELFv1.  Set need_func_desc_adj.  Don't fix undefs list.
	(ppc64_elf_check_relocs): Set non_ir_ref for descriptors.
	Don't call lookup_fdh here.
	(ppc64_elf_gc_sections): New function.
	(bfd_elf64_bfd_gc_sections): Define.
	(ppc64_elf_gc_mark_hook): Mark descriptor.
	(func_desc_adjust): Don't make fake function descriptor syms strong
	here.  Exit earlier on non-dotsyms.  Take note of elf.dynamic
	flag when deciding whether a dynamic function descriptor might
	be needed.  Transfer elf.dynamic and set elf.needs_plt.  Move
	plt regardless of visibility.  Make descriptor dynamic if
	entry sym is dynamic, not for other cases.
	(ppc64_elf_func_desc_adjust): Don't run func_desc_adjust if
	already done.
	(ppc64_elf_edit_opd): Use oh field rather than lookup_fdh.
	(ppc64_elf_size_stubs): Likewise.
	(ppc_build_one_stub): Don't clear was_undefined.  Only set sym
	undefweak if stub symbol is defined.
	(undo_symbol_twiddle, ppc64_elf_restore_symbols): Delete.
	* elf64-ppc.h (ppc64_elf_restore_symbols): Don't declare.
ld/
	* emultempl/ppc64elf.em (gld${EMULATION_NAME}_finish): Don't call
	ppc64_elf_restore_symbols.
	* testsuite/ld-powerpc/dotsym1.d: New.
	* testsuite/ld-powerpc/dotsym2.d: New.
	* testsuite/ld-powerpc/dotsym3.d: New.
	* testsuite/ld-powerpc/dotsym4.d: New.
	* testsuite/ld-powerpc/dotsymref.s: New.
	* testsuite/ld-powerpc/nodotsym.s: New.
	* testsuite/ld-powerpc/powerpc.exp: Run new tests.
This commit is contained in:
Alan Modra 2016-12-03 21:00:01 +10:30
parent 4e95fbcd79
commit 8c5b4e5228
12 changed files with 295 additions and 160 deletions

View File

@ -1,3 +1,40 @@
2016-12-03 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (struct ppc_link_hash_entry): Delete "was_undefined".
(struct ppc_link_hash_table): Delete "twiddled_syms". Add
"need_func_desc_adj".
(lookup_fdh): Link direct fdh sym via oh field and set flags.
(make_fdh): Make strong and weak undefined function descriptor
symbols.
(ppc64_elf_merge_symbol): New function.
(elf_backend_merge_symbol): Define.
(ppc64_elf_archive_symbol_lookup): Don't test undefweak for fake
function descriptors.
(add_symbol_adjust): Don't twiddle symbols to undefweak.
Propagate more ref flags to function descriptor symbol. Make
some function descriptor symbols dynamic.
(ppc64_elf_before_check_relocs): Only run add_symbol_adjust for
ELFv1. Set need_func_desc_adj. Don't fix undefs list.
(ppc64_elf_check_relocs): Set non_ir_ref for descriptors.
Don't call lookup_fdh here.
(ppc64_elf_gc_sections): New function.
(bfd_elf64_bfd_gc_sections): Define.
(ppc64_elf_gc_mark_hook): Mark descriptor.
(func_desc_adjust): Don't make fake function descriptor syms strong
here. Exit earlier on non-dotsyms. Take note of elf.dynamic
flag when deciding whether a dynamic function descriptor might
be needed. Transfer elf.dynamic and set elf.needs_plt. Move
plt regardless of visibility. Make descriptor dynamic if
entry sym is dynamic, not for other cases.
(ppc64_elf_func_desc_adjust): Don't run func_desc_adjust if
already done.
(ppc64_elf_edit_opd): Use oh field rather than lookup_fdh.
(ppc64_elf_size_stubs): Likewise.
(ppc_build_one_stub): Don't clear was_undefined. Only set sym
undefweak if stub symbol is defined.
(undo_symbol_twiddle, ppc64_elf_restore_symbols): Delete.
* elf64-ppc.h (ppc64_elf_restore_symbols): Don't declare.
2016-12-03 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_hide_symbol): Access hash table as

View File

@ -87,6 +87,7 @@ static bfd_vma opd_entry_value
#define bfd_elf64_bfd_link_hash_table_create ppc64_elf_link_hash_table_create
#define bfd_elf64_get_synthetic_symtab ppc64_elf_get_synthetic_symtab
#define bfd_elf64_bfd_link_just_syms ppc64_elf_link_just_syms
#define bfd_elf64_bfd_gc_sections ppc64_elf_gc_sections
#define elf_backend_object_p ppc64_elf_object_p
#define elf_backend_grok_prstatus ppc64_elf_grok_prstatus
@ -118,6 +119,7 @@ static bfd_vma opd_entry_value
#define elf_backend_link_output_symbol_hook ppc64_elf_output_symbol_hook
#define elf_backend_special_sections ppc64_elf_special_sections
#define elf_backend_merge_symbol_attribute ppc64_elf_merge_symbol_attribute
#define elf_backend_merge_symbol ppc64_elf_merge_symbol
/* The name of the dynamic interpreter. This is put in the .interp
section. */
@ -3978,9 +3980,6 @@ struct ppc_link_hash_entry
should be set for all globals defined in any opd/toc section. */
unsigned int adjust_done:1;
/* Set if we twiddled this symbol to weak at some stage. */
unsigned int was_undefined:1;
/* Set if this is an out-of-line register save/restore function,
with non-standard calling convention. */
unsigned int save_res:1;
@ -4087,8 +4086,8 @@ struct ppc_link_hash_table
/* Set on error. */
unsigned int stub_error:1;
/* Temp used by ppc64_elf_before_check_relocs. */
unsigned int twiddled_syms:1;
/* Whether func_desc_adjust needs to be run over symbols. */
unsigned int need_func_desc_adj:1;
/* Incremented every time we size stubs. */
unsigned int stub_iteration;
@ -4898,32 +4897,29 @@ lookup_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
fh->oh = fdh;
}
return ppc_follow_link (fdh);
fdh = ppc_follow_link (fdh);
fdh->is_func_descriptor = 1;
fdh->oh = fh;
return fdh;
}
/* Make a fake function descriptor sym for the code sym FH. */
/* Make a fake function descriptor sym for the undefined code sym FH. */
static struct ppc_link_hash_entry *
make_fdh (struct bfd_link_info *info,
struct ppc_link_hash_entry *fh)
{
bfd *abfd;
asymbol *newsym;
struct bfd_link_hash_entry *bh;
bfd *abfd = fh->elf.root.u.undef.abfd;
struct bfd_link_hash_entry *bh = NULL;
struct ppc_link_hash_entry *fdh;
flagword flags = (fh->elf.root.type == bfd_link_hash_undefweak
? BSF_WEAK
: BSF_GLOBAL);
abfd = fh->elf.root.u.undef.abfd;
newsym = bfd_make_empty_symbol (abfd);
newsym->name = fh->elf.root.root.string + 1;
newsym->section = bfd_und_section_ptr;
newsym->value = 0;
newsym->flags = BSF_WEAK;
bh = NULL;
if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
newsym->flags, newsym->section,
newsym->value, NULL, FALSE, FALSE,
&bh))
if (!_bfd_generic_link_add_one_symbol (info, abfd,
fh->elf.root.root.string + 1,
flags, bfd_und_section_ptr, 0,
NULL, FALSE, FALSE, &bh))
return NULL;
fdh = (struct ppc_link_hash_entry *) bh;
@ -5012,6 +5008,22 @@ ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
| ELF_ST_VISIBILITY (h->other));
}
/* Hook called on merging a symbol. We use this to clear "fake" since
we now have a real symbol. */
static bfd_boolean
ppc64_elf_merge_symbol (struct elf_link_hash_entry *h,
const Elf_Internal_Sym *isym ATTRIBUTE_UNUSED,
asection **psec ATTRIBUTE_UNUSED,
bfd_boolean newdef ATTRIBUTE_UNUSED,
bfd_boolean olddef ATTRIBUTE_UNUSED,
bfd *oldbfd ATTRIBUTE_UNUSED,
const asection *oldsec ATTRIBUTE_UNUSED)
{
((struct ppc_link_hash_entry *) h)->fake = 0;
return TRUE;
}
/* This function makes an old ABI object reference to ".bar" cause the
inclusion of a new ABI object archive that defines "bar".
NAME is a symbol defined in an archive. Return a symbol in the hash
@ -5030,8 +5042,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
if (h != NULL
/* Don't return this sym if it is a fake function descriptor
created by add_symbol_adjust. */
&& !(h->root.type == bfd_link_hash_undefweak
&& ((struct ppc_link_hash_entry *) h)->fake))
&& !((struct ppc_link_hash_entry *) h)->fake)
return h;
if (name[0] == '.')
@ -5077,38 +5088,49 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
return FALSE;
fdh = lookup_fdh (eh, htab);
if (fdh == NULL)
if (fdh == NULL
&& !bfd_link_relocatable (info)
&& (eh->elf.root.type == bfd_link_hash_undefined
|| eh->elf.root.type == bfd_link_hash_undefweak)
&& eh->elf.ref_regular)
{
if (!bfd_link_relocatable (info)
&& (eh->elf.root.type == bfd_link_hash_undefined
|| eh->elf.root.type == bfd_link_hash_undefweak)
&& eh->elf.ref_regular)
{
/* Make an undefweak function descriptor sym, which is enough to
pull in an --as-needed shared lib, but won't cause link
errors. Archives are handled elsewhere. */
fdh = make_fdh (info, eh);
if (fdh == NULL)
return FALSE;
fdh->elf.ref_regular = 1;
}
/* Make an undefined function descriptor sym, in order to
pull in an --as-needed shared lib. Archives are handled
elsewhere. */
fdh = make_fdh (info, eh);
if (fdh == NULL)
return FALSE;
}
else
if (fdh != NULL)
{
unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
/* Make both descriptor and entry symbol have the most
constraining visibility of either symbol. */
if (entry_vis < descr_vis)
fdh->elf.other += entry_vis - descr_vis;
else if (entry_vis > descr_vis)
eh->elf.other += descr_vis - entry_vis;
if ((fdh->elf.root.type == bfd_link_hash_defined
|| fdh->elf.root.type == bfd_link_hash_defweak)
&& eh->elf.root.type == bfd_link_hash_undefined)
/* Propagate reference flags from entry symbol to function
descriptor symbol. */
fdh->elf.root.non_ir_ref |= eh->elf.root.non_ir_ref;
fdh->elf.ref_regular |= eh->elf.ref_regular;
fdh->elf.ref_regular_nonweak |= eh->elf.ref_regular_nonweak;
if (!fdh->elf.forced_local
&& fdh->elf.dynindx == -1
&& fdh->elf.versioned != versioned_hidden
&& (bfd_link_dll (info)
|| fdh->elf.def_dynamic
|| fdh->elf.ref_dynamic)
&& (eh->elf.ref_regular
|| eh->elf.def_regular))
{
eh->elf.root.type = bfd_link_hash_undefweak;
eh->was_undefined = 1;
htab->twiddled_syms = 1;
if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
return FALSE;
}
}
@ -5190,18 +5212,14 @@ ppc64_elf_before_check_relocs (bfd *ibfd, struct bfd_link_info *info)
else if (htab->elf.hgot == NULL
&& strcmp (eh->elf.root.root.string, ".TOC.") == 0)
htab->elf.hgot = &eh->elf;
else if (!add_symbol_adjust (eh, info))
return FALSE;
else if (abiversion (ibfd) <= 1)
{
htab->need_func_desc_adj = 1;
if (!add_symbol_adjust (eh, info))
return FALSE;
}
p = &eh->u.next_dot_sym;
}
/* We need to fix the undefs list for any syms we have twiddled to
undefweak. */
if (htab->twiddled_syms)
{
bfd_link_repair_undef_list (&htab->elf.root);
htab->twiddled_syms = 0;
}
return TRUE;
}
@ -5394,12 +5412,17 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
h = NULL;
else
{
struct ppc_link_hash_entry *eh;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = elf_follow_link (h);
eh = (struct ppc_link_hash_entry *) h;
/* PR15323, ref flags aren't set for references in the same
object. */
h->root.non_ir_ref = 1;
if (eh->is_func && eh->oh != NULL)
eh->oh->elf.root.non_ir_ref = 1;
if (h == htab->elf.hgot)
sec->has_toc_reloc = 1;
@ -5809,14 +5832,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
{
if (h != NULL)
{
if (h->root.root.string[0] == '.'
&& h->root.root.string[1] != 0
&& lookup_fdh ((struct ppc_link_hash_entry *) h, htab))
;
else
((struct ppc_link_hash_entry *) h)->is_func = 1;
}
((struct ppc_link_hash_entry *) h)->is_func = 1;
else
{
asection *s;
@ -6343,6 +6359,23 @@ defined_func_desc (struct ppc_link_hash_entry *fh)
return NULL;
}
static bfd_boolean func_desc_adjust (struct elf_link_hash_entry *, void *);
/* Garbage collect sections, after first dealing with dot-symbols. */
static bfd_boolean
ppc64_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab = ppc_hash_table (info);
if (htab != NULL && htab->need_func_desc_adj)
{
elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
htab->need_func_desc_adj = 0;
}
return bfd_elf_gc_sections (abfd, info);
}
/* Mark all our entry sym sections, both opd and code section. */
static void
@ -6477,7 +6510,15 @@ ppc64_elf_gc_mark_hook (asection *sec,
eh = (struct ppc_link_hash_entry *) h;
fdh = defined_func_desc (eh);
if (fdh != NULL)
eh = fdh;
{
/* -mcall-aixdesc code references the dot-symbol on
a call reloc. Mark the function descriptor too
against garbage collection. */
fdh->elf.mark = 1;
if (fdh->elf.u.weakdef != NULL)
fdh->elf.u.weakdef->mark = 1;
eh = fdh;
}
/* Function descriptor syms cause the associated
function code sym section to be marked. */
@ -6956,7 +6997,6 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
{
struct bfd_link_info *info;
struct ppc_link_hash_table *htab;
struct plt_entry *ent;
struct ppc_link_hash_entry *fh;
struct ppc_link_hash_entry *fdh;
bfd_boolean force_local;
@ -6965,18 +7005,29 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
if (fh->elf.root.type == bfd_link_hash_indirect)
return TRUE;
if (!fh->is_func)
return TRUE;
if (fh->elf.root.root.string[0] != '.'
|| fh->elf.root.root.string[1] == '\0')
return TRUE;
info = inf;
htab = ppc_hash_table (info);
if (htab == NULL)
return FALSE;
/* Find the corresponding function descriptor symbol. */
fdh = lookup_fdh (fh, htab);
/* Resolve undefined references to dot-symbols as the value
in the function descriptor, if we have one in a regular object.
This is to satisfy cases like ".quad .foo". Calls to functions
in dynamic objects are handled elsewhere. */
if (fh->elf.root.type == bfd_link_hash_undefweak
&& fh->was_undefined
&& (fdh = defined_func_desc (fh)) != NULL
if ((fh->elf.root.type == bfd_link_hash_undefined
|| fh->elf.root.type == bfd_link_hash_undefweak)
&& (fdh->elf.root.type == bfd_link_hash_defined
|| fdh->elf.root.type == bfd_link_hash_defweak)
&& get_opd_info (fdh->elf.root.u.def.section) != NULL
&& opd_entry_value (fdh->elf.root.u.def.section,
fdh->elf.root.u.def.value,
@ -6989,23 +7040,18 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
fh->elf.def_dynamic = fdh->elf.def_dynamic;
}
/* If this is a function code symbol, transfer dynamic linking
information to the function descriptor symbol. */
if (!fh->is_func)
return TRUE;
if (!fh->elf.dynamic)
{
struct plt_entry *ent;
for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
if (ent->plt.refcount > 0)
break;
if (ent == NULL
|| fh->elf.root.root.string[0] != '.'
|| fh->elf.root.root.string[1] == '\0')
return TRUE;
for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
if (ent->plt.refcount > 0)
break;
if (ent == NULL)
return TRUE;
}
/* Find the corresponding function descriptor symbol. Create it
as undefined if necessary. */
fdh = lookup_fdh (fh, htab);
/* Create a descriptor as undefined if necessary. */
if (fdh == NULL
&& !bfd_link_executable (info)
&& (fh->elf.root.type == bfd_link_hash_undefined
@ -7016,51 +7062,30 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
return FALSE;
}
/* Fake function descriptors are made undefweak. If the function
code symbol is strong undefined, make the fake sym the same.
If the function code symbol is defined, then force the fake
descriptor local; We can't support overriding of symbols in a
shared library on a fake descriptor. */
/* We can't support overriding of symbols on a fake descriptor. */
if (fdh != NULL
&& fdh->fake
&& fdh->elf.root.type == bfd_link_hash_undefweak)
{
if (fh->elf.root.type == bfd_link_hash_undefined)
{
fdh->elf.root.type = bfd_link_hash_undefined;
bfd_link_add_undef (&htab->elf.root, &fdh->elf.root);
}
else if (fh->elf.root.type == bfd_link_hash_defined
|| fh->elf.root.type == bfd_link_hash_defweak)
{
_bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
}
}
&& (fh->elf.root.type == bfd_link_hash_defined
|| fh->elf.root.type == bfd_link_hash_defweak))
_bfd_elf_link_hash_hide_symbol (info, &fdh->elf, TRUE);
if (fdh != NULL
&& !fdh->elf.forced_local
&& (!bfd_link_executable (info)
|| fdh->elf.def_dynamic
|| fdh->elf.ref_dynamic
|| (fdh->elf.root.type == bfd_link_hash_undefweak
&& ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT)))
/* Transfer dynamic linking information to the function descriptor. */
if (fdh != NULL)
{
if (fdh->elf.dynindx == -1)
if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
return FALSE;
fdh->elf.ref_regular |= fh->elf.ref_regular;
fdh->elf.ref_dynamic |= fh->elf.ref_dynamic;
fdh->elf.ref_regular_nonweak |= fh->elf.ref_regular_nonweak;
fdh->elf.non_got_ref |= fh->elf.non_got_ref;
if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
{
move_plt_plist (fh, fdh);
fdh->elf.needs_plt = 1;
}
fdh->is_func_descriptor = 1;
fdh->oh = fh;
fh->oh = fdh;
fdh->elf.dynamic |= fh->elf.dynamic;
fdh->elf.needs_plt |= (fh->elf.needs_plt
|| fh->elf.type == STT_FUNC
|| fh->elf.type == STT_GNU_IFUNC);
move_plt_plist (fh, fdh);
if (!fdh->elf.forced_local
&& fh->elf.dynindx != -1)
if (!bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
return FALSE;
}
/* Now that the info is on the function descriptor, clear the
@ -7145,7 +7170,11 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
| STV_HIDDEN);
}
elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
if (htab->need_func_desc_adj)
{
elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
htab->need_func_desc_adj = 0;
}
return TRUE;
}
@ -8092,11 +8121,14 @@ ppc64_elf_edit_opd (struct bfd_link_info *info)
if (h != NULL
&& h->root.root.string[0] == '.')
{
fdh = lookup_fdh ((struct ppc_link_hash_entry *) h, htab);
if (fdh != NULL
&& fdh->elf.root.type != bfd_link_hash_defined
&& fdh->elf.root.type != bfd_link_hash_defweak)
fdh = NULL;
fdh = ((struct ppc_link_hash_entry *) h)->oh;
if (fdh != NULL)
{
fdh = ppc_follow_link (fdh);
if (fdh->elf.root.type != bfd_link_hash_defined
&& fdh->elf.root.type != bfd_link_hash_defweak)
fdh = NULL;
}
}
skip = (sym_sec->owner != ibfd
@ -11080,10 +11112,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
/* If the old-ABI "dot-symbol" is undefined make it weak so
we don't get a link error from RELOC_FOR_GLOBAL_SYMBOL. */
if (fh->elf.root.type == bfd_link_hash_undefined)
if (fh->elf.root.type == bfd_link_hash_undefined
&& (stub_entry->h->elf.root.type == bfd_link_hash_defined
|| stub_entry->h->elf.root.type == bfd_link_hash_defweak))
fh->elf.root.type = bfd_link_hash_undefweak;
/* Stop undo_symbol_twiddle changing it back to undefined. */
fh->was_undefined = 0;
}
/* Now build the stub. */
@ -12412,8 +12444,9 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
use the func descriptor sym instead if it is
defined. */
if (hash->elf.root.root.string[0] == '.'
&& (fdh = lookup_fdh (hash, htab)) != NULL)
&& hash->oh != NULL)
{
fdh = ppc_follow_link (hash->oh);
if (fdh->elf.root.type == bfd_link_hash_defined
|| fdh->elf.root.type == bfd_link_hash_defweak)
{
@ -13242,33 +13275,6 @@ ppc64_elf_build_stubs (struct bfd_link_info *info,
return TRUE;
}
/* This function undoes the changes made by add_symbol_adjust. */
static bfd_boolean
undo_symbol_twiddle (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
{
struct ppc_link_hash_entry *eh;
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
eh = (struct ppc_link_hash_entry *) h;
if (eh->elf.root.type != bfd_link_hash_undefweak || !eh->was_undefined)
return TRUE;
eh->elf.root.type = bfd_link_hash_undefined;
return TRUE;
}
void
ppc64_elf_restore_symbols (struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab = ppc_hash_table (info);
if (htab != NULL)
elf_link_hash_traverse (&htab->elf, undo_symbol_twiddle, info);
}
/* What to do when ld finds relocations against symbols defined in
discarded sections. */

View File

@ -94,5 +94,3 @@ bfd_boolean ppc64_elf_size_stubs
(struct bfd_link_info *);
bfd_boolean ppc64_elf_build_stubs
(struct bfd_link_info *, char **);
void ppc64_elf_restore_symbols
(struct bfd_link_info *info);

View File

@ -1,3 +1,15 @@
2016-12-03 Alan Modra <amodra@gmail.com>
* emultempl/ppc64elf.em (gld${EMULATION_NAME}_finish): Don't call
ppc64_elf_restore_symbols.
* testsuite/ld-powerpc/dotsym1.d: New.
* testsuite/ld-powerpc/dotsym2.d: New.
* testsuite/ld-powerpc/dotsym3.d: New.
* testsuite/ld-powerpc/dotsym4.d: New.
* testsuite/ld-powerpc/dotsymref.s: New.
* testsuite/ld-powerpc/nodotsym.s: New.
* testsuite/ld-powerpc/powerpc.exp: Run new tests.
2016-12-03 Alan Modra <amodra@gmail.com>
* testsuite/ld-elf/indirect1b.c: Give dot-symbol a version too.

View File

@ -592,7 +592,6 @@ gld${EMULATION_NAME}_finish (void)
if (msg != NULL)
free (msg);
ppc64_elf_restore_symbols (&link_info);
finish_default ();
}

View File

@ -0,0 +1,15 @@
#source: nodotsym.s
#source: dotsymref.s
#as: -a64
#ld: -melf64ppc -Ttext=0x10000000 -e foo
#objdump: -d
.*: file format .*
Disassembly of section \.text:
0+10000000 <\.foo>:
.*: (4e 80 00 20|20 00 80 4e) blr
.*: (60 00 00 00|00 00 00 60) nop
.*: (00 00 00 00|00 00 00 10) .*
.*: (10 00 00 00|00 00 00 00) .*

View File

@ -0,0 +1,16 @@
#source: dotsymref.s
#source: nodotsym.s
#as: -a64
#ld: -melf64ppc -Ttext=0x10000000 -e foo
#objdump: -d
.*: file format .*
Disassembly of section \.text:
0+10000000 <\.foo-0x8>:
.*: (00 00 00 00|08 00 00 10) .*
.*: (10 00 00 08|00 00 00 00) .*
0+10000008 <\.foo>:
.*: (4e 80 00 20|20 00 80 4e) blr

View File

@ -0,0 +1,16 @@
#source: nodotsym.s
#source: dotsymref.s
#as: -a64
#ld: -melf64ppc -Ttext=0x1000 -shared
#objdump: -dR
.*: file format .*
Disassembly of section \.text:
0+1000 <\.foo>:
.*: (4e 80 00 20|20 00 80 4e) blr
.*: (60 00 00 00|00 00 00 60) nop
.*: (00 00 00 00|00 10 00 00) .*
.*: R_PPC64_RELATIVE \*ABS\*\+0x1000
.*: (00 00 10 00|00 00 00 00) .*

View File

@ -0,0 +1,17 @@
#source: dotsymref.s
#source: nodotsym.s
#as: -a64
#ld: -melf64ppc -Ttext=0x1000 -shared
#objdump: -dR
.*: file format .*
Disassembly of section \.text:
0+1000 <\.foo-0x8>:
.*: (00 00 00 00|08 10 00 00) .*
.*: R_PPC64_RELATIVE \*ABS\*\+0x1008
.*: (00 00 10 08|00 00 00 00) .*
0+1008 <\.foo>:
.*: (4e 80 00 20|20 00 80 4e) blr

View File

@ -0,0 +1,4 @@
.abiversion 1
.text
.p2align 3
.quad .foo

View File

@ -0,0 +1,11 @@
.section .opd,"aw"
.p2align 3
.global foo
.type foo,@function
foo:
.quad .L.foo,.TOC.@tocbase,0
.text
.L.foo:
blr
.size foo,.-.L.foo

View File

@ -299,6 +299,10 @@ if [ supports_ppc64 ] then {
run_dump_test "tlsld"
run_dump_test "relocsort"
run_dump_test "addpcis"
run_dump_test "dotsym1"
run_dump_test "dotsym2"
run_dump_test "dotsym3"
run_dump_test "dotsym4"
}
run_dump_test "tlsld32"