ia64: Check UNDEFWEAK_NO_DYNAMIC_RELOC

Don't generate dynamic relocation against weak undefined symbol if it
is resolved to zero.  FIXME: UNDEFWEAK_NO_DYNAMIC_RELOC may need to be
checked in more places.

	PR ld/22269
	* elfnn-ia64.c (elfNN_ia64_check_relocs): Don't allocate
	dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true.
	(allocate_fptr): Don't allocate function pointer if
	UNDEFWEAK_NO_DYNAMIC_RELOC is true.
	(allocate_dynrel_entries): Don't allocate dynamic relocation
	if UNDEFWEAK_NO_DYNAMIC_RELOC is true.
	(set_got_entry): Don't set GOT entry if
	UNDEFWEAK_NO_DYNAMIC_RELOC is true.
	(set_pltoff_entry): Don't set PLTOFF entry if
	UNDEFWEAK_NO_DYNAMIC_RELOC is true.
	(elfNN_ia64_relocate_section): Don't install dynamic relocation
	UNDEFWEAK_NO_DYNAMIC_RELOC is true.
This commit is contained in:
H.J. Lu
2017-10-14 10:53:43 -07:00
parent ad95120309
commit db41f6eb52
2 changed files with 31 additions and 5 deletions

View File

@ -1,3 +1,19 @@
2017-10-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22269
* elfnn-ia64.c (elfNN_ia64_check_relocs): Don't allocate
dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true.
(allocate_fptr): Don't allocate function pointer if
UNDEFWEAK_NO_DYNAMIC_RELOC is true.
(allocate_dynrel_entries): Don't allocate dynamic relocation
if UNDEFWEAK_NO_DYNAMIC_RELOC is true.
(set_got_entry): Don't set GOT entry if
UNDEFWEAK_NO_DYNAMIC_RELOC is true.
(set_pltoff_entry): Don't set PLTOFF entry if
UNDEFWEAK_NO_DYNAMIC_RELOC is true.
(elfNN_ia64_relocate_section): Don't install dynamic relocation
UNDEFWEAK_NO_DYNAMIC_RELOC is true.
2017-10-14 H.J. Lu <hongjiu.lu@intel.com> 2017-10-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22269 PR ld/22269

View File

@ -2190,6 +2190,9 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
else else
h = NULL; h = NULL;
if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
continue;
/* We can only get preliminary data on whether a symbol is /* We can only get preliminary data on whether a symbol is
locally or externally defined, as not all of the input files locally or externally defined, as not all of the input files
have yet been processed. Do something with what we know, as have yet been processed. Do something with what we know, as
@ -2365,6 +2368,9 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
else else
h = NULL; h = NULL;
if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
continue;
/* We can only get preliminary data on whether a symbol is /* We can only get preliminary data on whether a symbol is
locally or externally defined, as not all of the input files locally or externally defined, as not all of the input files
have yet been processed. Do something with what we know, as have yet been processed. Do something with what we know, as
@ -2717,7 +2723,8 @@ allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
if (!bfd_link_executable (x->info) if (!bfd_link_executable (x->info)
&& (!h && (!h
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (x->info, h))
|| (h->root.type != bfd_link_hash_undefweak || (h->root.type != bfd_link_hash_undefweak
&& h->root.type != bfd_link_hash_undefined))) && h->root.type != bfd_link_hash_undefined)))
{ {
@ -2846,8 +2853,8 @@ allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
shared = bfd_link_pic (x->info); shared = bfd_link_pic (x->info);
resolved_zero = (dyn_i->h resolved_zero = (dyn_i->h
&& ELF_ST_VISIBILITY (dyn_i->h->other) && UNDEFWEAK_NO_DYNAMIC_RELOC (x->info,
&& dyn_i->h->root.type == bfd_link_hash_undefweak); dyn_i->h));
/* Take care of the GOT and PLT relocations. */ /* Take care of the GOT and PLT relocations. */
@ -3319,7 +3326,8 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
/* Install a dynamic relocation if needed. */ /* Install a dynamic relocation if needed. */
if (((bfd_link_pic (info) if (((bfd_link_pic (info)
&& (!dyn_i->h && (!dyn_i->h
|| ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
|| dyn_i->h->root.type != bfd_link_hash_undefweak) || dyn_i->h->root.type != bfd_link_hash_undefweak)
&& dyn_r_type != R_IA64_DTPREL32LSB && dyn_r_type != R_IA64_DTPREL32LSB
&& dyn_r_type != R_IA64_DTPREL64LSB) && dyn_r_type != R_IA64_DTPREL64LSB)
@ -3483,7 +3491,8 @@ set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
if (!is_plt if (!is_plt
&& bfd_link_pic (info) && bfd_link_pic (info)
&& (!dyn_i->h && (!dyn_i->h
|| ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
|| dyn_i->h->root.type != bfd_link_hash_undefweak)) || dyn_i->h->root.type != bfd_link_hash_undefweak))
{ {
unsigned int dyn_r_type; unsigned int dyn_r_type;
@ -3944,6 +3953,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
case R_IA64_DIR64LSB: case R_IA64_DIR64LSB:
/* Install a dynamic relocation for this reloc. */ /* Install a dynamic relocation for this reloc. */
if ((dynamic_symbol_p || bfd_link_pic (info)) if ((dynamic_symbol_p || bfd_link_pic (info))
&& !(h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
&& r_symndx != STN_UNDEF && r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC) != 0) && (input_section->flags & SEC_ALLOC) != 0)
{ {