summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Target.cpp')
-rw-r--r--lld/ELF/Target.cpp44
1 files changed, 34 insertions, 10 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 3751655e1d6..5be77fb185a 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -87,7 +87,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
- uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
+ uint64_t SA, uint64_t ZA = 0,
+ uint8_t *PairedLoc = nullptr) const override;
bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override;
unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
@@ -120,9 +121,11 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
- uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
+ uint64_t SA, uint64_t ZA = 0,
+ 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;
unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
uint64_t P, uint64_t SA,
const SymbolBody &S) const override;
@@ -150,7 +153,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
- uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
+ uint64_t SA, uint64_t ZA = 0,
+ uint8_t *PairedLoc = nullptr) const override;
bool isRelRelative(uint32_t Type) const override;
};
@@ -169,7 +173,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
- uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
+ uint64_t SA, uint64_t ZA = 0,
+ uint8_t *PairedLoc = nullptr) const override;
};
template <class ELFT> class MipsTargetInfo final : public TargetInfo {
@@ -185,7 +190,8 @@ public:
bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
- uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
+ uint64_t SA, uint64_t ZA = 0,
+ uint8_t *PairedLoc = nullptr) const override;
};
} // anonymous namespace
@@ -228,6 +234,10 @@ 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;
+}
+
unsigned TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
const SymbolBody &S) const {
@@ -338,7 +348,7 @@ bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
}
void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
- uint64_t P, uint64_t SA,
+ uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
switch (Type) {
case R_386_32:
@@ -623,10 +633,18 @@ bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
case R_X86_64_PC32:
case R_X86_64_PC64:
case R_X86_64_PLT32:
+ case R_X86_64_SIZE32:
+ case R_X86_64_SIZE64:
return true;
}
}
+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::isTlsOptimized(unsigned Type,
const SymbolBody *S) const {
if (Config->Shared || (S && !S->isTLS()))
@@ -767,7 +785,7 @@ unsigned X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
}
void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
- uint64_t P, uint64_t SA,
+ uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
switch (Type) {
case R_X86_64_32:
@@ -794,6 +812,12 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
case R_X86_64_TLSLD:
write32le(Loc, SA - P);
break;
+ case R_X86_64_SIZE32:
+ write32le(Loc, ZA);
+ break;
+ case R_X86_64_SIZE64:
+ write64le(Loc, ZA);
+ break;
case R_X86_64_TPOFF32: {
uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
checkInt<32>(Val, Type);
@@ -915,7 +939,7 @@ bool PPC64TargetInfo::isRelRelative(uint32_t Type) const {
}
void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
- uint64_t P, uint64_t SA,
+ uint64_t P, uint64_t SA, uint64_t ZA,
uint8_t *PairedLoc) const {
uint64_t TB = getPPC64TocBase();
@@ -1153,7 +1177,7 @@ static uint64_t getAArch64Page(uint64_t Expr) {
void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
- uint8_t *PairedLoc) const {
+ uint64_t ZA, uint8_t *PairedLoc) const {
switch (Type) {
case R_AARCH64_ABS16:
checkIntUInt<16>(SA, Type);
@@ -1266,7 +1290,7 @@ bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type,
template <class ELFT>
void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint64_t SA,
- uint8_t *PairedLoc) const {
+ uint64_t ZA, uint8_t *PairedLoc) const {
const endianness E = ELFT::TargetEndianness;
switch (Type) {
case R_MIPS_32:
OpenPOWER on IntegriCloud