@@ -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
10241015void addNullDerivedCapability (Ctx &ctx, Symbol &sym, InputSectionBase &sec,
0 commit comments