aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/Arch/RISCV.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Arch/RISCV.cpp')
-rw-r--r--lld/ELF/Arch/RISCV.cpp51
1 files changed, 27 insertions, 24 deletions
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index e7c0e36e0327..42db8e08162d 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "InputFiles.h"
+#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
@@ -27,8 +28,8 @@ public:
void writeGotHeader(uint8_t *buf) const override;
void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
void writePltHeader(uint8_t *buf) const override;
- void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
- int32_t index, unsigned relOff) const override;
+ void writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const override;
RelType getDynRel(RelType type) const override;
RelExpr getRelExpr(RelType type, const Symbol &s,
const uint8_t *loc) const override;
@@ -95,8 +96,9 @@ RISCV::RISCV() {
// .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map
gotPltHeaderEntriesNum = 2;
- pltEntrySize = 16;
pltHeaderSize = 32;
+ pltEntrySize = 16;
+ ipltEntrySize = 16;
}
static uint32_t getEFlags(InputFile *f) {
@@ -106,7 +108,10 @@ static uint32_t getEFlags(InputFile *f) {
}
uint32_t RISCV::calcEFlags() const {
- assert(!objectFiles.empty());
+ // If there are only binary input files (from -b binary), use a
+ // value of 0 for the ELF header flags.
+ if (objectFiles.empty())
+ return 0;
uint32_t target = getEFlags(objectFiles.front());
@@ -162,14 +167,13 @@ void RISCV::writePltHeader(uint8_t *buf) const {
write32le(buf + 28, itype(JALR, 0, X_T3, 0));
}
-void RISCV::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
- uint64_t pltEntryAddr, int32_t index,
- unsigned relOff) const {
+void RISCV::writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const {
// 1: auipc t3, %pcrel_hi(f@.got.plt)
// l[wd] t3, %pcrel_lo(1b)(t3)
// jalr t1, t3
// nop
- uint32_t offset = gotPltEntryAddr - pltEntryAddr;
+ uint32_t offset = sym.getGotPltVA() - pltEntryAddr;
write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset)));
write32le(buf + 4, itype(config->is64 ? LD : LW, X_T3, X_T3, lo12(offset)));
write32le(buf + 8, itype(JALR, X_T1, X_T3, 0));
@@ -184,6 +188,15 @@ RelType RISCV::getDynRel(RelType type) const {
RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
const uint8_t *loc) const {
switch (type) {
+ case R_RISCV_NONE:
+ return R_NONE;
+ case R_RISCV_32:
+ case R_RISCV_64:
+ case R_RISCV_HI20:
+ case R_RISCV_LO12_I:
+ case R_RISCV_LO12_S:
+ case R_RISCV_RVC_LUI:
+ return R_ABS;
case R_RISCV_ADD8:
case R_RISCV_ADD16:
case R_RISCV_ADD32:
@@ -225,9 +238,11 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
case R_RISCV_RELAX:
case R_RISCV_ALIGN:
case R_RISCV_TPREL_ADD:
- return R_HINT;
+ return R_NONE;
default:
- return R_ABS;
+ error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
+ ") against symbol " + toString(s));
+ return R_NONE;
}
}
@@ -419,21 +434,9 @@ void RISCV::relocateOne(uint8_t *loc, const RelType type,
case R_RISCV_ALIGN:
case R_RISCV_RELAX:
return; // Ignored (for now)
- case R_RISCV_NONE:
- return; // Do nothing
-
- // These are handled by the dynamic linker
- case R_RISCV_RELATIVE:
- case R_RISCV_COPY:
- case R_RISCV_JUMP_SLOT:
- // GP-relative relocations are only produced after relaxation, which
- // we don't support for now
- case R_RISCV_GPREL_I:
- case R_RISCV_GPREL_S:
+
default:
- error(getErrorLocation(loc) +
- "unimplemented relocation: " + toString(type));
- return;
+ llvm_unreachable("unknown relocation");
}
}