Skip to content

Commit 3faf3ae

Browse files
committed
[PPC][BOLT] Compute PPC64 ELFv2 TOC base as .got + 0x8000
According to the ELFv2 ABI, the TOC base register (r2) point to the address .got + 0x8000. This patch computes the correct TOC base when processing PPC64 binaries and uses it to anchor TOC-relative relocations. This resolves warnings such as: "ignoring symbol .TOC. at 0x10027f00, which lies outside .got"
1 parent 966b070 commit 3faf3ae

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

bolt/include/bolt/Rewrite/RewriteInstance.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,14 @@ class RewriteInstance {
517517
/// Flag indicating runtime library linking just started.
518518
bool StartLinkingRuntimeLib{false};
519519

520+
/// PPC64 TOC (Table of Contents) base address used for resolving function and
521+
/// data references on PPC64 binaries. Set when processing PPC64 binaries with
522+
/// a TOC base present.
523+
uint64_t PPC64TOCBase = 0;
524+
525+
/// Flag indicating whether PPC64TOCBase has been set and is valid for use.
526+
bool HavePPC64TOCBase = false;
527+
520528
/// Information on special Procedure Linkage Table sections. There are
521529
/// multiple variants generated by different linkers.
522530
struct PLTSectionInfo {

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,19 @@ Error RewriteInstance::run() {
743743
adjustCommandLineOptions();
744744
discoverFileObjects();
745745

746+
if (BC->isPPC64()) {
747+
if (const auto *G = BC->getUniqueSectionByName(".got")) {
748+
PPC64TOCBase = G->getAddress() + 0x8000; // ELFv2 ABI
749+
HavePPC64TOCBase = true;
750+
if (opts::Verbosity >= 1)
751+
BC->outs() << "BOLT-INFO: PPC64 TOC base: 0x"
752+
<< Twine::utohexstr(PPC64TOCBase) << "\n";
753+
} else if (opts::Verbosity >= 1) {
754+
BC->errs()
755+
<< "BOLT-WARNING: .got not found; PPC64 TOC base unavailable\n";
756+
}
757+
}
758+
746759
if (opts::Instrument && !BC->IsStaticExecutable)
747760
if (Error E = discoverRtFiniAddress())
748761
return E;
@@ -2415,6 +2428,22 @@ bool RewriteInstance::analyzeRelocation(
24152428
SkipVerification |= (*TypeOrErr == SymbolRef::ST_Other);
24162429
IsSectionRelocation = (*TypeOrErr == SymbolRef::ST_Debug);
24172430
}
2431+
2432+
if (HavePPC64TOCBase) {
2433+
switch (RType) {
2434+
case ELF::R_PPC64_TOC16:
2435+
case ELF::R_PPC64_TOC16_LO:
2436+
case ELF::R_PPC64_TOC16_HI:
2437+
case ELF::R_PPC64_TOC16_HA:
2438+
case ELF::R_PPC64_TOC16_DS:
2439+
case ELF::R_PPC64_TOC16_LO_DS:
2440+
SymbolAddress = PPC64TOCBase;
2441+
break;
2442+
default:
2443+
break;
2444+
}
2445+
}
2446+
24182447
} else {
24192448
// --- Original fast path for other arches ---
24202449
SymbolName = std::string(cantFail(Symbol.getName()));

bolt/lib/Target/PowerPC/PPCMCPlusBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,24 @@ PPCMCPlusBuilder::createRelocation(const MCFixup &Fixup,
406406
return R;
407407
}
408408

409+
if (L.find("toc16_lo_ds") != std::string::npos) {
410+
// TOC16_LO_DS can be optimized to R_GOTREL if tocOptimize is on
411+
R.Type = ELF::R_PPC64_TOC16_LO_DS;
412+
return R;
413+
}
414+
if (L.find("toc16_ds") != std::string::npos) {
415+
R.Type = ELF::R_PPC64_TOC16_DS;
416+
return R;
417+
}
418+
if (L.find("addr16_lo_ds") != std::string::npos) {
419+
R.Type = ELF::R_PPC64_ADDR16_LO_DS;
420+
return R;
421+
}
422+
if (L.find("addr16_ds") != std::string::npos) {
423+
R.Type = ELF::R_PPC64_ADDR16_DS;
424+
return R;
425+
}
426+
409427
// --- Fallback heuristic: use PCRel + bit-size ---
410428
if (Fixup.isPCRel()) {
411429
switch (FKI.TargetSize) {

0 commit comments

Comments
 (0)