Skip to content

Commit af5264f

Browse files
jrtc27resistor
authored andcommitted
[NFCI][ELF][CHERI] Restructure addCapabilityRelocation for clarity
1 parent bac4e13 commit af5264f

File tree

1 file changed

+61
-70
lines changed

1 file changed

+61
-70
lines changed

lld/ELF/Arch/Cheri.cpp

Lines changed: 61 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -916,12 +916,6 @@ void addCapabilityRelocation(
916916
<< ">>> referenced by " << sec->getObjMsg(offset);
917917
}
918918

919-
// Emit either the legacy __cap_relocs section or a R_CHERI_CAPABILITY reloc
920-
// For local symbols we can also emit the untagged capability bits and
921-
// instruct csu/rtld to run CBuildCap
922-
CapRelocsMode capRelocMode = sym && sym->isPreemptible
923-
? CapRelocsMode::ElfReloc
924-
: ctx.arg.localCapRelocsMode;
925919
bool needTrampoline = false;
926920
// In the PLT ABI (and fndesc?) we have to use an elf relocation for function
927921
// pointers to ensure that the runtime linker adds the required trampolines
@@ -944,81 +938,78 @@ void addCapabilityRelocation(
944938
needTrampoline = true;
945939
}
946940

947-
if (needTrampoline) {
948-
capRelocMode = CapRelocsMode::ElfReloc;
949-
if (ctx.arg.verboseCapRelocs)
950-
message("Using trampoline for function pointer against " +
951-
verboseToString(ctx, sym));
952-
}
941+
if (needTrampoline && ctx.arg.verboseCapRelocs)
942+
message("Using trampoline for function pointer against " +
943+
verboseToString(ctx, sym));
953944
}
954945

955946
// Non-preemptible undef weak symbols are link-time constants and should use
956947
// addNullDerivedCapability
957948
if (sym)
958949
assert(sym->isPreemptible || !sym->isUndefWeak());
959950

