From daf1c414a48baf090f005ce4b319b6881d5d6872 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 6 Oct 2017 00:21:48 -0700 Subject: [PATCH] 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. --- bfd/ChangeLog | 12 +++++++++++ bfd/elf32-i386.c | 44 ++++----------------------------------- bfd/elf64-x86-64.c | 52 +++++++--------------------------------------- bfd/elfxx-x86.h | 39 ++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 85 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9f267a2c967..612bf859571 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2017-10-06 H.J. Lu + + * 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 * elfxx-x86.h (TLS_TRANSITION_IE_TO_LE_P): New. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index c4af6b2e02b..4a3c6903481 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -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; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 1bad4d2dff6..df91ab80a4e 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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)) diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 0525c9c0a2e..88202b4af72 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -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) \ -- 2.30.2