13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
22 #define DEBUG_TYPE "jitlink"
42 return *CommonSection;
45 std::unique_ptr<LinkGraph>
G;
51 Section *CommonSection =
nullptr;
56 template <
typename ELFT>
116 template <
typename RelocHandlerFunction>
118 RelocHandlerFunction &&Func,
119 bool ProcessDebugSections =
false);
124 template <
typename ClassT,
typename RelocHandlerMethod>
126 RelocHandlerMethod &&Method,
127 bool ProcessDebugSections =
false) {
130 [Instance, Method](
const auto &Rel,
const auto &
Target,
auto &
GS) {
131 return (Instance->*Method)(Rel,
Target,
GS);
133 ProcessDebugSections);
146 DenseMap<
const typename ELFFile::Elf_Shdr *,
151 template <
typename ELFT>
156 FileName.str(),
Triple(
std::
move(TT)), ELFT::Is64Bits ? 8 : 4,
161 {
dbgs() <<
"Created ELFLinkGraphBuilder for \"" << FileName <<
"\""; });
164 template <
typename ELFT>
166 if (!isRelocatable())
167 return make_error<JITLinkError>(
"Object is not a relocatable ELF file");
169 if (
auto Err = prepare())
172 if (
auto Err = graphifySections())
175 if (
auto Err = graphifySymbols())
178 if (
auto Err = addRelocations())
184 template <
typename ELFT>
191 switch (Sym.getBinding()) {
203 return make_error<StringError>(
204 "Unrecognized symbol binding " +
205 Twine(
static_cast<int>(Sym.getBinding())) +
" for " +
Name,
209 switch (Sym.getVisibility()) {
222 return make_error<StringError>(
223 "Unrecognized symbol visibility " +
224 Twine(
static_cast<int>(Sym.getVisibility())) +
" for " +
Name,
228 return std::make_pair(L,
S);
235 if (
auto SectionsOrErr = Obj.sections())
236 Sections = *SectionsOrErr;
238 return SectionsOrErr.takeError();
241 if (
auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
242 SectionStringTab = *SectionStringTabOrErr;
244 return SectionStringTabOrErr.takeError();
247 for (
auto &Sec : Sections) {
252 return make_error<JITLinkError>(
"Multiple SHT_SYMTAB sections in " +
259 if (SymtabNdx >= Sections.size())
260 return make_error<JITLinkError>(
"sh_link is out of bound");
262 auto ShndxTable = Obj.getSHNDXTable(Sec);
264 return ShndxTable.takeError();
266 ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
270 return Error::success();
277 for (
ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
279 auto &Sec = Sections[SecIndex];
282 auto Name = Obj.getSectionName(Sec, SectionStringTab);
284 return Name.takeError();
290 dbgs() <<
" " << SecIndex <<
": \"" << *
Name
291 <<
"\" is a debug section: "
292 "No graph section will be created.\n";
300 dbgs() <<
" " << SecIndex <<
": \"" << *
Name
301 <<
"\" is not an SHF_ALLOC section: "
302 "No graph section will be created.\n";
308 dbgs() <<
" " << SecIndex <<
": Creating section for \"" << *
Name
315 Prot = MemProt::Read | MemProt::Exec;
317 Prot = MemProt::Read | MemProt::Write;
320 auto *GraphSec =
G->findSectionByName(*
Name);
322 GraphSec = &
G->createSection(*
Name, Prot);
323 assert(GraphSec->getMemProt() == Prot &&
"MemProt should match");
327 auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
329 return Data.takeError();
331 B = &
G->createContentBlock(*GraphSec, *
Data,
333 Sec.sh_addralign, 0);
335 B = &
G->createZeroFillBlock(*GraphSec, Sec.sh_size,
337 Sec.sh_addralign, 0);
339 setGraphBlock(SecIndex,
B);
342 return Error::success();
350 return Error::success();
353 auto Symbols = Obj.symbols(SymTabSec);
355 return Symbols.takeError();
358 auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
360 return StringTab.takeError();
365 if (
auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
366 SymTabName = *SymTabNameOrErr;
368 dbgs() <<
"Could not get ELF SHT_SYMTAB section name for logging: "
369 << toString(SymTabNameOrErr.takeError()) <<
"\n";
370 SymTabName =
"<SHT_SYMTAB section with invalid name>";
373 dbgs() <<
" Adding symbols from symtab section \"" << SymTabName
377 for (
ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
378 auto &Sym = (*Symbols)[SymIndex];
381 switch (Sym.getType()) {
384 if (
auto Name = Sym.getName(*StringTab))
385 dbgs() <<
" " << SymIndex <<
": Skipping STT_FILE symbol \""
388 dbgs() <<
"Could not get STT_FILE symbol name: "
390 dbgs() <<
" " << SymIndex
391 <<
": Skipping STT_FILE symbol with invalid name\n";
399 auto Name = Sym.getName(*StringTab);
401 return Name.takeError();
404 if (Sym.isCommon()) {
407 Sym.st_size, Sym.
getValue(),
false);
408 setGraphSymbol(SymIndex, GSym);
416 if (
auto LSOrErr = getSymbolLinkageAndScope(Sym, *
Name))
417 std::tie(L,
S) = *LSOrErr;
419 return LSOrErr.takeError();
421 if (Sym.isDefined() &&
426 unsigned Shndx = Sym.st_shndx;
428 auto ShndxTable = ShndxTables.find(SymTabSec);
429 if (ShndxTable == ShndxTables.end())
431 auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
432 Sym, SymIndex, ShndxTable->second);
434 return NdxOrErr.takeError();
437 if (
auto *
B = getGraphBlock(Shndx)) {
439 dbgs() <<
" " << SymIndex
440 <<
": Creating defined graph symbol for ELF symbol \"" << *
Name
451 ?
G->addAnonymousSymbol(*
B, Sym.getValue(), Sym.st_size,
453 :
G->addDefinedSymbol(*
B, Sym.getValue(), *
Name, Sym.st_size, L,
455 setGraphSymbol(SymIndex, GSym);
457 }
else if (Sym.isUndefined() && Sym.isExternal()) {
459 dbgs() <<
" " << SymIndex
460 <<
": Creating external graph symbol for ELF symbol \"" << *
Name
463 auto &GSym =
G->addExternalSymbol(*
Name, Sym.st_size, L);
464 setGraphSymbol(SymIndex, GSym);
467 dbgs() <<
" " << SymIndex
468 <<
": Not creating graph symbol for ELF symbol \"" << *
Name
469 <<
"\" with unrecognized type\n";
474 return Error::success();
477 template <
typename ELFT>
478 template <
typename RelocHandlerFunction>
480 const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
481 bool ProcessDebugSections) {
485 return Error::success();
489 auto FixupSection = Obj.getSection(RelSect.sh_info);
491 return FixupSection.takeError();
496 return Name.takeError();
502 return Error::success();
506 auto *BlockToFix = getGraphBlock(RelSect.sh_info);
508 return make_error<StringError>(
509 "Refencing a section that wasn't added to the graph: " + *
Name,
512 auto RelEntries = Obj.relas(RelSect);
514 return RelEntries.takeError();
517 for (
const typename ELFT::Rela &
R : *RelEntries)
518 if (
Error Err = Func(
R, **FixupSection, *BlockToFix))
522 return Error::success();
530 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H