@@ -180,7 +180,7 @@ std::string CheriCapRelocLocation::toString(Ctx &ctx) const {
180180 return SymbolAndOffset (section, offset).verboseToString (ctx);
181181}
182182
183- void CheriCapRelocsSection::addCapReloc (CheriCapRelocLocation loc,
183+ void CheriCapRelocsSection::addCapReloc (bool isCode, CheriCapRelocLocation loc,
184184 const SymbolAndOffset &target,
185185 int64_t capabilityOffset,
186186 Symbol *sourceSymbol) {
@@ -215,7 +215,7 @@ void CheriCapRelocsSection::addCapReloc(CheriCapRelocLocation loc,
215215 return ;
216216 }
217217
218- addEntry (loc, {target, capabilityOffset});
218+ addEntry (loc, {isCode, target, capabilityOffset});
219219}
220220
221221static uint64_t getTargetSize (Ctx &ctx, const CheriCapRelocLocation &location,
@@ -321,6 +321,7 @@ template <class ELFT> struct CapRelocPermission {
321321 static const uint64_t function = permissionBit(1 );
322322 static const uint64_t readOnly = permissionBit(2 );
323323 static const uint64_t indirect = permissionBit(3 );
324+ static const uint64_t code = permissionBit(4 );
324325 // clang-format on
325326};
326327
@@ -353,7 +354,7 @@ void CheriCapRelocsSection::writeToImpl(uint8_t *buf) {
353354
354355 // The target VA is the base address of the capability, so symbol + 0
355356 uint64_t targetVA;
356- bool isFunc, isGnuIFunc, isTls;
357+ bool isFunc, isGnuIFunc, isTls, isCode = reloc. isCode ;
357358 OutputSection *os;
358359 if (Symbol *s = dyn_cast<Symbol *>(realTarget.symOrSec )) {
359360 targetVA = realTarget.sym ()->getVA (ctx, 0 );
@@ -369,6 +370,15 @@ void CheriCapRelocsSection::writeToImpl(uint8_t *buf) {
369370 isTls = isec->type == STT_TLS;
370371 os = isec->getOutputSection ();
371372 }
373+ if (isCode && !isFunc) {
374+ auto msg = " code relocation against non-function symbol " +
375+ realTarget.verboseToString (ctx) + " \n >>> referenced by " +
376+ location.toString (ctx);
377+ if (ctx.arg .noinhibitExec )
378+ warn (msg);
379+ else
380+ error (msg);
381+ }
372382 uint64_t targetSize = getTargetSize (ctx, location, realTarget);
373383 uint64_t targetOffset = reloc.capabilityOffset + realTarget.offset ;
374384 uint64_t permissions = 0 ;
@@ -377,6 +387,8 @@ void CheriCapRelocsSection::writeToImpl(uint8_t *buf) {
377387 permissions |= CapRelocPermission<ELFT>::function;
378388 if (isGnuIFunc)
379389 permissions |= CapRelocPermission<ELFT>::indirect;
390+ if (isCode)
391+ permissions |= CapRelocPermission<ELFT>::code;
380392 } else if (os) {
381393 assert (!isTls);
382394 // if ((OS->getPhdrFlags() & PF_W) == 0) {
@@ -960,10 +972,12 @@ void addRelativeCapabilityRelocation(
960972 type);
961973 return ;
962974 }
975+ bool isCode = type == ctx.target ->symbolicCodeCapRel ;
963976 assert (!sym || !sym->isPreemptible );
964977 assert (!ctx.arg .useRelativeElfCheriRelocs &&
965978 " relative ELF capability relocations not currently implemented" );
966- ctx.in .capRelocs ->addCapReloc ({&isec, offsetInSec}, {symOrSec, 0u }, addend);
979+ ctx.in .capRelocs ->addCapReloc (isCode, {&isec, offsetInSec}, {symOrSec, 0u },
980+ addend);
967981}
968982
969983} // namespace elf
0 commit comments