@@ -210,8 +210,9 @@ static bool needsPlt(RelExpr expr) {
210210}
211211
212212bool lld::elf::needsGot (RelExpr expr) {
213- return oneof<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
214- R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
213+ return oneof<R_GOT, R_AARCH64_AUTH_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
214+ R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC,
215+ R_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
215216 R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(
216217 expr);
217218}
@@ -933,14 +934,26 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
933934
934935 // If preemptible, emit a GLOB_DAT relocation.
935936 if (sym.isPreemptible ) {
936- ctx.mainPart ->relaDyn ->addReloc ({ctx.target ->gotRel , ctx.in .got .get (), off,
937+ RelType gotRel = ctx.target ->gotRel ;
938+ if (sym.hasFlag (NEEDS_GOT_AUTH)) {
939+ assert (ctx.arg .emachine == EM_AARCH64);
940+ gotRel = R_AARCH64_AUTH_GLOB_DAT;
941+ }
942+ ctx.mainPart ->relaDyn ->addReloc ({gotRel, ctx.in .got .get (), off,
937943 DynamicReloc::AgainstSymbol, sym, 0 ,
938944 R_ABS});
939945 return ;
940946 }
941947
942948 // Otherwise, the value is either a link-time constant or the load base
943- // plus a constant.
949+ // plus a constant. Signed GOT requires dynamic relocation.
950+ if (sym.hasFlag (NEEDS_GOT_AUTH)) {
951+ ctx.in .got ->getPartition (ctx).relaDyn ->addReloc (
952+ {R_AARCH64_AUTH_RELATIVE, ctx.in .got .get (), off,
953+ DynamicReloc::AddendOnlyWithTargetVA, sym, 0 , R_ABS});
954+ return ;
955+ }
956+
944957 if (!ctx.arg .isPic || isAbsolute (sym))
945958 ctx.in .got ->addConstant ({R_ABS, ctx.target ->symbolicRel , off, 0 , &sym});
946959 else
@@ -994,10 +1007,11 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
9941007 // These expressions always compute a constant
9951008 if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, R_MIPS_GOT_LOCAL_PAGE,
9961009 R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
997- R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,
998- R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT, R_GOTPLT_GOTREL, R_GOTPLT_PC,
999- R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD,
1000- R_AARCH64_GOT_PAGE, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,
1010+ R_AARCH64_GOT_PAGE_PC, R_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
1011+ R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
1012+ R_GOTPLT_GOTREL, R_GOTPLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT,
1013+ R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE,
1014+ R_AARCH64_AUTH_GOT, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,
10011015 R_LOONGARCH_GOT_PAGE_PC>(e))
10021016 return true ;
10031017
@@ -1111,7 +1125,19 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11111125 } else if (!sym.isTls () || ctx.arg .emachine != EM_LOONGARCH) {
11121126 // Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which
11131127 // case the NEEDS_GOT flag shouldn't get set.
1114- sym.setFlags (NEEDS_GOT);
1128+ bool needsGotAuth =
1129+ (expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PAGE_PC);
1130+ uint16_t flags = sym.flags .load (std::memory_order_relaxed);
1131+ if (!(flags & NEEDS_GOT)) {
1132+ if (needsGotAuth)
1133+ sym.setFlags (NEEDS_GOT | NEEDS_GOT_AUTH);
1134+ else
1135+ sym.setFlags (NEEDS_GOT);
1136+ } else if (needsGotAuth != static_cast <bool >(flags & NEEDS_GOT_AUTH)) {
1137+ fatal (" both AUTH and non-AUTH GOT entries for '" + sym.getName () +
1138+ " ' requested, but only one type of GOT entry per symbol is "
1139+ " supported" );
1140+ }
11151141 }
11161142 } else if (needsPlt (expr)) {
11171143 sym.setFlags (NEEDS_PLT);
0 commit comments