@@ -210,8 +210,9 @@ static bool needsPlt(RelExpr expr) {
210
210
}
211
211
212
212
bool 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,
215
216
R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(
216
217
expr);
217
218
}
@@ -933,14 +934,26 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
933
934
934
935
// If preemptible, emit a GLOB_DAT relocation.
935
936
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,
937
943
DynamicReloc::AgainstSymbol, sym, 0 ,
938
944
R_ABS});
939
945
return ;
940
946
}
941
947
942
948
// 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
+
944
957
if (!ctx.arg .isPic || isAbsolute (sym))
945
958
ctx.in .got ->addConstant ({R_ABS, ctx.target ->symbolicRel , off, 0 , &sym});
946
959
else
@@ -994,10 +1007,11 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
994
1007
// These expressions always compute a constant
995
1008
if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, R_MIPS_GOT_LOCAL_PAGE,
996
1009
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,
1001
1015
R_LOONGARCH_GOT_PAGE_PC>(e))
1002
1016
return true ;
1003
1017
@@ -1111,7 +1125,19 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
1111
1125
} else if (!sym.isTls () || ctx.arg .emachine != EM_LOONGARCH) {
1112
1126
// Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which
1113
1127
// 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
+ }
1115
1141
}
1116
1142
} else if (needsPlt (expr)) {
1117
1143
sym.setFlags (NEEDS_PLT);
0 commit comments