@@ -195,8 +195,8 @@ static bool isAbsoluteValue(const Symbol &sym) {
195195
196196// Returns true if Expr refers a PLT entry.
197197static bool needsPlt (RelExpr expr) {
198- return oneof<R_PLT, R_PLT_PC, R_PLT_GOTPLT, R_PPC32_PLTREL, R_PPC64_CALL_PLT>(
199- expr);
198+ return oneof<R_PLT, R_PLT_PC, R_PLT_GOTPLT, R_LOONGARCH_PLT_PAGE_PC,
199+ R_PPC32_PLTREL, R_PPC64_CALL_PLT>( expr);
200200}
201201
202202// Returns true if Expr refers a GOT entry. Note that this function
@@ -205,20 +205,23 @@ static bool needsPlt(RelExpr expr) {
205205static bool needsGot (RelExpr expr) {
206206 return oneof<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
207207 R_MIPS_GOT_OFF32, R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
208- R_AARCH64_GOT_PAGE>(expr);
208+ R_AARCH64_GOT_PAGE, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(
209+ expr);
209210}
210211
211212// True if this expression is of the form Sym - X, where X is a position in the
212213// file (PC, or GOT for example).
213214static bool isRelExpr (RelExpr expr) {
214215 return oneof<R_PC, R_GOTREL, R_GOTPLTREL, R_MIPS_GOTREL, R_PPC64_CALL,
215216 R_PPC64_RELAX_TOC, R_AARCH64_PAGE_PC, R_RELAX_GOT_PC,
216- R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC>(expr);
217+ R_RISCV_PC_INDIRECT, R_PPC64_RELAX_GOT_PC, R_LOONGARCH_PAGE_PC>(
218+ expr);
217219}
218220
219-
220221static RelExpr toPlt (RelExpr expr) {
221222 switch (expr) {
223+ case R_LOONGARCH_PAGE_PC:
224+ return R_LOONGARCH_PLT_PAGE_PC;
222225 case R_PPC64_CALL:
223226 return R_PPC64_CALL_PLT;
224227 case R_PC:
@@ -237,6 +240,8 @@ static RelExpr fromPlt(RelExpr expr) {
237240 case R_PLT_PC:
238241 case R_PPC32_PLTREL:
239242 return R_PC;
243+ case R_LOONGARCH_PLT_PAGE_PC:
244+ return R_LOONGARCH_PAGE_PC;
240245 case R_PPC64_CALL_PLT:
241246 return R_PPC64_CALL;
242247 case R_PLT:
@@ -951,7 +956,9 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
951956 R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
952957 R_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC, R_GOTPLTONLY_PC,
953958 R_PLT_PC, R_PLT_GOTPLT, R_PPC32_PLTREL, R_PPC64_CALL_PLT,
954- R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE>(e))
959+ R_PPC64_RELAX_TOC, R_RISCV_ADD, R_AARCH64_GOT_PAGE,
960+ R_LOONGARCH_PLT_PAGE_PC, R_LOONGARCH_GOT, R_LOONGARCH_GOT_PAGE_PC>(
961+ e))
955962 return true ;
956963
957964 // These never do, except if the entire file is position dependent or if
@@ -1055,7 +1062,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
10551062 // for detailed description:
10561063 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
10571064 in.mipsGot ->addEntry (*sec->file , sym, addend, expr);
1058- } else {
1065+ } else if (!sym.isTls () || config->emachine != EM_LOONGARCH) {
1066+ // Many LoongArch TLS relocs reuse the R_LOONGARCH_GOT type, in which
1067+ // case the NEEDS_GOT flag shouldn't get set.
10591068 sym.setFlags (NEEDS_GOT);
10601069 }
10611070 } else if (needsPlt (expr)) {
@@ -1095,7 +1104,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
10951104 (isa<EhInputSection>(sec) && config->emachine != EM_MIPS));
10961105 if (canWrite) {
10971106 RelType rel = target->getDynRel (type);
1098- if (expr == R_GOT || (rel == target->symbolicRel && !sym.isPreemptible )) {
1107+ if (oneof<R_GOT, R_LOONGARCH_GOT>(expr) ||
1108+ (rel == target->symbolicRel && !sym.isPreemptible )) {
10991109 addRelativeReloc<true >(*sec, offset, sym, addend, expr, type);
11001110 return ;
11011111 } else if (rel != 0 ) {
@@ -1247,11 +1257,13 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
12471257 return 1 ;
12481258 }
12491259
1250- // ARM, Hexagon and RISC-V do not support GD/LD to IE/LE relaxation. For
1251- // PPC64, if the file has missing R_PPC64_TLSGD/R_PPC64_TLSLD, disable
1260+ // ARM, Hexagon, LoongArch and RISC-V do not support GD/LD to IE/LE
1261+ // relaxation.
1262+ // For PPC64, if the file has missing R_PPC64_TLSGD/R_PPC64_TLSLD, disable
12521263 // relaxation as well.
12531264 bool toExecRelax = !config->shared && config->emachine != EM_ARM &&
12541265 config->emachine != EM_HEXAGON &&
1266+ config->emachine != EM_LOONGARCH &&
12551267 config->emachine != EM_RISCV &&
12561268 !c.file ->ppc64DisableTLSRelax ;
12571269
@@ -1268,8 +1280,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
12681280 // being suitable for being dynamically loaded via dlopen. GOT[e0] is the
12691281 // module index, with a special value of 0 for the current module. GOT[e1] is
12701282 // unused. There only needs to be one module index entry.
1271- if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(
1272- expr)) {
1283+ if (oneof<R_TLSLD_GOT, R_TLSLD_GOTPLT, R_TLSLD_PC, R_TLSLD_HINT>(expr)) {
12731284 // Local-Dynamic relocs can be relaxed to Local-Exec.
12741285 if (toExecRelax) {
12751286 c.addReloc ({target->adjustTlsExpr (type, R_RELAX_TLS_LD_TO_LE), type,
@@ -1300,7 +1311,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13001311 }
13011312
13021313 if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
1303- R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
1314+ R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC,
1315+ R_LOONGARCH_TLSGD_PAGE_PC>(expr)) {
13041316 if (!toExecRelax) {
13051317 sym.setFlags (NEEDS_TLSGD);
13061318 c.addReloc ({expr, type, offset, addend, &sym});
@@ -1320,8 +1332,8 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
13201332 return target->getTlsGdRelaxSkip (type);
13211333 }
13221334
1323- if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC, R_GOT_OFF,
1324- R_TLSIE_HINT>(expr)) {
1335+ if (oneof<R_GOT, R_GOTPLT, R_GOT_PC, R_AARCH64_GOT_PAGE_PC,
1336+ R_LOONGARCH_GOT_PAGE_PC, R_GOT_OFF, R_TLSIE_HINT>(expr)) {
13251337 ctx.hasTlsIe .store (true , std::memory_order_relaxed);
13261338 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
13271339 // defined.
0 commit comments