@@ -307,6 +307,8 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
307307 sym.verdefIndex = old.verdefIndex ;
308308 sym.exportDynamic = true ;
309309 sym.isUsedInRegularObj = true ;
310+ // A copy relocated alias may need a GOT entry.
311+ sym.needsGot = old.needsGot ;
310312}
311313
312314// 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,
351353// to the variable in .bss. This kind of issue is sometimes very hard to
352354// debug. What's a solution? Instead of exporting a variable V from a DSO,
353355// define an accessor getV().
354- template <class ELFT > static void addCopyRelSymbol (SharedSymbol &ss) {
356+ template <class ELFT > static void addCopyRelSymbolImpl (SharedSymbol &ss) {
355357 // Copy relocation against zero-sized symbol doesn't make sense.
356358 uint64_t symSize = ss.getSize ();
357359 if (symSize == 0 || ss.alignment == 0 )
@@ -382,6 +384,26 @@ template <class ELFT> static void addCopyRelSymbol(SharedSymbol &ss) {
382384 mainPart->relaDyn ->addSymbolReloc (target->copyRel , sec, 0 , ss);
383385}
384386
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+
385407// MIPS has an odd notion of "paired" relocations to calculate addends.
386408// For example, if a relocation is of R_MIPS_HI16, there must be a
387409// 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,
10451067 " against symbol '" + toString (*ss) +
10461068 " '; recompile with -fPIC or remove '-z nocopyreloc'" +
10471069 getLocation (sec, sym, offset));
1048- addCopyRelSymbol<ELFT>(*ss) ;
1070+ sym. needsCopy = true ;
10491071 }
10501072 sec.relocations .push_back ({expr, type, offset, addend, &sym});
10511073 return ;
@@ -1083,20 +1105,8 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
10831105 errorOrWarn (" symbol '" + toString (sym) +
10841106 " ' cannot be preempted; recompile with -fPIE" +
10851107 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 ;
11001110 sec.relocations .push_back ({expr, type, offset, addend, &sym});
11011111 return ;
11021112 }
@@ -1425,116 +1435,23 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
14251435 return ;
14261436 }
14271437
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 ;
14491450 }
1451+ } else if (needsPlt (expr)) {
1452+ sym.needsPlt = true ;
14501453 } 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 ;
15381455 }
15391456
15401457 processRelocAux<ELFT>(sec, expr, type, offset, sym, addend);
@@ -1615,6 +1532,124 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
16151532 scanRelocs<ELFT>(s, rels.relas );
16161533}
16171534
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+
16181653static bool mergeCmp (const InputSection *a, const InputSection *b) {
16191654 // std::merge requires a strict weak ordering.
16201655 if (a->outSecOff < b->outSecOff )
0 commit comments