@@ -124,6 +124,19 @@ static uint32_t setLO12_S(uint32_t insn, uint32_t imm) {
124124 (extractBits (imm, 4 , 0 ) << 7 );
125125}
126126
127+ static bool isCheriotHighPartReloc (RelType ty) {
128+ switch (ty) {
129+ case R_RISCV_CHERIOT_COMPARTMENT_HI:
130+ case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
131+ // FIXME: This can be enabled once they handle cheriot 11-bit AUIPC shifts.
132+ // case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
133+ // case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
134+ return true ;
135+ default :
136+ return false ;
137+ }
138+ }
139+
127140RISCV::RISCV (Ctx &ctx) : TargetInfo(ctx) {
128141 copyRel = R_RISCV_COPY;
129142 pltRel = R_RISCV_JUMP_SLOT;
@@ -540,6 +553,17 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
540553 case R_RISCV_TLS_GOT_HI20:
541554 case R_RISCV_TPREL_HI20:
542555 case R_RISCV_HI20: {
556+ if (ctx.arg .isCheriot && isCheriotHighPartReloc (rel.type )) {
557+ // Similar to R_RISCV_CHERIOT_COMPARTMENT_HI, except that these
558+ // always use AUIPCC.
559+ if (int64_t (val) < 0 )
560+ val = (val + 0x7ff ) & ~0x7ff ;
561+ val = int64_t (val) >> 11 ;
562+ checkInt (ctx, loc, SignExtend64 (val + 0x800 , bits) >> 12 , 20 , rel);
563+ write32le (loc, (read32le (loc) & 0xFFF ) | (val << 12 ));
564+ return ;
565+ }
566+
543567 uint64_t hi = val + 0x800 ;
544568 checkInt (ctx, loc, SignExtend64 (hi, bits) >> 12 , 20 , rel);
545569 write32le (loc, (read32le (loc) & 0xFFF ) | (hi & 0xFFFFF000 ));
@@ -1096,19 +1120,24 @@ static bool rewriteCheriotLowRelocs(Ctx &ctx, InputSection &sec) {
10961120
10971121 const Relocation *target = nullptr ;
10981122 for (auto it = range.first ; it != range.second ; ++it)
1099- if (it->type == R_RISCV_CHERIOT_COMPARTMENT_HI ) {
1123+ if (isCheriotHighPartReloc ( it->type ) ) {
11001124 target = &*it;
11011125 break ;
11021126 }
11031127 if (!target) {
1104- error (
1105- " Could not find R_RISCV_CHERIOT_COMPARTMENT_HI relocation for " +
1106- toStr (ctx, *r. sym ));
1128+ error (" Could not find high-part relocation for " +
1129+ toStr (ctx, *r. sym ) + " at 0x " +
1130+ llvm::utohexstr (r. offset , false , 8 ) + " @ " + toStr (ctx, &sec ));
11071131 }
11081132 // If the target is PCC-relative then the auipcc can't be erased and so
11091133 // skip the rewriting.
11101134 if (isPCCRelative (ctx, nullptr , target->sym ))
11111135 continue ;
1136+
1137+ // captab relocations similarly are never relaxed, so we can skip them.
1138+ if (target->type == R_RISCV_CHERI_CAPTAB_PCREL_HI20)
1139+ continue ;
1140+
11121141 // Update our relocation to point to the target thing.
11131142 r.sym = target->sym ;
11141143 r.addend = target->addend ;
0 commit comments