From aebcc8ffd201adbee973b414818b01876dabe1a0 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 6 Oct 2017 00:40:56 -0700 Subject: [PATCH] x86: Add GENERATE_DYNAMIC_RELOCATION_P Add GENERATE_DYNAMIC_RELOCATION_P which returns TRUE if dynamic relocation should be generated. * elf32-i386.c (X86_SIZE_TYPE_P): New. (elf_i386_relocate_section): Use GENERATE_DYNAMIC_RELOCATION_P. * elf64-x86-64.c (X86_SIZE_TYPE_P): New. (elf_x86_64_relocate_section): Use GENERATE_DYNAMIC_RELOCATION_P. * elfxx-x86.h (GENERATE_DYNAMIC_RELOCATION_P): New. --- bfd/ChangeLog | 8 ++++++++ bfd/elf32-i386.c | 28 +++++--------------------- bfd/elf64-x86-64.c | 50 +++++++++++++++------------------------------- bfd/elfxx-x86.h | 30 ++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index feff37e0784..0f066026d41 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2017-10-06 H.J. Lu + + * elf32-i386.c (X86_SIZE_TYPE_P): New. + (elf_i386_relocate_section): Use GENERATE_DYNAMIC_RELOCATION_P. + * elf64-x86-64.c (X86_SIZE_TYPE_P): New. + (elf_x86_64_relocate_section): Use GENERATE_DYNAMIC_RELOCATION_P. + * elfxx-x86.h (GENERATE_DYNAMIC_RELOCATION_P): New. + 2017-10-06 H.J. Lu * elfxx-x86.h (POINTER_LOCAL_IFUNC_P): New. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index b6c478d901d..0c63d267448 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -184,6 +184,8 @@ static reloc_howto_type elf_howto_table[]= #define X86_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32) +#define X86_SIZE_TYPE_P(TYPE) ((TYPE) == R_386_SIZE32) + #ifdef DEBUG_GEN_RELOC #define TRACE(str) \ fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) @@ -2749,29 +2751,9 @@ disallow_got32: || is_vxworks_tls) break; - /* Copy dynamic function pointer relocations. Don't generate - dynamic relocations against resolved undefined weak symbols - in PIE, except for R_386_PC32. */ - if ((bfd_link_pic (info) - && (h == NULL - || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - && (!resolved_to_zero - || r_type == R_386_PC32)) - || h->root.type != bfd_link_hash_undefweak)) - && ((r_type != R_386_PC32 && r_type != R_386_SIZE32) - || !SYMBOL_CALLS_LOCAL (info, h))) - || (ELIMINATE_COPY_RELOCS - && !bfd_link_pic (info) - && h != NULL - && h->dynindx != -1 - && (!h->non_got_ref - || eh->func_pointer_refcount > 0 - || (h->root.type == bfd_link_hash_undefweak - && !resolved_to_zero)) - && ((h->def_dynamic && !h->def_regular) - /* Undefined weak symbol is bound locally when - PIC is false. */ - || h->root.type == bfd_link_hash_undefweak))) + if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, + FALSE, resolved_to_zero, + (r_type == R_386_PC32))) { Elf_Internal_Rela outrel; bfd_boolean skip, relocate; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index f5ba5a6cc9d..b27d4c5761f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -206,6 +206,9 @@ static reloc_howto_type x86_64_elf_howto_table[] = || ((TYPE) == R_X86_64_PC32_BND) \ || ((TYPE) == R_X86_64_PC64)) +#define X86_SIZE_TYPE_P(TYPE) \ + ((TYPE) == R_X86_64_SIZE32 || (TYPE) == R_X86_64_SIZE64) + /* Map BFD relocs to the x86_64 elf relocs. */ struct elf_reloc_map { @@ -2393,6 +2396,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, bfd_boolean resolved_to_zero; bfd_boolean relative_reloc; bfd_boolean converted_reloc; + bfd_boolean need_copy_reloc_in_pie; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == (int) R_X86_64_GNU_VTINHERIT @@ -3085,40 +3089,18 @@ direct: if ((input_section->flags & SEC_ALLOC) == 0) break; - /* Don't copy a pc-relative relocation into the output file - if the symbol needs copy reloc or the symbol is undefined - when building executable. Copy dynamic function pointer - relocations. Don't generate dynamic relocations against - resolved undefined weak symbols in PIE. */ - if ((bfd_link_pic (info) - && !(bfd_link_pie (info) - && h != NULL - && (h->needs_copy - || eh->needs_copy - || h->root.type == bfd_link_hash_undefined) - && (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)) - && ((! X86_PCREL_TYPE_P (r_type) - && r_type != R_X86_64_SIZE32 - && r_type != R_X86_64_SIZE64) - || ! SYMBOL_CALLS_LOCAL (info, h))) - || (ELIMINATE_COPY_RELOCS - && !bfd_link_pic (info) - && h != NULL - && h->dynindx != -1 - && (!h->non_got_ref - || eh->func_pointer_refcount > 0 - || (h->root.type == bfd_link_hash_undefweak - && !resolved_to_zero)) - && ((h->def_dynamic && !h->def_regular) - /* Undefined weak symbol is bound locally when - PIC is false. */ - || h->root.type == bfd_link_hash_undefined))) + need_copy_reloc_in_pie = (bfd_link_pie (info) + && h != NULL + && (h->needs_copy + || eh->needs_copy + || (h->root.type + == bfd_link_hash_undefined)) + && (X86_PCREL_TYPE_P (r_type) + || X86_SIZE_TYPE_P (r_type))); + + if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, + need_copy_reloc_in_pie, + resolved_to_zero, FALSE)) { Elf_Internal_Rela outrel; bfd_boolean skip, relocate; diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 3be85d085f2..cef2eba30e3 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -113,6 +113,36 @@ && ((H)->root.type == bfd_link_hash_defweak \ || !(H)->def_regular))) +/* TRUE if dynamic relocation should be generated. Don't copy a + pc-relative relocation into the output file if the symbol needs + copy reloc or the symbol is undefined when building executable. + Copy dynamic function pointer relocations. Don't generate dynamic + relocations against resolved undefined weak symbols in PIE, except + when PC32_RELOC is TRUE. Undefined weak symbol is bound locally + when PIC is false. */ +#define GENERATE_DYNAMIC_RELOCATION_P(INFO, EH, R_TYPE, \ + NEED_COPY_RELOC_IN_PIE, \ + RESOLVED_TO_ZERO, PC32_RELOC) \ + ((bfd_link_pic (INFO) \ + && !(NEED_COPY_RELOC_IN_PIE) \ + && ((EH) == NULL \ + || ((ELF_ST_VISIBILITY ((EH)->elf.other) == STV_DEFAULT \ + && (!(RESOLVED_TO_ZERO) || PC32_RELOC)) \ + || (EH)->elf.root.type != bfd_link_hash_undefweak)) \ + && ((!X86_PCREL_TYPE_P (R_TYPE) \ + && !X86_SIZE_TYPE_P (R_TYPE)) \ + || ! SYMBOL_CALLS_LOCAL ((INFO), &(EH)->elf))) \ + || (ELIMINATE_COPY_RELOCS \ + && !bfd_link_pic (INFO) \ + && (EH) != NULL \ + && (EH)->elf.dynindx != -1 \ + && (!(EH)->elf.non_got_ref \ + || (EH)->func_pointer_refcount > 0 \ + || ((EH)->elf.root.type == bfd_link_hash_undefweak \ + && !(RESOLVED_TO_ZERO))) \ + && (((EH)->elf.def_dynamic && !(EH)->elf.def_regular) \ + || (EH)->elf.root.type == bfd_link_hash_undefined))) + /* TRUE if this is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol was forced to be local because of a version file. */ -- 2.30.2