1 //===---- llvm-jitlink-elf.cpp -- ELF parsing support for llvm-jitlink ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // ELF parsing support for llvm-jitlink. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm-jitlink.h" 14 15 #include "llvm/Support/Error.h" 16 #include "llvm/Support/Path.h" 17 18 #define DEBUG_TYPE "llvm_jitlink" 19 20 using namespace llvm; 21 using namespace llvm::jitlink; 22 23 namespace llvm { 24 25 Error registerELFGraphInfo(Session &S, LinkGraph &G) { 26 auto FileName = sys::path::filename(G.getName()); 27 if (S.FileInfos.count(FileName)) { 28 return make_error<StringError>("When -check is passed, file names must be " 29 "distinct (duplicate: \"" + 30 FileName + "\")", 31 inconvertibleErrorCode()); 32 } 33 34 auto &FileInfo = S.FileInfos[FileName]; 35 LLVM_DEBUG({ 36 dbgs() << "Registering ELF file info for \"" << FileName << "\"\n"; 37 }); 38 for (auto &Sec : G.sections()) { 39 LLVM_DEBUG({ 40 dbgs() << " Section \"" << Sec.getName() << "\": " 41 << (llvm::empty(Sec.symbols()) ? "empty. skipping." 42 : "processing...") 43 << "\n"; 44 }); 45 46 // Skip empty sections. 47 if (llvm::empty(Sec.symbols())) 48 continue; 49 50 if (FileInfo.SectionInfos.count(Sec.getName())) 51 return make_error<StringError>("Encountered duplicate section name \"" + 52 Sec.getName() + "\" in \"" + FileName + 53 "\"", 54 inconvertibleErrorCode()); 55 56 bool SectionContainsContent = false; 57 bool SectionContainsZeroFill = false; 58 59 auto *FirstSym = *Sec.symbols().begin(); 60 auto *LastSym = FirstSym; 61 for (auto *Sym : Sec.symbols()) { 62 if (Sym->getAddress() < FirstSym->getAddress()) 63 FirstSym = Sym; 64 if (Sym->getAddress() > LastSym->getAddress()) 65 LastSym = Sym; 66 67 if (Sym->hasName()) { 68 dbgs() << "Symbol: " << Sym->getName() << "\n"; 69 if (Sym->isSymbolZeroFill()) { 70 S.SymbolInfos[Sym->getName()] = {Sym->getSize(), Sym->getAddress()}; 71 SectionContainsZeroFill = true; 72 } else { 73 S.SymbolInfos[Sym->getName()] = {Sym->getSymbolContent(), 74 Sym->getAddress()}; 75 SectionContainsContent = true; 76 } 77 } 78 } 79 80 JITTargetAddress SecAddr = FirstSym->getAddress(); 81 uint64_t SecSize = 82 (LastSym->getBlock().getAddress() + LastSym->getBlock().getSize()) - 83 SecAddr; 84 85 if (SectionContainsZeroFill && SectionContainsContent) 86 return make_error<StringError>("Mixed zero-fill and content sections not " 87 "supported yet", 88 inconvertibleErrorCode()); 89 if (SectionContainsZeroFill) 90 FileInfo.SectionInfos[Sec.getName()] = {SecSize, SecAddr}; 91 else 92 FileInfo.SectionInfos[Sec.getName()] = { 93 StringRef(FirstSym->getBlock().getContent().data(), SecSize), 94 SecAddr}; 95 } 96 97 return Error::success(); 98 } 99 100 } // end namespace llvm 101