x86: Add NEED_DYNAMIC_RELOCATION_P

Add NEED_DYNAMIC_RELOCATION_P which returns TRUE if dynamic relocation
is needed.

	* elf32-i386.c (X86_PCREL_TYPE_P): New.
	(elf_i386_check_relocs): Use NEED_DYNAMIC_RELOCATION_P.
	* elf64-x86-64.c (IS_X86_64_PCREL_TYPE): Renamed to ...
	(X86_PCREL_TYPE_P): This.
	(elf_x86_64_check_relocs): Use NEED_DYNAMIC_RELOCATION_P.
	Replace IS_X86_64_PCREL_TYPE with X86_PCREL_TYPE_P.
	(elf_x86_64_relocate_section): Replace IS_X86_64_PCREL_TYPE with
	X86_PCREL_TYPE_P.
	* elfxx-x86.h (NEED_DYNAMIC_RELOCATION_P): New.
This commit is contained in:
H.J. Lu 2017-10-06 00:21:48 -07:00
parent 51537393bd
commit daf1c414a4
4 changed files with 62 additions and 85 deletions

View file

@ -1,3 +1,15 @@
2017-10-06 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (X86_PCREL_TYPE_P): New.
(elf_i386_check_relocs): Use NEED_DYNAMIC_RELOCATION_P.
* elf64-x86-64.c (IS_X86_64_PCREL_TYPE): Renamed to ...
(X86_PCREL_TYPE_P): This.
(elf_x86_64_check_relocs): Use NEED_DYNAMIC_RELOCATION_P.
Replace IS_X86_64_PCREL_TYPE with X86_PCREL_TYPE_P.
(elf_x86_64_relocate_section): Replace IS_X86_64_PCREL_TYPE with
X86_PCREL_TYPE_P.
* elfxx-x86.h (NEED_DYNAMIC_RELOCATION_P): New.
2017-10-06 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-x86.h (TLS_TRANSITION_IE_TO_LE_P): New.

View file

