@@ -307,8 +307,6 @@ 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 ;
312310}
313311
314312// Reserve space in .bss or .bss.rel.ro for copy relocation.
@@ -353,7 +351,7 @@ static void replaceWithDefined(Symbol &sym, SectionBase *sec, uint64_t value,
353351// to the variable in .bss. This kind of issue is sometimes very hard to
354352// debug. What's a solution? Instead of exporting a variable V from a DSO,
355353// define an accessor getV().
356- template <class ELFT > static void addCopyRelSymbolImpl (SharedSymbol &ss) {
354+ template <class ELFT > static void addCopyRelSymbol (SharedSymbol &ss) {
357355 // Copy relocation against zero-sized symbol doesn't make sense.
358356 uint64_t symSize = ss.getSize ();
359357 if (symSize == 0 || ss.alignment == 0 )
@@ -384,26 +382,6 @@ template <class ELFT> static void addCopyRelSymbolImpl(SharedSymbol &ss) {
384382 mainPart->relaDyn ->addSymbolReloc (target->copyRel , sec, 0 , ss);
385383}
386384
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-
407385// MIPS has an odd notion of "paired" relocations to calculate addends.
408386// For example, if a relocation is of R_MIPS_HI16, there must be a
409387// R_MIPS_LO16 relocation after that, and an addend is calculated using
@@ -1067,7 +1045,7 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
10671045 " against symbol '" + toString (*ss) +
10681046 " '; recompile with -fPIC or remove '-z nocopyreloc'" +
10691047 getLocation (sec, sym, offset));
1070- sym. needsCopy = true ;
1048+ addCopyRelSymbol<ELFT>(*ss) ;
10711049 }
10721050 sec.relocations .push_back ({expr, type, offset, addend, &sym});
10731051 return ;
@@ -1105,8 +1083,20 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
11051083 errorOrWarn (" symbol '" + toString (sym) +
11061084 " ' cannot be preempted; recompile with -fPIE" +
11071085 getLocation (sec, sym, offset));
1108- sym.needsCopy = true ;
1109- sym.needsPlt = true ;
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 ;
11101100 sec.relocations .push_back ({expr, type, offset, addend, &sym});
11111101 return ;
11121102 }
@@ -1435,23 +1425,116 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i,
14351425 return ;
14361426 }
14371427
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 ;
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+ }
14501449 }
1451- } else if (needsPlt (expr)) {
1452- sym.needsPlt = true ;
14531450 } else {
1454- sym.hasDirectReloc = true ;
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+ }
14551538 }
14561539
14571540 processRelocAux<ELFT>(sec, expr, type, offset, sym, addend);
@@ -1532,121 +1615,6 @@ template <class ELFT> void elf::scanRelocations(InputSectionBase &s) {
15321615 scanRelocs<ELFT>(s, rels.relas );
15331616}
15341617
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-
1579- sym.isInIplt = true ;
1580-
1581- // Create an Iplt and the associated IRELATIVE relocation pointing to the
1582- // original section/value pairs. For non-GOT non-PLT relocation case below, we
1583- // may alter section/value, so create a copy of the symbol to make
1584- // section/value fixed.
1585- auto *directSym = make<Defined>(cast<Defined>(sym));
1586- addPltEntry (in.iplt , in.igotPlt , in.relaIplt , target->iRelativeRel ,
1587- *directSym);
1588- sym.pltIndex = directSym->pltIndex ;
1589-
1590- if (sym.hasDirectReloc ) {
1591- // Change the value to the IPLT and redirect all references to it.
1592- auto &d = cast<Defined>(sym);
1593- d.section = in.iplt ;
1594- d.value = sym.pltIndex * target->ipltEntrySize ;
1595- d.size = 0 ;
1596- // It's important to set the symbol type here so that dynamic loaders
1597- // don't try to call the PLT as if it were an ifunc resolver.
1598- d.type = STT_FUNC;
1599-
1600- if (sym.needsGot )
1601- addGotEntry (sym);
1602- } else if (sym.needsGot ) {
1603- // Redirect GOT accesses to point to the Igot.
1604- sym.gotInIgot = true ;
1605- }
1606- return true ;
1607- }
1608-
1609- void elf::postScanRelocations () {
1610- auto fn = [](Symbol &sym) {
1611- if (handleNonPreemptibleIfunc (sym))
1612- return ;
1613- if (sym.needsGot )
1614- addGotEntry (sym);
1615- if (sym.needsPlt )
1616- addPltEntry (in.plt , in.gotPlt , in.relaPlt , target->pltRel , sym);
1617- if (sym.needsCopy ) {
1618- if (sym.isObject ()) {
1619- addCopyRelSymbol (cast<SharedSymbol>(sym));
1620- // needsCopy is cleared for sym and its aliases so that in later
1621- // iterations aliases won't cause redundant copies.
1622- assert (!sym.needsCopy );
1623- } else {
1624- assert (sym.isFunc () && sym.needsPlt );
1625- if (!sym.isDefined ()) {
1626- replaceWithDefined (
1627- sym, in.plt ,
1628- target->pltHeaderSize + target->pltEntrySize * sym.pltIndex , 0 );
1629- sym.needsCopy = true ;
1630- if (config->emachine == EM_PPC) {
1631- // PPC32 canonical PLT entries are at the beginning of .glink
1632- cast<Defined>(sym).value = in.plt ->headerSize ;
1633- in.plt ->headerSize += 16 ;
1634- cast<PPC32GlinkSection>(in.plt )->canonical_plts .push_back (&sym);
1635- }
1636- }
1637- }
1638- }
1639- };
1640- for (Symbol *sym : symtab->symbols ())
1641- fn (*sym);
1642-
1643- // Local symbols may need the aforementioned non-preemptible ifunc and GOT
1644- // handling. They don't need regular PLT.
1645- for (InputFile *file : objectFiles)
1646- for (Symbol *sym : cast<ELFFileBase>(file)->getLocalSymbols ())
1647- fn (*sym);
1648- }
1649-
16501618static bool mergeCmp (const InputSection *a, const InputSection *b) {
16511619 // std::merge requires a strict weak ordering.
16521620 if (a->outSecOff < b->outSecOff )
0 commit comments