summaryrefslogtreecommitdiff
path: root/lld/ELF/Arch/ARM.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Arch/ARM.cpp')
-rw-r--r--lld/ELF/Arch/ARM.cpp21
1 files changed, 14 insertions, 7 deletions
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 3e0efe540e1b..07a7535c4a23 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.