aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/Arch/X86.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Arch/X86.cpp')
-rw-r--r--lld/ELF/Arch/X86.cpp55
1 files changed, 29 insertions, 26 deletions
diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index b4daedc0f5dc..8c8824d53cce 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -16,9 +16,8 @@
using namespace llvm;
using namespace llvm::support::endian;
using namespace llvm::ELF;
-
-namespace lld {
-namespace elf {
+using namespace lld;
+using namespace lld::elf;
namespace {
class X86 : public TargetInfo {
@@ -35,14 +34,19 @@ public:
void writePltHeader(uint8_t *buf) const override;
void writePlt(uint8_t *buf, const Symbol &sym,
uint64_t pltEntryAddr) const override;
- void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relocate(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const override;
RelExpr adjustRelaxExpr(RelType type, const uint8_t *data,
RelExpr expr) const override;
- void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const override;
- void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
- void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const override;
- void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const override;
+ void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const override;
+ void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const override;
+ void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const override;
+ void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const override;
};
} // namespace
@@ -262,21 +266,21 @@ int64_t X86::getImplicitAddend(const uint8_t *buf, RelType type) const {
}
}
-void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
- switch (type) {
+void X86::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
+ switch (rel.type) {
case R_386_8:
// R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
// being used for some 16-bit programs such as boot loaders, so
// we want to support them.
- checkIntUInt(loc, val, 8, type);
+ checkIntUInt(loc, val, 8, rel);
*loc = val;
break;
case R_386_PC8:
- checkInt(loc, val, 8, type);
+ checkInt(loc, val, 8, rel);
*loc = val;
break;
case R_386_16:
- checkIntUInt(loc, val, 16, type);
+ checkIntUInt(loc, val, 16, rel);
write16le(loc, val);
break;
case R_386_PC16:
@@ -290,7 +294,7 @@ void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
// current location subtracted from it.
// We just check that Val fits in 17 bits. This misses some cases, but
// should have no false positives.
- checkInt(loc, val, 17, type);
+ checkInt(loc, val, 17, rel);
write16le(loc, val);
break;
case R_386_32:
@@ -312,7 +316,7 @@ void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
case R_386_TLS_LE_32:
case R_386_TLS_TPOFF:
case R_386_TLS_TPOFF32:
- checkInt(loc, val, 32, type);
+ checkInt(loc, val, 32, rel);
write32le(loc, val);
break;
default:
@@ -320,7 +324,7 @@ void X86::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
}
}
-void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsGdToLe(uint8_t *loc, const Relocation &, uint64_t val) const {
// Convert
// leal x@tlsgd(, %ebx, 1),
// call __tls_get_addr@plt
@@ -335,7 +339,7 @@ void X86::relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const {
write32le(loc + 5, val);
}
-void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsGdToIe(uint8_t *loc, const Relocation &, uint64_t val) const {
// Convert
// leal x@tlsgd(, %ebx, 1),
// call __tls_get_addr@plt
@@ -352,14 +356,15 @@ void X86::relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const {
// In some conditions, relocations can be optimized to avoid using GOT.
// This function does that for Initial Exec to Local Exec case.
-void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
+void X86::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const {
// Ulrich's document section 6.2 says that @gotntpoff can
// be used with MOVL or ADDL instructions.
// @indntpoff is similar to @gotntpoff, but for use in
// position dependent code.
uint8_t reg = (loc[-1] >> 3) & 7;
- if (type == R_386_TLS_IE) {
+ if (rel.type == R_386_TLS_IE) {
if (loc[-1] == 0xa1) {
// "movl foo@indntpoff,%eax" -> "movl $foo,%eax"
// This case is different from the generic case below because
@@ -375,7 +380,7 @@ void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
loc[-1] = 0xc0 | reg;
}
} else {
- assert(type == R_386_TLS_GOTIE);
+ assert(rel.type == R_386_TLS_GOTIE);
if (loc[-2] == 0x8b) {
// "movl foo@gottpoff(%rip),%reg" -> "movl $foo,%reg"
loc[-2] = 0xc7;
@@ -389,8 +394,9 @@ void X86::relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const {
write32le(loc, val);
}
-void X86::relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const {
- if (type == R_386_TLS_LDO_32) {
+void X86::relaxTlsLdToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const {
+ if (rel.type == R_386_TLS_LDO_32) {
write32le(loc, val);
return;
}
@@ -608,7 +614,7 @@ void RetpolineNoPic::writePlt(uint8_t *buf, const Symbol &sym,
write32le(buf + 22, -off - 26);
}
-TargetInfo *getX86TargetInfo() {
+TargetInfo *elf::getX86TargetInfo() {
if (config->zRetpolineplt) {
if (config->isPic) {
static RetpolinePic t;
@@ -626,6 +632,3 @@ TargetInfo *getX86TargetInfo() {
static X86 t;
return &t;
}
-
-} // namespace elf
-} // namespace lld