@@ -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}
@@ -932,14 +933,26 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
932933
933934 // If preemptible, emit a GLOB_DAT relocation.
934935 if (sym.isPreemptible ) {
935- ctx.mainPart ->relaDyn ->addReloc ({ctx.target ->gotRel , ctx.in .got .get (), off,
936+ RelType gotRel = ctx.target ->gotRel ;
937+ if (sym.hasFlag (NEEDS_GOT_AUTH)) {
938+ assert (ctx.arg .emachine == EM_AARCH64);
939+ gotRel = R_AARCH64_AUTH_GLOB_DAT;
940+ }
941+ ctx.mainPart ->relaDyn ->addReloc ({gotRel, ctx.in .got .get (), off,
936942 DynamicReloc::AgainstSymbol, sym, 0 ,
937943 R_ABS});
938944 return ;
939945 }
940946
941947 // Otherwise, the value is either a link-time constant or the load base
942- // plus a constant.
948+ // plus a constant. Signed GOT requires dynamic relocation.
949+ if (sym.hasFlag (NEEDS_GOT_AUTH)) {
950+ ctx.in .got ->getPartition (ctx).relaDyn ->addReloc (
951+ {R_AARCH64_AUTH_RELATIVE, ctx.in .got .get (), off,
952+ DynamicReloc::AddendOnlyWithTargetVA, sym, 0 , R_ABS});
953+ return ;
954+ }
955+
943956 if (!ctx.arg .isPic || isAbsolute (sym))
944957 ctx.in .got ->addConstant ({R_ABS, ctx.target ->symbolicRel , off, 0 , &sym});
945958 else
@@ -993,10 +1006,11 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
9931006 // These expressions always compute a constant
9941007 if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, R_MIPS_GOT_LOCAL_PAGE,
9951008 R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
996- R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,
997- R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT, R_GOTPLT_GOTREL, R_GOTPLT_PC,
998- R_PPC32_PLTREL, R_PPC64_CALL_PLT, R_PPC64_RELAX_TOC, R_RISCV_ADD,
999- R_AARCH64_GOT_PAGE, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,
1009+ R_AARCH64_GOT_PAGE_PC, R_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
1010+ R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
1011+ R_GOTPLT_GOTREL, R_GOTPLT_PC, R_PPC32_PLTREL, R_PPC64_CALL_PLT,
1012+ R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE,
1013+ R_AARCH64_AUTH_GOT, R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT,
10001014 R_LOONGARCH_GOT_PAGE_PC>(e))
10011015 return true ;
10021016
@@ -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