llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lld-elf Author: None (llvmbot) <details> <summary>Changes</summary> Backport a1c6467bd Requested by: @<!-- -->ostannard --- Full diff: https://github.com/llvm/llvm-project/pull/102292.diff 4 Files Affected: - (modified) lld/ELF/Arch/ARM.cpp (+14-7) - (modified) lld/ELF/Config.h (+2-1) - (modified) lld/ELF/InputFiles.cpp (+2-4) - (added) lld/test/ELF/arm-mixed-plts.s (+44) ``````````diff diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 3e0efe540e1bf..07a7535c4a231 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -228,10 +228,16 @@ static void writePltHeaderLong(uint8_t *buf) { write32(buf + 16, gotPlt - l1 - 8); } +// True if we should use Thumb PLTs, which currently require Thumb2, and are +// only used if the target does not have the ARM ISA. +static bool useThumbPLTs() { + return config->armHasThumb2ISA && !config->armHasArmISA; +} + // The default PLT header requires the .got.plt to be within 128 Mb of the // .plt in the positive direction. void ARM::writePltHeader(uint8_t *buf) const { - if (config->armThumbPLTs) { + if (useThumbPLTs()) { // The instruction sequence for thumb: // // 0: b500 push {lr} @@ -289,7 +295,7 @@ void ARM::writePltHeader(uint8_t *buf) const { } void ARM::addPltHeaderSymbols(InputSection &isec) const { - if (config->armThumbPLTs) { + if (useThumbPLTs()) { addSyntheticLocal("$t", STT_NOTYPE, 0, 0, isec); addSyntheticLocal("$d", STT_NOTYPE, 12, 0, isec); } else { @@ -315,7 +321,7 @@ static void writePltLong(uint8_t *buf, uint64_t gotPltEntryAddr, void ARM::writePlt(uint8_t *buf, const Symbol &sym, uint64_t pltEntryAddr) const { - if (!config->armThumbPLTs) { + if (!useThumbPLTs()) { uint64_t offset = sym.getGotPltVA() - pltEntryAddr - 8; // The PLT entry is similar to the example given in Appendix A of ELF for @@ -367,7 +373,7 @@ void ARM::writePlt(uint8_t *buf, const Symbol &sym, } void ARM::addPltSymbols(InputSection &isec, uint64_t off) const { - if (config->armThumbPLTs) { + if (useThumbPLTs()) { addSyntheticLocal("$t", STT_NOTYPE, off, 0, isec); } else { addSyntheticLocal("$a", STT_NOTYPE, off, 0, isec); @@ -393,7 +399,7 @@ bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file, case R_ARM_JUMP24: // Source is ARM, all PLT entries are ARM so no interworking required. // Otherwise we need to interwork if STT_FUNC Symbol has bit 0 set (Thumb). - assert(!config->armThumbPLTs && + assert(!useThumbPLTs() && "If the source is ARM, we should not need Thumb PLTs"); if (s.isFunc() && expr == R_PC && (s.getVA() & 1)) return true; @@ -407,7 +413,8 @@ bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file, case R_ARM_THM_JUMP24: // Source is Thumb, when all PLT entries are ARM interworking is required. // Otherwise we need to interwork if STT_FUNC Symbol has bit 0 clear (ARM). - if ((expr == R_PLT_PC && !config->armThumbPLTs) || (s.isFunc() && (s.getVA() & 1) == 0)) + if ((expr == R_PLT_PC && !useThumbPLTs()) || + (s.isFunc() && (s.getVA() & 1) == 0)) return true; [[fallthrough]]; case R_ARM_THM_CALL: { @@ -675,7 +682,7 @@ void ARM::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { // PLT entries are always ARM state so we know we need to interwork. assert(rel.sym); // R_ARM_THM_CALL is always reached via relocate(). bool bit0Thumb = val & 1; - bool useThumb = bit0Thumb || config->armThumbPLTs; + bool useThumb = bit0Thumb || useThumbPLTs(); bool isBlx = (read16(loc + 2) & 0x1000) == 0; // lld 10.0 and before always used bit0Thumb when deciding to write a BLX // even when type not STT_FUNC. diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 0173be396163e..28726d48e4284 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -217,7 +217,8 @@ struct Config { bool allowMultipleDefinition; bool fatLTOObjects; bool androidPackDynRelocs = false; - bool armThumbPLTs = false; + bool armHasArmISA = false; + bool armHasThumb2ISA = false; bool armHasBlx = false; bool armHasMovtMovw = false; bool armJ1J2BranchEncoding = false; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index f1c0eb292361b..48f5a9609ecfb 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -203,10 +203,8 @@ static void updateSupportedARMFeatures(const ARMAttributeParser &attributes) { attributes.getAttributeValue(ARMBuildAttrs::ARM_ISA_use); std::optional<unsigned> thumb = attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use); - bool noArmISA = !armISA || *armISA == ARMBuildAttrs::Not_Allowed; - bool hasThumb2 = thumb && *thumb >= ARMBuildAttrs::AllowThumb32; - if (noArmISA && hasThumb2) - config->armThumbPLTs = true; + config->armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed; + config->armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32; } InputFile::InputFile(Kind k, MemoryBufferRef m) diff --git a/lld/test/ELF/arm-mixed-plts.s b/lld/test/ELF/arm-mixed-plts.s new file mode 100644 index 0000000000000..801de70f4f101 --- /dev/null +++ b/lld/test/ELF/arm-mixed-plts.s @@ -0,0 +1,44 @@ +# REQUIRES: arm + +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %t/a.s -o %t1.o +# RUN: llvm-mc -filetype=obj -arm-add-build-attributes -triple=armv7a-none-linux-gnueabi %t/b.s -o %t2.o +# RUN: ld.lld -shared %t1.o %t2.o -o %t.so +# RUN: llvm-objdump -d %t.so | FileCheck %s + +## Check that, when the input is a mixture of objects which can and cannot use +## the ARM ISA, we use the default ARM PLT sequences. + +# CHECK: <.plt>: +# CHECK-NEXT: e52de004 str lr, [sp, #-0x4]! +# CHECK-NEXT: e28fe600 add lr, pc, #0, #12 +# CHECK-NEXT: e28eea20 add lr, lr, #32, #20 +# CHECK-NEXT: e5bef084 ldr pc, [lr, #0x84]! +# CHECK-NEXT: d4 d4 d4 d4 .word 0xd4d4d4d4 +# CHECK-NEXT: d4 d4 d4 d4 .word 0xd4d4d4d4 +# CHECK-NEXT: d4 d4 d4 d4 .word 0xd4d4d4d4 +# CHECK-NEXT: d4 d4 d4 d4 .word 0xd4d4d4d4 +# CHECK-NEXT: e28fc600 add r12, pc, #0, #12 +# CHECK-NEXT: e28cca20 add r12, r12, #32, #20 +# CHECK-NEXT: e5bcf06c ldr pc, [r12, #0x6c]! +# CHECK-NEXT: d4 d4 d4 d4 .word 0xd4d4d4d4 + +#--- a.s + .globl foo + .type foo, %function + .globl bar + .type bar, %function + + .thumb +foo: + bl bar + bx lr + +#--- b.s + .eabi_attribute Tag_ARM_ISA_use, 0 + + .arm + .globl bar + .type bar, %function +bar: + bx lr `````````` </details> https://github.com/llvm/llvm-project/pull/102292 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits