6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
//
9
- // This file contains platform-independent functions to process relocations.
10
- // I'll describe the overview of this file here.
9
+ // This file implements the core relocation processing logic. It analyzes
10
+ // relocations and determines what auxiliary data structures (GOT, PLT, copy
11
+ // relocations) need to be created during linking.
11
12
//
12
- // Simple relocations are easy to handle for the linker. For example,
13
- // for R_X86_64_PC64 relocs, the linker just has to fix up locations
14
- // with the relative offsets to the target symbols. It would just be
15
- // reading records from relocation sections and applying them to output .
13
+ // The main entry point is scanRelocations<ELFT>(), which calls scanSection()
14
+ // to process all relocations within an input section. For each relocation,
15
+ // scan() analyzes the type and target, and determines whether a synthetic
16
+ // section entry or dynamic relocation is needed .
16
17
//
17
- // But not all relocations are that easy to handle. For example, for
18
- // R_386_GOTOFF relocs, the linker has to create new GOT entries for
19
- // symbols if they don't exist, and fix up locations with GOT entry
20
- // offsets from the beginning of GOT section. So there is more than
21
- // fixing addresses in relocation processing.
18
+ // Note: This file analyzes what needs to be done but doesn't apply the
19
+ // actual relocations - that happens later in InputSection::writeTo().
20
+ // Instead, it populates Relocation objects in InputSectionBase::relocations
21
+ // and creates necessary synthetic sections (GOT, PLT, etc.).
22
22
//
23
- // ELF defines a large number of complex relocations.
24
- //
25
- // The functions in this file analyze relocations and do whatever needs
26
- // to be done. It includes, but not limited to, the following.
27
- //
28
- // - create GOT/PLT entries
29
- // - create new relocations in .dynsym to let the dynamic linker resolve
30
- // them at runtime (since ELF supports dynamic linking, not all
31
- // relocations can be resolved at link-time)
32
- // - create COPY relocs and reserve space in .bss
33
- // - replace expensive relocs (in terms of runtime cost) with cheap ones
34
- // - error out infeasible combinations such as PIC and non-relative relocs
35
- //
36
- // Note that the functions in this file don't actually apply relocations
37
- // because it doesn't know about the output file nor the output file buffer.
38
- // It instead stores Relocation objects to InputSection's Relocations
39
- // vector to let it apply later in InputSection::writeTo.
23
+ // In addition, this file implements the core Thunk creation logic, called
24
+ // during finalizeAddressDependentContent().
40
25
//
41
26
// ===----------------------------------------------------------------------===//
42
27
@@ -466,14 +451,14 @@ class RelocationScanner {
466
451
int64_t computeMipsAddend (const RelTy &rel, RelExpr expr, bool isLocal) const ;
467
452
bool isStaticLinkTimeConstant (RelExpr e, RelType type, const Symbol &sym,
468
453
uint64_t relOff) const ;
469
- void processAux (RelExpr expr, RelType type, uint64_t offset, Symbol &sym,
470
- int64_t addend) const ;
454
+ void process (RelExpr expr, RelType type, uint64_t offset, Symbol &sym,
455
+ int64_t addend) const ;
471
456
unsigned handleTlsRelocation (RelExpr expr, RelType type, uint64_t offset,
472
457
Symbol &sym, int64_t addend);
473
458
474
459
template <class ELFT , class RelTy >
475
- void scanOne (typename Relocs<RelTy>::const_iterator &i);
476
- template <class ELFT , class RelTy > void scan (Relocs<RelTy> rels);
460
+ void scan (typename Relocs<RelTy>::const_iterator &i);
461
+ template <class ELFT , class RelTy > void scanSectionImpl (Relocs<RelTy> rels);
477
462
};
478
463
} // namespace
479
464
@@ -961,7 +946,7 @@ static bool canDefineSymbolInExecutable(Ctx &ctx, Symbol &sym) {
961
946
}
962
947
963
948
// Returns true if a given relocation can be computed at link-time.
964
- // This only handles relocation types expected in processAux .
949
+ // This only handles relocation types expected in process() .
965
950
//
966
951
// For instance, we know the offset from a relocation to its target at
967
952
// link-time if the relocation is PC-relative and refers a
@@ -1052,8 +1037,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
1052
1037
// sections. Given that it is ro, we will need an extra PT_LOAD. This
1053
1038
// complicates things for the dynamic linker and means we would have to reserve
1054
1039
// space for the extra PT_LOAD even if we end up not using it.
1055
- void RelocationScanner::processAux (RelExpr expr, RelType type, uint64_t offset,
1056
- Symbol &sym, int64_t addend) const {
1040
+ void RelocationScanner::process (RelExpr expr, RelType type, uint64_t offset,
1041
+ Symbol &sym, int64_t addend) const {
1057
1042
// If non-ifunc non-preemptible, change PLT to direct call and optimize GOT
1058
1043
// indirection.
1059
1044
const bool isIfunc = sym.isGnuIFunc ();
@@ -1493,7 +1478,7 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
1493
1478
}
1494
1479
1495
1480
template <class ELFT , class RelTy >
1496
- void RelocationScanner::scanOne (typename Relocs<RelTy>::const_iterator &i) {
1481
+ void RelocationScanner::scan (typename Relocs<RelTy>::const_iterator &i) {
1497
1482
const RelTy &rel = *i;
1498
1483
uint32_t symIndex = rel.getSymbol (ctx.arg .isMips64EL );
1499
1484
Symbol &sym = sec->getFile <ELFT>()->getSymbol (symIndex);
@@ -1587,7 +1572,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
1587
1572
}
1588
1573
1589
1574
// Process TLS relocations, including TLS optimizations. Note that
1590
- // R_TPREL and R_TPREL_NEG relocations are resolved in processAux .
1575
+ // R_TPREL and R_TPREL_NEG relocations are resolved in process() .
1591
1576
//
1592
1577
// Some RISCV TLSDESC relocations reference a local NOTYPE symbol,
1593
1578
// but we need to process them in handleTlsRelocation.
@@ -1599,7 +1584,7 @@ void RelocationScanner::scanOne(typename Relocs<RelTy>::const_iterator &i) {
1599
1584
}
1600
1585
}
1601
1586
1602
- processAux (expr, type, offset, sym, addend);
1587
+ process (expr, type, offset, sym, addend);
1603
1588
}
1604
1589
1605
1590
// R_PPC64_TLSGD/R_PPC64_TLSLD is required to mark `bl __tls_get_addr` for
@@ -1642,7 +1627,7 @@ static void checkPPC64TLSRelax(InputSectionBase &sec, Relocs<RelTy> rels) {
1642
1627
}
1643
1628
1644
1629
template <class ELFT , class RelTy >
1645
- void RelocationScanner::scan (Relocs<RelTy> rels) {
1630
+ void RelocationScanner::scanSectionImpl (Relocs<RelTy> rels) {
1646
1631
// Not all relocations end up in Sec->Relocations, but a lot do.
1647
1632
sec->relocations .reserve (rels.size ());
1648
1633
@@ -1660,12 +1645,12 @@ void RelocationScanner::scan(Relocs<RelTy> rels) {
1660
1645
1661
1646
if constexpr (RelTy::IsCrel) {
1662
1647
for (auto i = rels.begin (); i != rels.end ();)
1663
- scanOne <ELFT, RelTy>(i);
1648
+ scan <ELFT, RelTy>(i);
1664
1649
} else {
1665
1650
// The non-CREL code path has additional check for PPC64 TLS.
1666
1651
end = static_cast <const void *>(rels.end ());
1667
1652
for (auto i = rels.begin (); i != end;)
1668
- scanOne <ELFT, RelTy>(i);
1653
+ scan <ELFT, RelTy>(i);
1669
1654
}
1670
1655
1671
1656
// Sort relocations by offset for more efficient searching for
@@ -1686,11 +1671,11 @@ void RelocationScanner::scanSection(InputSectionBase &s, bool isEH) {
1686
1671
getter = OffsetGetter (s);
1687
1672
const RelsOrRelas<ELFT> rels = s.template relsOrRelas <ELFT>(!isEH);
1688
1673
if (rels.areRelocsCrel ())
1689
- scan <ELFT>(rels.crels );
1674
+ scanSectionImpl <ELFT>(rels.crels );
1690
1675
else if (rels.areRelocsRel ())
1691
- scan <ELFT>(rels.rels );
1676
+ scanSectionImpl <ELFT>(rels.rels );
1692
1677
else
1693
- scan <ELFT>(rels.relas );
1678
+ scanSectionImpl <ELFT>(rels.relas );
1694
1679
}
1695
1680
1696
1681
template <class ELFT > void elf::scanRelocations (Ctx &ctx) {
0 commit comments