Skip to content

Commit e870c75

Browse files
committed
[CHERIoT] Introduce INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI to simplify handling of
PCC-relative R_RISCV_CHERIOT_COMPARTMENT_HI relocs.
1 parent 290fdf2 commit e870c75

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class RISCV final : public TargetInfo {
6363
#define INTERNAL_R_RISCV_X0REL_S 259
6464

6565
#define INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_LO_I 270
66+
#define INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI 271
6667

6768
const uint64_t dtpOffset = 0x800;
6869

@@ -398,8 +399,10 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
398399
return R_GOT_PC;
399400
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
400401
return R_TLSGD_PC;
402+
case INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI:
403+
return R_PC;
401404
case R_RISCV_CHERIOT_COMPARTMENT_HI:
402-
return isPCCRelative(ctx, loc, &s) ? R_PC : RE_CHERIOT_COMPARTMENT_CGPREL_HI;
405+
return RE_CHERIOT_COMPARTMENT_CGPREL_HI;
403406
case R_RISCV_CHERIOT_COMPARTMENT_LO_I:
404407
case R_RISCV_CHERIOT_COMPARTMENT_LO_S:
405408
return RE_CHERIOT_COMPARTMENT_CGPREL_LO;
@@ -500,8 +503,9 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
500503
if (isInt<20>(hi)) {
501504
relocate(loc,
502505
Relocation{R_NONE,
503-
ctx.arg.isCheriot ? R_RISCV_CHERIOT_COMPARTMENT_HI
504-
: R_RISCV_PCREL_HI20,
506+
ctx.arg.isCheriot
507+
? INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI
508+
: R_RISCV_PCREL_HI20,
505509
0, 0, rel.sym},
506510
val);
507511
relocate(loc + 4,
@@ -676,12 +680,24 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
676680
case R_RISCV_CHERIOT_COMPARTMENT_HI: {
677681
// AUICGP
678682
uint32_t opcode = AUICGP;
679-
if (isPCCRelative(ctx, loc, rel.sym)) {
680-
opcode = AUIPCC;
681-
if (int64_t(val) < 0)
682-
val = (val + 0x7ff) & ~0x7ff;
683-
val = int64_t(val) >> 11;
684-
}
683+
uint32_t existingOpcode = read32le(loc) & 0x7f;
684+
if ((existingOpcode != AUIPCC) && (existingOpcode != AUICGP))
685+
warn("R_RISCV_CHERIOT_COMPARTMENT_HI relocation applied to instruction "
686+
"with unexpected opcode " +
687+
Twine(existingOpcode));
688+
checkInt(ctx, loc, SignExtend64(val + 0x800, bits) >> 12, 20, rel);
689+
// Preserve the target register. We will rewrite the opcode (source
690+
// register) to either AUICGP or AUIPCC and set the immediate field.
691+
uint32_t insn = read32le(loc) & 0x00000f80;
692+
write32le(loc, insn | (val << 12) | opcode);
693+
break;
694+
}
695+
case INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI: {
696+
// AUIPCC
697+
uint32_t opcode = AUIPCC;
698+
if (int64_t(val) < 0)
699+
val = (val + 0x7ff) & ~0x7ff;
700+
val = int64_t(val) >> 11;
685701
uint32_t existingOpcode = read32le(loc) & 0x7f;
686702
if ((existingOpcode != AUIPCC) && (existingOpcode != AUICGP))
687703
warn("R_RISCV_CHERIOT_COMPARTMENT_HI relocation applied to instruction "
@@ -1065,7 +1081,12 @@ static void relaxCGP(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc,
10651081
static bool rewriteCheriotLowRelocs(Ctx &ctx, InputSection &sec) {
10661082
bool modified = false;
10671083
for (auto &r : sec.relocations) {
1068-
if (r.type == R_RISCV_CHERIOT_COMPARTMENT_LO_I) {
1084+
if (r.type == R_RISCV_CHERIOT_COMPARTMENT_HI &&
1085+
isPCCRelative(ctx, nullptr, r.sym)) {
1086+
modified = true;
1087+
r.type = INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI;
1088+
r.expr = R_PC;
1089+
} else if (r.type == R_RISCV_CHERIOT_COMPARTMENT_LO_I) {
10691090
// If this is PCC-relative, then the relocation points to the auicgp /
10701091
// auipcc instruction and we need to look there to find the real target.
10711092
if (!isPCCRelative(ctx, nullptr, r.sym))
@@ -1091,7 +1112,8 @@ static bool rewriteCheriotLowRelocs(Ctx &ctx, InputSection &sec) {
10911112

10921113
const Relocation *target = nullptr;
10931114
for (auto it = range.first; it != range.second; ++it)
1094-
if (it->type == R_RISCV_CHERIOT_COMPARTMENT_HI) {
1115+
if (it->type == R_RISCV_CHERIOT_COMPARTMENT_HI ||
1116+
it->type == INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI) {
10951117
target = &*it;
10961118
break;
10971119
}

lld/ELF/InputSection.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ using namespace llvm::sys;
3434
using namespace lld;
3535
using namespace lld::elf;
3636

37-
#define INTERNAL_R_RISCV_COMPARTMENT_AUICGP_LO_I 272
38-
#define INTERNAL_R_RISCV_COMPARTMENT_CGPREL_LO_I 273
39-
#define INTERNAL_R_RISCV_COMPARTMENT_AUIPCC_LO_I 274
37+
#define INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI 271
4038

4139
// Returns a string to construct an error message.
4240
std::string elf::toStr(Ctx &ctx, const InputSectionBase *sec) {
@@ -712,6 +710,7 @@ static Relocation *getRISCVPCRelHi20(Ctx &ctx, const InputSectionBase *loSec,
712710
if (it->type == R_RISCV_PCREL_HI20 || it->type == R_RISCV_GOT_HI20 ||
713711
it->type == R_RISCV_TLS_GD_HI20 || it->type == R_RISCV_TLS_GOT_HI20 ||
714712
it->type == R_RISCV_CHERIOT_COMPARTMENT_HI ||
713+
it->type == INTERNAL_R_RISCV_CHERIOT_COMPARTMENT_PCCREL_HI ||
715714
it->type == R_RISCV_CHERI_CAPTAB_PCREL_HI20 ||
716715
it->type == R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20 ||
717716
it->type == R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20)

0 commit comments

Comments
 (0)