@@ -307,6 +307,8 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
307
307
sym.verdefIndex = old.verdefIndex ;
308
308
sym.exportDynamic = true ;
309
309
sym.isUsedInRegularObj = true ;
310
+ // A copy relocated alias may need a GOT entry.
311
+ sym.needsGot = old.needsGot ;
310
312
}
311
313
312
314
// Reserve space in .bss or .bss.rel.ro for copy relocation.
@@ -351,7 +353,7 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
351
353
// to the variable in .bss. This kind of issue is sometimes very hard to
352
354
// debug. What's a solution? Instead of exporting a variable V from a DSO,
353
355
// define an accessor getV().
354
- template <class ELFT > static void addCopyRelSymbol (SharedSymbol &ss) {
356
+ template <class ELFT > static void addCopyRelSymbolImpl (SharedSymbol &ss) {
355
357
// Copy relocation against zero-sized symbol doesn't make sense.
356
358
uint64_t symSize = ss.getSize ();
357
359
if (symSize == 0 || ss.alignment == 0 )
@@ -382,6 +384,26 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
382
384
mainPart->relaDyn ->addSymbolReloc (target->copyRel , sec, 0 , ss);
383
385
}
384
386
387
+ static void addCopyRelSymbol (SharedSymbol &ss) {
388
+ const SharedFile &file = ss.getFile ();
389
+ switch (file.ekind ) {
390
+ case ELF32LEKind:
391
+ addCopyRelSymbolImpl<ELF32LE>(ss);
392
+ break ;
393
+ case ELF32BEKind:
394
+ addCopyRelSymbolImpl<ELF32BE>(ss);
395
+ break ;
396
+ case ELF64LEKind:
397
+ addCopyRelSymbolImpl<ELF64LE>(ss);
398
+ break ;
399
+ case ELF64BEKind:
400
+ addCopyRelSymbolImpl<ELF64BE>(ss);
401
+ break ;
402
+ default :
403
+ llvm_unreachable (" " );
404
+ }
405
+ }
406
+
385
407
// MIPS has an odd notion of "paired" relocations to calculate addends.
386
408
// For example, if a relocation is of R_MIPS_HI16, there must be a
387
409
// R_MIPS_LO16 relocation after that, and an addend is calculated using
@@ -1045,7 +1067,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
1045
1067
" against symbol '" + toString (*ss) +
1046
1068
" '; recompile with -fPIC or remove '-z nocopyreloc'" +
1047
1069
getLocation (sec, sym, offset));
1048
- addCopyRelSymbol<ELFT>(*ss) ;
1070
+ sym. needsCopy = true ;
1049
1071
}
1050
1072
sec.relocations .push_back ({expr, type, offset, addend, &sym});
1051
1073
return ;
@@ -1083,20 +1105,8 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
1083
1105
errorOrWarn (" symbol '" + toString (sym) +
1084
1106
" ' cannot be preempted; recompile with -fPIE" +
1085
1107
getLocation (sec, sym, offset));
1086
- if (!sym.isInPlt ())
1087
- addPltEntry (in.plt , in.gotPlt , in.relaPlt , target->pltRel , sym);
1088
- if (!sym.isDefined ()) {
1089
- replaceWithDefined (
1090
- sym, in.plt ,
1091
- target->pltHeaderSize + target->pltEntrySize * sym.pltIndex , 0 );
1092
- if (config->emachine == EM_PPC) {
1093
- // PPC32 canonical PLT entries are at the beginning of .glink
1094
- cast<Defined>(sym).value = in.plt ->headerSize ;
1095
- in.plt ->headerSize += 16 ;
1096
- cast<PPC32GlinkSection>(in.plt )->canonical_plts .push_back (&sym);
1097
- }
1098
- }
1099
- sym.needsPltAddr = true ;
1108
+ sym.needsCopy = true ;
1109
+ sym.needsPlt = true ;
1100
1110
sec.relocations .push_back ({expr, type, offset, addend, &sym});
1101
1111
return ;
1102
1112
}
@@ -1425,116 +1435,23 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
1425
1435
return ;
1426
1436
}
1427
1437
1428
- // Non-preemptible ifuncs require special handling. First, handle the usual
1429
- // case where the symbol isn't one of these.
1430
- if (!sym.isGnuIFunc () || sym.isPreemptible ) {
1431
- // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
1432
- if (needsPlt (expr) && !sym.isInPlt ())
1433
- addPltEntry (in.plt , in.gotPlt , in.relaPlt , target->pltRel , sym);
1434
-
1435
- // Create a GOT slot if a relocation needs GOT.
1436
- if (needsGot (expr)) {
1437
- if (config->emachine == EM_MIPS) {
1438
- // MIPS ABI has special rules to process GOT entries and doesn't
1439
- // require relocation entries for them. A special case is TLS
1440
- // relocations. In that case dynamic loader applies dynamic
1441
- // relocations to initialize TLS GOT entries.
1442
- // See "Global Offset Table" in Chapter 5 in the following document
1443
- // for detailed description:
1444
- // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1445
- in.mipsGot ->addEntry (*sec.file , sym, addend, expr);
1446
- } else if (!sym.isInGot ()) {
1447
- addGotEntry (sym);
1448
- }
1438
+ if (needsGot (expr)) {
1439
+ if (config->emachine == EM_MIPS) {
1440
+ // MIPS ABI has special rules to process GOT entries and doesn't
1441
+ // require relocation entries for them. A special case is TLS
1442
+ // relocations. In that case dynamic loader applies dynamic
1443
+ // relocations to initialize TLS GOT entries.
1444
+ // See "Global Offset Table" in Chapter 5 in the following document
1445
+ // for detailed description:
1446
+ // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1447
+ in.mipsGot ->addEntry (*sec.file , sym, addend, expr);
1448
+ } else {
1449
+ sym.needsGot = true ;
1449
1450
}
1451
+ } else if (needsPlt (expr)) {
1452
+ sym.needsPlt = true ;
1450
1453
} else {
1451
- // Handle a reference to a non-preemptible ifunc. These are special in a
1452
- // few ways:
1453
- //
1454
- // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
1455
- // a fixed value. But assuming that all references to the ifunc are
1456
- // GOT-generating or PLT-generating, the handling of an ifunc is
1457
- // relatively straightforward. We create a PLT entry in Iplt, which is
1458
- // usually at the end of .plt, which makes an indirect call using a
1459
- // matching GOT entry in igotPlt, which is usually at the end of .got.plt.
1460
- // The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
1461
- // which is usually at the end of .rela.plt. Unlike most relocations in
1462
- // .rela.plt, which may be evaluated lazily without -z now, dynamic
1463
- // loaders evaluate IRELATIVE relocs eagerly, which means that for
1464
- // IRELATIVE relocs only, GOT-generating relocations can point directly to
1465
- // .got.plt without requiring a separate GOT entry.
1466
- //
1467
- // - Despite the fact that an ifunc does not have a fixed value, compilers
1468
- // that are not passed -fPIC will assume that they do, and will emit
1469
- // direct (non-GOT-generating, non-PLT-generating) relocations to the
1470
- // symbol. This means that if a direct relocation to the symbol is
1471
- // seen, the linker must set a value for the symbol, and this value must
1472
- // be consistent no matter what type of reference is made to the symbol.
1473
- // This can be done by creating a PLT entry for the symbol in the way
1474
- // described above and making it canonical, that is, making all references
1475
- // point to the PLT entry instead of the resolver. In lld we also store
1476
- // the address of the PLT entry in the dynamic symbol table, which means
1477
- // that the symbol will also have the same value in other modules.
1478
- // Because the value loaded from the GOT needs to be consistent with
1479
- // the value computed using a direct relocation, a non-preemptible ifunc
1480
- // may end up with two GOT entries, one in .got.plt that points to the
1481
- // address returned by the resolver and is used only by the PLT entry,
1482
- // and another in .got that points to the PLT entry and is used by
1483
- // GOT-generating relocations.
1484
- //
1485
- // - The fact that these symbols do not have a fixed value makes them an
1486
- // exception to the general rule that a statically linked executable does
1487
- // not require any form of dynamic relocation. To handle these relocations
1488
- // correctly, the IRELATIVE relocations are stored in an array which a
1489
- // statically linked executable's startup code must enumerate using the
1490
- // linker-defined symbols __rela?_iplt_{start,end}.
1491
- if (!sym.isInPlt ()) {
1492
- // Create PLT and GOTPLT slots for the symbol.
1493
- sym.isInIplt = true ;
1494
-
1495
- // Create a copy of the symbol to use as the target of the IRELATIVE
1496
- // relocation in the igotPlt. This is in case we make the PLT canonical
1497
- // later, which would overwrite the original symbol.
1498
- //
1499
- // FIXME: Creating a copy of the symbol here is a bit of a hack. All
1500
- // that's really needed to create the IRELATIVE is the section and value,
1501
- // so ideally we should just need to copy those.
1502
- auto *directSym = make<Defined>(cast<Defined>(sym));
1503
- addPltEntry (in.iplt , in.igotPlt , in.relaIplt , target->iRelativeRel ,
1504
- *directSym);
1505
- sym.pltIndex = directSym->pltIndex ;
1506
- }
1507
- if (needsGot (expr)) {
1508
- // Redirect GOT accesses to point to the Igot.
1509
- //
1510
- // This field is also used to keep track of whether we ever needed a GOT
1511
- // entry. If we did and we make the PLT canonical later, we'll need to
1512
- // create a GOT entry pointing to the PLT entry for Sym.
1513
- sym.gotInIgot = true ;
1514
- } else if (!needsPlt (expr)) {
1515
- // Make the ifunc's PLT entry canonical by changing the value of its
1516
- // symbol to redirect all references to point to it.
1517
- auto &d = cast<Defined>(sym);
1518
- d.section = in.iplt ;
1519
- d.value = sym.pltIndex * target->ipltEntrySize ;
1520
- d.size = 0 ;
1521
- // It's important to set the symbol type here so that dynamic loaders
1522
- // don't try to call the PLT as if it were an ifunc resolver.
1523
- d.type = STT_FUNC;
1524
-
1525
- if (sym.gotInIgot ) {
1526
- // We previously encountered a GOT generating reference that we
1527
- // redirected to the Igot. Now that the PLT entry is canonical we must
1528
- // clear the redirection to the Igot and add a GOT entry. As we've
1529
- // changed the symbol type to STT_FUNC future GOT generating references
1530
- // will naturally use this GOT entry.
1531
- //
1532
- // We don't need to worry about creating a MIPS GOT here because ifuncs
1533
- // aren't a thing on MIPS.
1534
- sym.gotInIgot = false ;
1535
- addGotEntry (sym);
1536
- }
1537
- }
1454
+ sym.hasDirectReloc = true ;
1538
1455
}
1539
1456
1540
1457
processRelocAux<ELFT>(sec, expr, type, offset, sym, addend);
@@ -1615,6 +1532,124 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
1615
1532
scanRelocs<ELFT>(s, rels.relas );
1616
1533
}
1617
1534
1535
+ static bool handleNonPreemptibleIfunc (Symbol &sym) {
1536
+ // Handle a reference to a non-preemptible ifunc. These are special in a
1537
+ // few ways:
1538
+ //
1539
+ // - Unlike most non-preemptible symbols, non-preemptible ifuncs do not have
1540
+ // a fixed value. But assuming that all references to the ifunc are
1541
+ // GOT-generating or PLT-generating, the handling of an ifunc is
1542
+ // relatively straightforward. We create a PLT entry in Iplt, which is
1543
+ // usually at the end of .plt, which makes an indirect call using a
1544
+ // matching GOT entry in igotPlt, which is usually at the end of .got.plt.
1545
+ // The GOT entry is relocated using an IRELATIVE relocation in relaIplt,
1546
+ // which is usually at the end of .rela.plt. Unlike most relocations in
1547
+ // .rela.plt, which may be evaluated lazily without -z now, dynamic
1548
+ // loaders evaluate IRELATIVE relocs eagerly, which means that for
1549
+ // IRELATIVE relocs only, GOT-generating relocations can point directly to
1550
+ // .got.plt without requiring a separate GOT entry.
1551
+ //
1552
+ // - Despite the fact that an ifunc does not have a fixed value, compilers
1553
+ // that are not passed -fPIC will assume that they do, and will emit
1554
+ // direct (non-GOT-generating, non-PLT-generating) relocations to the
1555
+ // symbol. This means that if a direct relocation to the symbol is
1556
+ // seen, the linker must set a value for the symbol, and this value must
1557
+ // be consistent no matter what type of reference is made to the symbol.
1558
+ // This can be done by creating a PLT entry for the symbol in the way
1559
+ // described above and making it canonical, that is, making all references
1560
+ // point to the PLT entry instead of the resolver. In lld we also store
1561
+ // the address of the PLT entry in the dynamic symbol table, which means
1562
+ // that the symbol will also have the same value in other modules.
1563
+ // Because the value loaded from the GOT needs to be consistent with
1564
+ // the value computed using a direct relocation, a non-preemptible ifunc
1565
+ // may end up with two GOT entries, one in .got.plt that points to the
1566
+ // address returned by the resolver and is used only by the PLT entry,
1567
+ // and another in .got that points to the PLT entry and is used by
1568
+ // GOT-generating relocations.
1569
+ //
1570
+ // - The fact that these symbols do not have a fixed value makes them an
1571
+ // exception to the general rule that a statically linked executable does
1572
+ // not require any form of dynamic relocation. To handle these relocations
1573
+ // correctly, the IRELATIVE relocations are stored in an array which a
1574
+ // statically linked executable's startup code must enumerate using the
1575
+ // linker-defined symbols __rela?_iplt_{start,end}.
1576
+ if (!sym.isGnuIFunc () || sym.isPreemptible || config->zIfuncNoplt )
1577
+ return false ;
1578
+ // Skip unreferenced non-preemptible ifunc.
1579
+ if (!(sym.needsGot || sym.needsPlt || sym.hasDirectReloc ))
1580
+ return true ;
1581
+
1582
+ sym.isInIplt = true ;
1583
+
1584
+ // Create an Iplt and the associated IRELATIVE relocation pointing to the
1585
+ // original section/value pairs. For non-GOT non-PLT relocation case below, we
1586
+ // may alter section/value, so create a copy of the symbol to make
1587
+ // section/value fixed.
1588
+ auto *directSym = make<Defined>(cast<Defined>(sym));
1589
+ addPltEntry (in.iplt , in.igotPlt , in.relaIplt , target->iRelativeRel ,
1590
+ *directSym);
1591
+ sym.pltIndex = directSym->pltIndex ;
1592
+
1593
+ if (sym.hasDirectReloc ) {
1594
+ // Change the value to the IPLT and redirect all references to it.
1595
+ auto &d = cast<Defined>(sym);
1596
+ d.section = in.iplt ;
1597
+ d.value = sym.pltIndex * target->ipltEntrySize ;
1598
+ d.size = 0 ;
1599
+ // It's important to set the symbol type here so that dynamic loaders
1600
+ // don't try to call the PLT as if it were an ifunc resolver.
1601
+ d.type = STT_FUNC;
1602
+
1603
+ if (sym.needsGot )
1604
+ addGotEntry (sym);
1605
+ } else if (sym.needsGot ) {
1606
+ // Redirect GOT accesses to point to the Igot.
1607
+ sym.gotInIgot = true ;
1608
+ }
1609
+ return true ;
1610
+ }
1611
+
1612
+ void elf::postScanRelocations () {
1613
+ auto fn = [](Symbol &sym) {
1614
+ if (handleNonPreemptibleIfunc (sym))
1615
+ return ;
1616
+ if (sym.needsGot )
1617
+ addGotEntry (sym);
1618
+ if (sym.needsPlt )
1619
+ addPltEntry (in.plt , in.gotPlt , in.relaPlt , target->pltRel , sym);
1620
+ if (sym.needsCopy ) {
1621
+ if (sym.isObject ()) {
1622
+ addCopyRelSymbol (cast<SharedSymbol>(sym));
1623
+ // needsCopy is cleared for sym and its aliases so that in later
1624
+ // iterations aliases won't cause redundant copies.
1625
+ assert (!sym.needsCopy );
1626
+ } else {
1627
+ assert (sym.isFunc () && sym.needsPlt );
1628
+ if (!sym.isDefined ()) {
1629
+ replaceWithDefined (
1630
+ sym, in.plt ,
1631
+ target->pltHeaderSize + target->pltEntrySize * sym.pltIndex , 0 );
1632
+ sym.needsCopy = true ;
1633
+ if (config->emachine == EM_PPC) {
1634
+ // PPC32 canonical PLT entries are at the beginning of .glink
1635
+ cast<Defined>(sym).value = in.plt ->headerSize ;
1636
+ in.plt ->headerSize += 16 ;
1637
+ cast<PPC32GlinkSection>(in.plt )->canonical_plts .push_back (&sym);
1638
+ }
1639
+ }
1640
+ }
1641
+ }
1642
+ };
1643
+ for (Symbol *sym : symtab->symbols ())
1644
+ fn (*sym);
1645
+
1646
+ // Local symbols may need the aforementioned non-preemptible ifunc and GOT
1647
+ // handling. They don't need regular PLT.
1648
+ for (InputFile *file : objectFiles)
1649
+ for (Symbol *sym : cast<ELFFileBase>(file)->getLocalSymbols ())
1650
+ fn (*sym);
1651
+ }
1652
+
1618
1653
static bool mergeCmp (const InputSection *a, const InputSection *b) {
1619
1654
// std::merge requires a strict weak ordering.
1620
1655
if (a->outSecOff < b->outSecOff )
0 commit comments