@@ -1035,9 +1035,30 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
1035
1035
// space for the extra PT_LOAD even if we end up not using it.
1036
1036
void RelocationScanner::processAux (RelExpr expr, RelType type, uint64_t offset,
1037
1037
Symbol &sym, int64_t addend) const {
1038
+ // If non-ifunc non-preemptible, change PLT to direct call and optimize GOT
1039
+ // indirection.
1040
+ const bool isIfunc = sym.isGnuIFunc ();
1041
+ if (!sym.isPreemptible && (!isIfunc || config->zIfuncNoplt )) {
1042
+ if (expr != R_GOT_PC) {
1043
+ // The 0x8000 bit of r_addend of R_PPC_PLTREL24 is used to choose call
1044
+ // stub type. It should be ignored if optimized to R_PC.
1045
+ if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)
1046
+ addend &= ~0x8000 ;
1047
+ // R_HEX_GD_PLT_B22_PCREL (call a@GDPLT) is transformed into
1048
+ // call __tls_get_addr even if the symbol is non-preemptible.
1049
+ if (!(config->emachine == EM_HEXAGON &&
1050
+ (type == R_HEX_GD_PLT_B22_PCREL ||
1051
+ type == R_HEX_GD_PLT_B22_PCREL_X ||
1052
+ type == R_HEX_GD_PLT_B32_PCREL_X)))
1053
+ expr = fromPlt (expr);
1054
+ } else if (!isAbsoluteValue (sym)) {
1055
+ expr =
1056
+ target->adjustGotPcExpr (type, addend, sec->rawData .data () + offset);
1057
+ }
1058
+ }
1059
+
1038
1060
// We were asked not to generate PLT entries for ifuncs. Instead, pass the
1039
1061
// direct relocation on through.
1040
- const bool isIfunc = sym.isGnuIFunc ();
1041
1062
if (LLVM_UNLIKELY (isIfunc) && config->zIfuncNoplt ) {
1042
1063
std::lock_guard<std::mutex> lock (relocMutex);
1043
1064
sym.exportDynamic = true ;
@@ -1428,30 +1449,6 @@ template <class ELFT, class RelTy> void RelocationScanner::scanOne(RelTy *&i) {
1428
1449
}
1429
1450
}
1430
1451
1431
- // If we know that a PLT entry will be resolved within the same ELF module, we
1432
- // can skip PLT access and directly jump to the destination function. For
1433
- // example, if we are linking a main executable, all dynamic symbols that can
1434
- // be resolved within the executable will actually be resolved that way at
1435
- // runtime, because the main executable is always at the beginning of a search
1436
- // list. We can leverage that fact.
1437
- if (!sym.isPreemptible && (!sym.isGnuIFunc () || config->zIfuncNoplt )) {
1438
- if (expr != R_GOT_PC) {
1439
- // The 0x8000 bit of r_addend of R_PPC_PLTREL24 is used to choose call
1440
- // stub type. It should be ignored if optimized to R_PC.
1441
- if (config->emachine == EM_PPC && expr == R_PPC32_PLTREL)
1442
- addend &= ~0x8000 ;
1443
- // R_HEX_GD_PLT_B22_PCREL (call a@GDPLT) is transformed into
1444
- // call __tls_get_addr even if the symbol is non-preemptible.
1445
- if (!(config->emachine == EM_HEXAGON &&
1446
- (type == R_HEX_GD_PLT_B22_PCREL ||
1447
- type == R_HEX_GD_PLT_B22_PCREL_X ||
1448
- type == R_HEX_GD_PLT_B32_PCREL_X)))
1449
- expr = fromPlt (expr);
1450
- } else if (!isAbsoluteValue (sym)) {
1451
- expr = target->adjustGotPcExpr (type, addend, relocatedAddr);
1452
- }
1453
- }
1454
-
1455
1452
processAux (expr, type, offset, sym, addend);
1456
1453
}
1457
1454
0 commit comments