diff options
-rw-r--r-- | lld/ELF/InputSection.cpp | 9 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/Target.h | 2 |
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; |