@ -182,6 +182,8 @@ static reloc_howto_type elf_howto_table[]=
};
#define X86_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32)
#ifdef DEBUG_GEN_RELOC
#define TRACE(str) \
fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
@ -1813,46 +1815,8 @@ do_relocation:
size_reloc = FALSE;
do_size:
/* If we are creating a shared library, and this is a reloc
against a global symbol, or a non PC relative reloc
against a local symbol, then we need to copy the reloc
into the shared library. However, if we are linking with
-Bsymbolic, we do not need to copy a reloc against a
global symbol which is defined in an object we are
including in the link (i.e., DEF_REGULAR is set). At
this point we have not seen all the input files, so it is
possible that DEF_REGULAR is not set now but will be set
later (it is never cleared). In case of a weak definition,
DEF_REGULAR may be cleared later by a strong definition in
a shared library. We account for that possibility below by
storing information in the relocs_copied field of the hash
table entry. A similar situation occurs when creating
shared libraries and symbol visibility changes render the
symbol local.
If on the other hand, we are creating an executable, we
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol.
Generate dynamic pointer relocation against STT_GNU_IFUNC
symbol in the non-code section. */
if ((bfd_link_pic (info)
&& (r_type != R_386_PC32
|| (h != NULL
&& (! (bfd_link_pie (info)
|| SYMBOLIC_BIND (info, h))
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (h != NULL
&& h->type == STT_GNU_IFUNC
&& r_type == R_386_32
&& (sec->flags & SEC_CODE) == 0)
|| (ELIMINATE_COPY_RELOCS
&& !bfd_link_pic (info)
&& h != NULL
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular)))
if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type,
R_386_32))
{
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **head;

View file

@ -199,7 +199,7 @@ static reloc_howto_type x86_64_elf_howto_table[] =
/* Set if a relocation is converted from a GOTPCREL relocation. */
#define R_X86_64_converted_reloc_bit (1 << 7)
#define IS_X86_64_PCREL_TYPE(TYPE) \
#define X86_PCREL_TYPE_P(TYPE) \
( ((TYPE) == R_X86_64_PC8) \
|| ((TYPE) == R_X86_64_PC16) \
|| ((TYPE) == R_X86_64_PC32) \
@ -2180,46 +2180,8 @@ pointer:
size_reloc = FALSE;
do_size:
/* If we are creating a shared library, and this is a reloc
against a global symbol, or a non PC relative reloc
against a local symbol, then we need to copy the reloc
into the shared library. However, if we are linking with
-Bsymbolic, we do not need to copy a reloc against a
global symbol which is defined in an object we are
including in the link (i.e., DEF_REGULAR is set). At
this point we have not seen all the input files, so it is
possible that DEF_REGULAR is not set now but will be set
later (it is never cleared). In case of a weak definition,
DEF_REGULAR may be cleared later by a strong definition in
a shared library. We account for that possibility below by
storing information in the relocs_copied field of the hash
table entry. A similar situation occurs when creating
shared libraries and symbol visibility changes render the
symbol local.
If on the other hand, we are creating an executable, we
may need to keep relocations for symbols satisfied by a
dynamic library if we manage to avoid copy relocs for the
symbol.
Generate dynamic pointer relocation against STT_GNU_IFUNC
symbol in the non-code section. */
if ((bfd_link_pic (info)
&& (! IS_X86_64_PCREL_TYPE (r_type)
|| (h != NULL
&& (! (bfd_link_pie (info)
|| SYMBOLIC_BIND (info, h))
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (h != NULL
&& h->type == STT_GNU_IFUNC
&& r_type == htab->pointer_r_type
&& (sec->flags & SEC_CODE) == 0)
|| (ELIMINATE_COPY_RELOCS
&& !bfd_link_pic (info)
&& h != NULL
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular)))
if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type,
htab->pointer_r_type))
{
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **head;
@ -2282,7 +2244,7 @@ do_size:
p->count += 1;
/* Count size relocation as PC-relative relocation. */
if (IS_X86_64_PCREL_TYPE (r_type) || size_reloc)
if (X86_PCREL_TYPE_P (r_type) || size_reloc)
p->pc_count += 1;
}
break;
@ -3150,14 +3112,14 @@ direct:
&& (h->needs_copy
|| eh->needs_copy
|| h->root.type == bfd_link_hash_undefined)
&& (IS_X86_64_PCREL_TYPE (r_type)
&& (X86_PCREL_TYPE_P (r_type)
|| r_type == R_X86_64_SIZE32
|| r_type == R_X86_64_SIZE64))
&& (h == NULL
|| ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
&& !resolved_to_zero)
|| h->root.type != bfd_link_hash_undefweak))
&& ((! IS_X86_64_PCREL_TYPE (r_type)
&& ((! X86_PCREL_TYPE_P (r_type)
&& r_type != R_X86_64_SIZE32
&& r_type != R_X86_64_SIZE64)
|| ! SYMBOL_CALLS_LOCAL (info, h)))
@ -3202,7 +3164,7 @@ direct:
become local. */
else if (h != NULL
&& h->dynindx != -1
&& (IS_X86_64_PCREL_TYPE (r_type)
&& (X86_PCREL_TYPE_P (r_type)
|| !(bfd_link_executable (info)
|| SYMBOLIC_BIND (info, h))
|| ! h->def_regular))

View file

@ -74,6 +74,45 @@
&& ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
&& ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
/* TRUE if dynamic relocation is needed. If we are creating a shared
library, and this is a reloc against a global symbol, or a non PC
relative reloc against a local symbol, then we need to copy the reloc
into the shared library. However, if we are linking with -Bsymbolic,
we do not need to copy a reloc against a global symbol which is
defined in an object we are including in the link (i.e., DEF_REGULAR
is set). At this point we have not seen all the input files, so it
is possible that DEF_REGULAR is not set now but will be set later (it
is never cleared). In case of a weak definition, DEF_REGULAR may be
cleared later by a strong definition in a shared library. We account
for that possibility below by storing information in the relocs_copied
field of the hash table entry. A similar situation occurs when
creating shared libraries and symbol visibility changes render the
symbol local.
If on the other hand, we are creating an executable, we may need to
keep relocations for symbols satisfied by a dynamic library if we
manage to avoid copy relocs for the symbol.
We also need to generate dynamic pointer relocation against
STT_GNU_IFUNC symbol in the non-code section. */
#define NEED_DYNAMIC_RELOCATION_P(INFO, H, SEC, R_TYPE, POINTER_TYPE) \
((bfd_link_pic (INFO) \
&& (! X86_PCREL_TYPE_P (R_TYPE) \
|| ((H) != NULL \
&& (! (bfd_link_pie (INFO) \
|| SYMBOLIC_BIND ((INFO), (H))) \
|| (H)->root.type == bfd_link_hash_defweak \
|| !(H)->def_regular)))) \
|| ((H) != NULL \
&& (H)->type == STT_GNU_IFUNC \
&& (R_TYPE) == POINTER_TYPE \
&& ((SEC)->flags & SEC_CODE) == 0) \
|| (ELIMINATE_COPY_RELOCS \
&& !bfd_link_pic (INFO) \
&& (H) != NULL \
&& ((H)->root.type == bfd_link_hash_defweak \
|| !(H)->def_regular)))
/* TRUE if TLS IE->LE transition is OK. */
#define TLS_TRANSITION_IE_TO_LE_P(INFO, H, TLS_TYPE) \
(bfd_link_executable (INFO) \