960-
// local cap relocs don't need a Elf relocation with a full symbol lookup:
961-
if (capRelocMode == CapRelocsMode::ElfReloc) {
962-
assert(sym && "ELF relocs should not be used against sections");
963-
assert((sym->isPreemptible || needTrampoline) &&
964-
"ELF relocs should not be used for non-preemptible symbols");
965-
assert((!sym->isLocal() || needTrampoline) &&
966-
"ELF relocs should not be used for local symbols");
967-
if (ctx.arg.emachine == llvm::ELF::EM_MIPS && ctx.arg.buildingFreeBSDRtld) {
968-
Err(ctx) << "relocation " << type << " against " << verboseToString(ctx, sym)
969-
<< " cannot be using when building FreeBSD RTLD"
970-
<< referencedBy();
971-
return;
972-
}
973-
if (!lld::elf::hasDynamicLinker(ctx)) {
974-
auto diag = Err(ctx);
975-
diag << "attempting to emit a R_CAPABILITY relocation against ";
976-
if (sym->getName().empty())
977-
diag << "local symbol";
978-
else
979-
diag << "symbol " << toStr(ctx, *sym);
980-
diag << " in binary without a dynamic linker; try removing -Wl,-"
981-
<< (sym->isPreemptible ? "preemptible" : "local") << "-caprelocs=elf"
982-
<< referencedBy();
983-
return;
984-
}
985-
assert(ctx.hasDynsym && "Should have been checked in Driver.cpp");
986-
// We don't use a R_MIPS_CHERI_CAPABILITY relocation for the input but
987-
// instead need to use an absolute pointer size relocation to write
988-
// the offset addend
989-
if (!dynRelSec) dynRelSec = ctx.mainPart->relaDyn.get();
990-
// in the case that -local-caprelocs=elf is passed we need to ensure that
991-
// the target symbol is included in the dynamic symbol table
992-
if (!ctx.mainPart->dynSymTab) {
993-
error("R_CHERI_CAPABILITY relocations need a dynamic symbol table");
994-
return;
995-
}
996-
if (!isSymIncludedInDynsym(ctx, *sym)) {
997-
if (!needTrampoline) {
998-
error(
999-
"added a R_CHERI_CAPABILITY relocation but symbol not included "
951+
// Emit either the legacy __cap_relocs section or a R_CHERI_CAPABILITY reloc
952+
// For local symbols we can also emit the untagged capability bits and
953+
// instruct csu/rtld to run CBuildCap
954+
if ((!sym || !sym->isPreemptible) && !needTrampoline) {
955+
assert(ctx.arg.localCapRelocsMode == CapRelocsMode::Legacy &&
956+
"relative ELF capability relocations not currently implemented");
957+
ctx.in.capRelocs->addCapReloc({sec, offset}, {symOrSec, 0u}, addend);
958+
return;
959+
}
960+
961+
assert(sym && "ELF relocs should not be used against sections");
962+
assert((sym->isPreemptible || needTrampoline) &&
963+
"ELF relocs should not be used for non-preemptible symbols");
964+
assert((!sym->isLocal() || needTrampoline) &&
965+
"ELF relocs should not be used for local symbols");
966+
if (ctx.arg.emachine == llvm::ELF::EM_MIPS && ctx.arg.buildingFreeBSDRtld) {
967+
error("relocation " + toStr(ctx, type) + " against " +
968+
verboseToString(ctx, sym) +
969+
" cannot be using when building FreeBSD RTLD" + referencedBy());
970+
return;
971+
}
972+
if (!lld::elf::hasDynamicLinker(ctx)) {
973+
error("attempting to emit a R_CAPABILITY relocation against " +
974+
(sym->getName().empty() ? "local symbol"
975+
: "symbol " + toStr(ctx, *sym)) +
976+
" in binary without a dynamic linker; try removing -Wl,-" +
977+
(sym->isPreemptible ? "preemptible" : "local") + "-caprelocs=elf" +
978+
referencedBy());
979+
return;
980+
}
981+
assert(ctx.hasDynsym && "Should have been checked in Driver.cpp");
982+
// We don't use a R_MIPS_CHERI_CAPABILITY relocation for the input but
983+
// instead need to use an absolute pointer size relocation to write
984+
// the offset addend
985+
if (!dynRelSec)
986+
dynRelSec = ctx.mainPart->relaDyn.get();
987+
// in the case that -local-caprelocs=elf is passed we need to ensure that
988+
// the target symbol is included in the dynamic symbol table
989+
if (!ctx.mainPart->dynSymTab) {
990+
error("R_CHERI_CAPABILITY relocations need a dynamic symbol table");
991+
return;
992+
}
993+
if (!isSymIncludedInDynsym(ctx, *sym)) {
994+
if (!needTrampoline) {
995+
error("added a R_CHERI_CAPABILITY relocation but symbol not included "
1000996
"in dynamic symbol: " +
1001997
verboseToString(ctx, sym));
1002-
return;
1003-
}
1004-
// Hack: Add a new global symbol with a unique name so that we can use
1005-
// a dynamic relocation against it.
1006-
// TODO: should it be possible to add STB_LOCAL symbols to .dynsymtab?
1007-
Defined *newSym = ctx.symtab->ensureSymbolWillBeInDynsym(sym);
1008-
assert(newSym->isFunc() && "This should only be used for functions");
1009-
assert(newSym->isExported);
1010-
assert(newSym->binding == llvm::ELF::STB_GLOBAL);
1011-
assert(newSym->visibility() == llvm::ELF::STV_HIDDEN);
1012-
sym = newSym; // Make the relocation point to the newly added symbol
998+
return;
1013999
}
1014-
dynRelSec->addReloc(
1015-
DynamicReloc::AgainstSymbol, type, *sec, offset, *sym, addend, expr,
1016-
/* Relocation type for the addend = */ ctx.target->symbolicRel);
1017-
1018-
} else {
1019-
assert(ctx.arg.localCapRelocsMode == CapRelocsMode::Legacy);
1020-
ctx.in.capRelocs->addCapReloc({sec, offset}, {symOrSec, 0u}, addend);
1000+
// Hack: Add a new global symbol with a unique name so that we can use
1001+
// a dynamic relocation against it.
1002+
// TODO: should it be possible to add STB_LOCAL symbols to .dynsymtab?
1003+
Defined *newSym = ctx.symtab->ensureSymbolWillBeInDynsym(sym);
1004+
assert(newSym->isFunc() && "This should only be used for functions");
1005+
assert(isSymIncludedInDynsym(ctx, *newSym));
1006+
assert(newSym->binding == llvm::ELF::STB_GLOBAL);
1007+
assert(newSym->visibility() == llvm::ELF::STV_HIDDEN);
1008+
sym = newSym; // Make the relocation point to the newly added symbol
10211009
}
1010+
dynRelSec->addReloc(
1011+
DynamicReloc::AgainstSymbol, type, *sec, offset, *sym, addend, expr,
1012+
/* Relocation type for the addend = */ ctx.target->symbolicRel);
10221013
}
10231014

10241015
void addNullDerivedCapability(Ctx &ctx, Symbol &sym, InputSectionBase &sec,

0 commit comments

Comments
 (0)