From 0bb2d96afee35ad4b023efc2df2791c56f68cfe6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 19 Feb 2002 12:40:32 +0000 Subject: [PATCH] * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Enable absptr -> pcrel optimization for shared libs. Only create minimal .eh_frame_hdr if absptr FDE encoding in shared library cannot be converted to pcrel. (_bfd_elf_eh_frame_section_offset): Return -2 if making absptr relative. * elf32-i386.c (elf_i386_relocate_section): If _bfd_elf_section_offset returned -2, skip, but make sure the relocation is installed. * elf32-arm.h (elf32_arm_final_link_relocate): Likewise. * elf32-cris.c (cris_elf_relocate_section): Likewise. * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. * elf32-i370.c (i370_elf_relocate_section): Likewise. * elf32-m68k.c (elf_m68k_relocate_section): Likewise. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf32-s390.c (elf_s390_relocate_section): Likewise. * elf32-sh.c (sh_elf_relocate_section): Likewise. * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-s390.c (elf_s390_relocate_section): Likewise. * elf64-sh64.c (sh_elf64_relocate_section): Likewise. * elf64-sparc.c (sparc64_elf_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. * elf64-alpha.c (elf64_alpha_relocate_section): Handle _bfd_elf_section_offset returning -2 the same way as -1. * elfxx-ia64.c (elfNN_ia64_install_dyn_reloc): Likewise. * elf32-mips.c (mips_elf_create_dynamic_relocation): Add FIXME and BFD_ASSERT. * elf64-mips.c (mips_elf64_create_dynamic_relocation): Likewise. --- bfd/ChangeLog | 32 ++++++++++++++++++++++++++++++++ bfd/elf-eh-frame.c | 24 +++++++++++++++--------- bfd/elf32-arm.h | 16 ++++++---------- bfd/elf32-cris.c | 10 ++++------ bfd/elf32-hppa.c | 3 ++- bfd/elf32-i370.c | 11 ++++++----- bfd/elf32-i386.c | 14 +++++--------- bfd/elf32-m68k.c | 10 ++++------ bfd/elf32-mips.c | 3 +++ bfd/elf32-ppc.c | 11 ++++++----- bfd/elf32-s390.c | 9 ++++----- bfd/elf32-sh.c | 10 ++++------ bfd/elf32-sparc.c | 7 +++++-- bfd/elf64-alpha.c | 2 +- bfd/elf64-mips.c | 3 +++ bfd/elf64-ppc.c | 14 +++++--------- bfd/elf64-s390.c | 9 ++++----- bfd/elf64-sh64.c | 10 ++++------ bfd/elf64-sparc.c | 8 ++++++-- bfd/elf64-x86-64.c | 10 ++++------ bfd/elfxx-ia64.c | 2 +- 21 files changed, 124 insertions(+), 94 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bc5c02e2b51..cf986d81625 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,35 @@ +2002-02-19 Jakub Jelinek + + * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Enable + absptr -> pcrel optimization for shared libs. + Only create minimal .eh_frame_hdr if absptr FDE encoding in shared + library cannot be converted to pcrel. + (_bfd_elf_eh_frame_section_offset): Return -2 if making absptr + relative. + * elf32-i386.c (elf_i386_relocate_section): If + _bfd_elf_section_offset returned -2, skip, but make sure the + relocation is installed. + * elf32-arm.h (elf32_arm_final_link_relocate): Likewise. + * elf32-cris.c (cris_elf_relocate_section): Likewise. + * elf32-hppa.c (elf32_hppa_relocate_section): Likewise. + * elf32-i370.c (i370_elf_relocate_section): Likewise. + * elf32-m68k.c (elf_m68k_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-sh.c (sh_elf_relocate_section): Likewise. + * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-s390.c (elf_s390_relocate_section): Likewise. + * elf64-sh64.c (sh_elf64_relocate_section): Likewise. + * elf64-sparc.c (sparc64_elf_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_relocate_section): Handle + _bfd_elf_section_offset returning -2 the same way as -1. + * elfxx-ia64.c (elfNN_ia64_install_dyn_reloc): Likewise. + * elf32-mips.c (mips_elf_create_dynamic_relocation): Add FIXME + and BFD_ASSERT. + * elf64-mips.c (mips_elf64_create_dynamic_relocation): Likewise. + 2002-02-18 Tom Rix * xcofflink.c (bfd_xcoff_link_gernate_rtinit): Add -brtl support. diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index b479c00f323..20cbfb22c83 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -586,16 +586,12 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, } /* For shared libraries, try to get rid of as many RELATIVE relocs - as possible. - FIXME: For this to work, ELF backends need to perform the - relocation if omitting dynamic relocs, not skip it. */ - if (0 - && info->shared + as possible. */ + if (info->shared && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr) cie.make_relative = 1; - if (0 - && info->shared + if (info->shared && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr) cie.make_lsda_relative = 1; @@ -636,6 +632,16 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, } else { + if (info->shared + && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr + && cie.make_relative == 0) + { + /* If shared library uses absolute pointers + which we cannot turn into PC relative, + don't create the binary search table, + since it is affected by runtime relocations. */ + hdr_info->table = false; + } cie_usage_count++; hdr_info->fde_count++; } @@ -856,7 +862,7 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset) if (sec_info->entry[mid].make_relative && ! sec_info->entry[mid].cie && offset == sec_info->entry[mid].offset + 8) - return (bfd_vma) -1; + return (bfd_vma) -2; /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need for run-time relocation against LSDA field. */ @@ -865,7 +871,7 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset) && (offset == (sec_info->entry[mid].offset + 8 + sec_info->entry[mid].lsda_offset))) - return (bfd_vma) -1; + return (bfd_vma) -2; return (offset + sec_info->entry[mid].new_offset - sec_info->entry[mid].offset); diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 8818c649734..a452465ead2 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1148,26 +1148,24 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (r_type == R_ARM_PC24) { BFD_ASSERT (h != NULL && h->dynindx != -1); - if ((input_section->flags & SEC_ALLOC) != 0) - relocate = false; - else + if ((input_section->flags & SEC_ALLOC) == 0) relocate = true; outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_PC24); } @@ -1184,9 +1182,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, else { BFD_ASSERT (h->dynindx != -1); - if ((input_section->flags & SEC_ALLOC) != 0) - relocate = false; - else + if ((input_section->flags & SEC_ALLOC) == 0) relocate = true; outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_ABS32); } diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index c588adcc48b..ef8c95193cc 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1296,20 +1296,20 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); /* h->dynindx may be -1 if the symbol was marked to become local. */ else if (h != NULL @@ -1318,7 +1318,6 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, & ELF_LINK_HASH_DEF_REGULAR) == 0)) { BFD_ASSERT (h->dynindx != -1); - relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_addend = relocation + rel->r_addend; } @@ -1359,7 +1358,6 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (indx > 0); } - relocate = false; outrel.r_info = ELF32_R_INFO (indx, r_type); outrel.r_addend = relocation + rel->r_addend; } diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index ce3a9b85c8a..5a65dcb1d61 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -3976,7 +3976,8 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); - skip = (outrel.r_offset == (bfd_vma) -1); + skip = (outrel.r_offset == (bfd_vma) -1 + || outrel.r_offset == (bfd_vma) -2); outrel.r_offset += (input_section->output_offset + input_section->output_section->vma); diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 5ac43dda756..aa9cd3955a7 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1436,7 +1436,7 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, && r_symndx != 0) { Elf_Internal_Rela outrel; - boolean skip; + int skip; #ifdef DEBUG fprintf (stderr, @@ -1468,13 +1468,14 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sreloc != NULL); } - skip = false; + skip = 0; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1) - skip = true; + if (outrel.r_offset == (bfd_vma) -1 + || outrel.r_offset == (bfd_vma) -2) + skip = (int) outrel.r_offset; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -1549,7 +1550,7 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* This reloc will be computed at runtime, so there's no need to do anything now, unless this is a RELATIVE reloc in an unallocated section. */ - if (skip + if (skip == -1 || (input_section->flags & SEC_ALLOC) != 0 || ELF32_R_TYPE (outrel.r_info) != R_I370_RELATIVE) continue; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index a1a7b5ca5d2..7e6588c24ed 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2006,20 +2006,20 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && (r_type == R_386_PC32 @@ -2027,11 +2027,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, || !info->symbolic || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) - - { - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - } + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); else { /* This symbol is local, or marked to become local. */ diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index ab7ab452c7e..1fb684472f0 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1654,20 +1654,20 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); /* h->dynindx may be -1 if the symbol was marked to become local. */ else if (h != NULL @@ -1676,7 +1676,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, & ELF_LINK_HASH_DEF_REGULAR) == 0)) { BFD_ASSERT (h->dynindx != -1); - relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_addend = relocation + rel->r_addend; } @@ -1717,7 +1716,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (indx > 0); } - relocate = false; outrel.r_info = ELF32_R_INFO (indx, r_type); outrel.r_addend = relocation + rel->r_addend; } diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index c62c5db213d..d52e5d2001e 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -6369,6 +6369,9 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec, _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + /* FIXME: For -2 runtime relocation needs to be skipped, but + properly resolved statically and installed. */ + BFD_ASSERT (outrel.r_offset != (bfd_vma) -2); /* If we've decided to skip this relocation, just output an empty record. Note that R_MIPS_NONE == 0, so that this call to memset diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 4c9ff8297f9..be6cfabb195 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3152,7 +3152,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (info->shared && r_symndx != 0) { Elf_Internal_Rela outrel; - boolean skip; + int skip; #ifdef DEBUG fprintf (stderr, "ppc_elf_relocate_section need to create relocation for %s\n", @@ -3183,13 +3183,14 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sreloc != NULL); } - skip = false; + skip = 0; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); - if (outrel.r_offset == (bfd_vma) -1) - skip = true; + if (outrel.r_offset == (bfd_vma) -1 + || outrel.r_offset == (bfd_vma) -2) + skip = (int) outrel.r_offset; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -3260,7 +3261,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* This reloc will be computed at runtime, so there's no need to do anything now, unless this is a RELATIVE reloc in an unallocated section. */ - if (skip + if (skip != -1 || (input_section->flags & SEC_ALLOC) != 0 || ELF32_R_TYPE (outrel.r_info) != R_PPC_RELATIVE) continue; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 0a913ef81f1..01ce47c3056 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1891,20 +1891,20 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && (r_type == R_390_PC16 @@ -1915,7 +1915,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) { - relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); outrel.r_addend = rel->r_addend; } diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 6c13404fd05..d8d4a6aab4d 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -4419,24 +4419,23 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (r_type == R_SH_REL32) { BFD_ASSERT (h != NULL && h->dynindx != -1); - relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32); outrel.r_addend = bfd_get_32 (input_bfd, contents + rel->r_offset); @@ -4459,7 +4458,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, else { BFD_ASSERT (h->dynindx != -1); - relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32); outrel.r_addend = relocation + bfd_get_32 (input_bfd, diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index f0f97464056..e944f00f6ad 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -1438,7 +1438,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, && (input_section->flags & SEC_ALLOC)) { Elf_Internal_Rela outrel; - boolean skip; + boolean skip, relocate = false; /* When generating a shared object, these relocations are copied into the output file to be resolved at run @@ -1471,6 +1471,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -1571,7 +1573,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, /* This reloc will be computed at runtime, so there's no need to do anything now. */ - continue; + if (! relocate) + continue; } break; diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 53ac1e79175..2c380d6a19b 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -3671,7 +3671,7 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); - if (outrel.r_offset != (bfd_vma) -1) + if ((outrel.r_offset | 1) != (bfd_vma) -1) outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); else diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index f20d15bc07f..084e08a157b 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -3396,6 +3396,9 @@ mips_elf64_create_dynamic_relocation (output_bfd, info, rel, h, sec, outrel[0].r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset); + /* FIXME: For -2 runtime relocation needs to be skipped, but + properly resolved statically and installed. */ + BFD_ASSERT (outrel[0].r_offset != (bfd_vma) -2); /* We begin by assuming that the offset for the dynamic relocation is the same as for the original relocation. We'll adjust this diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 08232a304dd..fe46bd53eae 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4082,22 +4082,21 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; - + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); outrel.r_addend = addend; if (skip) - { - relocate = false; - memset (&outrel, 0, sizeof outrel); - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && !is_opd @@ -4106,10 +4105,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, || !info->symbolic || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - relocate = false; - outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); - } + outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); else { /* This symbol is local, or marked to become local, diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index efdf194c996..f296c3e9131 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1890,21 +1890,21 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, time. */ skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (h != NULL && h->dynindx != -1 && (r_type == R_390_PC16 @@ -1917,7 +1917,6 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) { - relocate = false; outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); outrel.r_addend = rel->r_addend; } diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index ab22187e24d..901bfa5bda6 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1746,6 +1746,7 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, @@ -1753,19 +1754,17 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -1) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); else if (r_type == R_SH_64_PCREL) { BFD_ASSERT (h != NULL && h->dynindx != -1); - relocate = false; outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64_PCREL); outrel.r_addend = rel->r_addend; } @@ -1785,7 +1784,6 @@ sh_elf64_relocate_section (output_bfd, info, input_bfd, input_section, else { BFD_ASSERT (h->dynindx != -1); - relocate = false; outrel.r_info = ELF64_R_INFO (h->dynindx, R_SH_64); outrel.r_addend = relocation + rel->r_addend; } diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index 5cae63aed9c..0f81fa26bf7 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -2161,7 +2161,7 @@ do_dynreloc: case R_SPARC_UA16: { Elf_Internal_Rela outrel; - boolean skip; + boolean skip, relocate; if (sreloc == NULL) { @@ -2184,12 +2184,15 @@ do_dynreloc: } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -2301,7 +2304,8 @@ do_dynreloc: /* This reloc will be computed at runtime, so there's no need to do anything now. */ - continue; + if (! relocate) + continue; } break; } diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 4bbbb0871ea..cdd36d1623f 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1466,21 +1466,21 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, } skip = false; + relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rela->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; + else if (outrel.r_offset == (bfd_vma) -1) + skip = true, relocate = true; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); if (skip) - { - memset (&outrel, 0, sizeof outrel); - relocate = false; - } + memset (&outrel, 0, sizeof outrel); /* h->dynindx may be -1 if this symbol was marked to become local. */ else if (h != NULL @@ -1489,7 +1489,6 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, & ELF_LINK_HASH_DEF_REGULAR) == 0)) { BFD_ASSERT (h->dynindx != -1); - relocate = false; outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); outrel.r_addend = relocation + rela->r_addend; } @@ -1530,7 +1529,6 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sindx > 0); } - relocate = false; outrel.r_info = ELF64_R_INFO (sindx, r_type); outrel.r_addend = relocation + rela->r_addend; } diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index 7c4e1394ec3..e458477010e 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -3107,7 +3107,7 @@ elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type, outrel.r_info = ELFNN_R_INFO (dynindx, type); outrel.r_addend = addend; outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset); - if (outrel.r_offset == (bfd_vma) -1) + if ((outrel.r_offset | 1) == (bfd_vma) -1) { /* Run for the hills. We shouldn't be outputting a relocation for this. So do what everyone else does and output a no-op. */ -- 2.30.2