[PATCH] D142880: [RISCV][LLD] Support R_RISCV_SET_ULEB128 and R_RISCV_SUB_ULEB128
Kito Cheng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 30 02:53:30 PST 2023
kito-cheng created this revision.
kito-cheng added reviewers: asb, jrtc27, MaskRay.
Herald added subscribers: luke, VincentWu, vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, arichardson, emaste.
Herald added a project: All.
kito-cheng requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead, eopXD.
Herald added a project: LLVM.
Support for the uleb128 related relocation[1].
R_RISCV_SET_ULEB128 should defer the relocation until
R_RISCV_SUB_ULEB128 appear since the symbol address of
R_RISCV_SET_ULEB128 might not fit the space of the current ULEB128
value, e.g. current ULEB128 value occupy 2 byte only, but the address of symbol
might not fit in 2 byte, it only fit for the address difference of
R_RISCV_SET_ULEB128 and R_RISCV_SUB_ULEB128.
R_RISCV_SUB_ULEB128 must come after R_RISCV_SET_ULEB128, and rely value
of previous R_RISCV_SET_ULEB128 relocation.
NOTE: DO NOT merge this until corresponding psABI PR has merged.
[1] https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/361
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142880
Files:
lld/ELF/Arch/RISCV.cpp
Index: lld/ELF/Arch/RISCV.cpp
===================================================================
--- lld/ELF/Arch/RISCV.cpp
+++ lld/ELF/Arch/RISCV.cpp
@@ -41,6 +41,7 @@
RelType getDynRel(RelType type) const override;
RelExpr getRelExpr(RelType type, const Symbol &s,
const uint8_t *loc) const override;
+ void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
bool relaxOnce(int pass) const override;
@@ -95,6 +96,17 @@
(extractBits(imm, 4, 0) << 7);
}
+static void checkULEB128LengthNoExtend(uint8_t *loc, const RelType type,
+ unsigned oldLength, unsigned newLength) {
+ if (newLength <= oldLength)
+ return;
+
+ ErrorPlace errPlace = getErrorPlace(loc);
+ error(errPlace.loc + " ULEB128 value has extended the length by " +
+ toString(type) + "relocation from " + Twine(oldLength) + " byte to " +
+ Twine(newLength) + " byte");
+}
+
RISCV::RISCV() {
copyRel = R_RISCV_COPY;
pltRel = R_RISCV_JUMP_SLOT;
@@ -270,6 +282,8 @@
case R_RISCV_SUB16:
case R_RISCV_SUB32:
case R_RISCV_SUB64:
+ case R_RISCV_SET_ULEB128:
+ case R_RISCV_SUB_ULEB128:
return R_RISCV_ADD;
case R_RISCV_JAL:
case R_RISCV_BRANCH:
@@ -306,6 +320,60 @@
}
}
+void RISCV::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
+ const unsigned bits = config->is64 ? 64 : 32;
+ uint64_t secAddr = sec.getOutputSection()->addr;
+ if (auto *s = dyn_cast<InputSection>(&sec))
+ secAddr += s->outSecOff;
+
+ uint8_t *lastULEB128SetLoc = nullptr;
+ uint64_t lastULEB128SetVal = 0;
+ for (const Relocation &rel : sec.relocs()) {
+ uint8_t *loc = buf + rel.offset;
+ const uint64_t val = SignExtend64(
+ sec.getRelocTargetVA(sec.file, rel.type, rel.addend,
+ secAddr + rel.offset, *rel.sym, rel.expr),
+ bits);
+
+ if (rel.expr == R_RELAX_HINT)
+ continue;
+
+ switch (rel.type) {
+ case R_RISCV_SET_ULEB128: {
+ if (lastULEB128SetLoc != nullptr) {
+ ErrorPlace errPlace = getErrorPlace(loc);
+ error(errPlace.loc +
+ " More than one R_RISCV_SET_ULEB128 in same location");
+ }
+ lastULEB128SetLoc = loc;
+ lastULEB128SetVal = val;
+ break;
+ }
+ case R_RISCV_SUB_ULEB128: {
+ if (loc != lastULEB128SetLoc) {
+ ErrorPlace errPlace = getErrorPlace(loc);
+ error(errPlace.loc +
+ " R_RISCV_SUB_ULEB128 must come after R_RISCV_SET_ULEB128");
+ break;
+ }
+ unsigned oldLength;
+ decodeULEB128(loc, &oldLength);
+ uint64_t newVal = lastULEB128SetVal - val;
+ unsigned newLength = encodeULEB128(newVal, loc, /*PadTo*/ oldLength);
+ checkULEB128LengthNoExtend(loc, rel.type, oldLength, newLength);
+ lastULEB128SetLoc = nullptr;
+ break;
+ }
+ default:
+ relocate(loc, rel, val);
+ }
+ }
+ if (lastULEB128SetLoc != nullptr) {
+ ErrorPlace errPlace = getErrorPlace(lastULEB128SetLoc);
+ error(errPlace.loc + " Orphan R_RISCV_SET_ULEB128");
+ }
+}
+
void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
const unsigned bits = config->wordsize * 8;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142880.493260.patch
Type: text/x-patch
Size: 3322 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230130/81a942c5/attachment.bin>
More information about the llvm-commits
mailing list