summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/InputSection.cpp9
-rw-r--r--lld/ELF/Target.cpp12
-rw-r--r--lld/ELF/Target.h2
3 files changed, 12 insertions, 11 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index b490793518f..3e949ffc555 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -219,8 +219,13 @@ void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
} else if (!Target->needsCopyRel(Type, *Body) &&
isa<SharedSymbol<ELFT>>(*Body)) {
continue;
- } else if (Target->isTlsDynReloc(Type, *Body) ||
- Target->isSizeDynReloc(Type, *Body)) {
+ } else if (Target->isTlsDynReloc(Type, *Body)) {
+ continue;
+ } else if (Target->isSizeReloc(Type) && canBePreempted(Body, false)) {
+ // A SIZE relocation is supposed to set a symbol size, but if a symbol
+ // can be preempted, the size at runtime may be different than link time.
+ // If that's the case, we leave the field alone rather than filling it
+ // with a possibly incorrect value.
continue;
} else if (Config->EMachine == EM_MIPS) {
if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp)
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index bd302accdcd..ccc59fdc3c4 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -139,7 +139,7 @@ public:
uint8_t *PairedLoc = nullptr) const override;
bool isRelRelative(uint32_t Type) const override;
bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override;
- bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const override;
+ bool isSizeReloc(uint32_t Type) const override;
unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
const SymbolBody &S) const override;
@@ -269,9 +269,7 @@ unsigned TargetInfo::getPltRefReloc(unsigned Type) const { return PCRelReloc; }
bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
-bool TargetInfo::isSizeDynReloc(uint32_t Type, const SymbolBody &S) const {
- return false;
-}
+bool TargetInfo::isSizeReloc(uint32_t Type) const { return false; }
unsigned TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
@@ -722,10 +720,8 @@ bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
}
}
-bool X86_64TargetInfo::isSizeDynReloc(uint32_t Type,
- const SymbolBody &S) const {
- return (Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64) &&
- canBePreempted(&S, false);
+bool X86_64TargetInfo::isSizeReloc(uint32_t Type) const {
+ return Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64;
}
bool X86_64TargetInfo::isTlsOptimized(unsigned Type,
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 52c2697dc60..dcdd5f8f801 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -58,7 +58,7 @@ public:
uint64_t GotEntryAddr, uint64_t PltEntryAddr,
int32_t Index, unsigned RelOff) const = 0;
virtual bool isRelRelative(uint32_t Type) const;
- virtual bool isSizeDynReloc(uint32_t Type, const SymbolBody &S) const;
+ virtual bool isSizeReloc(uint32_t Type) const;
virtual bool relocNeedsDynRelative(unsigned Type) const { return false; }
virtual bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const = 0;
virtual bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const = 0;
OpenPOWER on IntegriCloud