ELF_x86_64.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //===---- ELF_x86_64.cpp -JIT linker implementation for ELF/x86-64 ----===//
  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/x86-64 jit-link implementation.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
  13. #include "llvm/ExecutionEngine/JITLink/DWARFRecordSectionSplitter.h"
  14. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  15. #include "llvm/ExecutionEngine/JITLink/TableManager.h"
  16. #include "llvm/ExecutionEngine/JITLink/x86_64.h"
  17. #include "llvm/Object/ELFObjectFile.h"
  18. #include "llvm/Support/Endian.h"
  19. #include "DefineExternalSectionStartAndEndSymbols.h"
  20. #include "EHFrameSupportImpl.h"
  21. #include "ELFLinkGraphBuilder.h"
  22. #include "JITLinkGeneric.h"
  23. #define DEBUG_TYPE "jitlink"
  24. using namespace llvm;
  25. using namespace llvm::jitlink;
  26. namespace {
  27. constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";
  28. constexpr StringRef ELFTLSInfoSectionName = "$__TLSINFO";
  29. class TLSInfoTableManager_ELF_x86_64
  30. : public TableManager<TLSInfoTableManager_ELF_x86_64> {
  31. public:
  32. static const uint8_t TLSInfoEntryContent[16];
  33. static StringRef getSectionName() { return ELFTLSInfoSectionName; }
  34. bool visitEdge(LinkGraph &G, Block *B, Edge &E) {
  35. if (E.getKind() == x86_64::RequestTLSDescInGOTAndTransformToDelta32) {
  36. LLVM_DEBUG({
  37. dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
  38. << formatv("{0:x}", B->getFixupAddress(E)) << " ("
  39. << formatv("{0:x}", B->getAddress()) << " + "
  40. << formatv("{0:x}", E.getOffset()) << ")\n";
  41. });
  42. E.setKind(x86_64::Delta32);
  43. E.setTarget(getEntryForTarget(G, E.getTarget()));
  44. return true;
  45. }
  46. return false;
  47. }
  48. Symbol &createEntry(LinkGraph &G, Symbol &Target) {
  49. // the TLS Info entry's key value will be written by the fixTLVSectionByName
  50. // pass, so create mutable content.
  51. auto &TLSInfoEntry = G.createMutableContentBlock(
  52. getTLSInfoSection(G), G.allocateContent(getTLSInfoEntryContent()),
  53. orc::ExecutorAddr(), 8, 0);
  54. TLSInfoEntry.addEdge(x86_64::Pointer64, 8, Target, 0);
  55. return G.addAnonymousSymbol(TLSInfoEntry, 0, 16, false, false);
  56. }
  57. private:
  58. Section &getTLSInfoSection(LinkGraph &G) {
  59. if (!TLSInfoTable)
  60. TLSInfoTable =
  61. &G.createSection(ELFTLSInfoSectionName, orc::MemProt::Read);
  62. return *TLSInfoTable;
  63. }
  64. ArrayRef<char> getTLSInfoEntryContent() const {
  65. return {reinterpret_cast<const char *>(TLSInfoEntryContent),
  66. sizeof(TLSInfoEntryContent)};
  67. }
  68. Section *TLSInfoTable = nullptr;
  69. };
  70. const uint8_t TLSInfoTableManager_ELF_x86_64::TLSInfoEntryContent[16] = {
  71. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*pthread key */
  72. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /*data address*/
  73. };
  74. Error buildTables_ELF_x86_64(LinkGraph &G) {
  75. LLVM_DEBUG(dbgs() << "Visiting edges in graph:\n");
  76. x86_64::GOTTableManager GOT;
  77. x86_64::PLTTableManager PLT(GOT);
  78. TLSInfoTableManager_ELF_x86_64 TLSInfo;
  79. visitExistingEdges(G, GOT, PLT, TLSInfo);
  80. return Error::success();
  81. }
  82. } // namespace
  83. namespace llvm {
  84. namespace jitlink {
  85. // This should become a template as the ELFFile is so a lot of this could become
  86. // generic
  87. class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder<object::ELF64LE> {
  88. private:
  89. using ELFT = object::ELF64LE;
  90. enum ELFX86RelocationKind : Edge::Kind {
  91. Branch32 = Edge::FirstRelocation,
  92. Pointer32Signed,
  93. Pointer64,
  94. PCRel32,
  95. PCRel32GOTLoad,
  96. PCRel32GOTLoadRelaxable,
  97. PCRel32REXGOTLoadRelaxable,
  98. PCRel32TLV,
  99. PCRel64GOT,
  100. GOTOFF64,
  101. GOT64,
  102. Delta64,
  103. };
  104. static Expected<ELFX86RelocationKind> getRelocationKind(const uint32_t Type) {
  105. switch (Type) {
  106. case ELF::R_X86_64_32S:
  107. return ELFX86RelocationKind::Pointer32Signed;
  108. case ELF::R_X86_64_PC32:
  109. return ELFX86RelocationKind::PCRel32;
  110. case ELF::R_X86_64_PC64:
  111. case ELF::R_X86_64_GOTPC64:
  112. return ELFX86RelocationKind::Delta64;
  113. case ELF::R_X86_64_64:
  114. return ELFX86RelocationKind::Pointer64;
  115. case ELF::R_X86_64_GOTPCREL:
  116. return ELFX86RelocationKind::PCRel32GOTLoad;
  117. case ELF::R_X86_64_GOTPCRELX:
  118. return ELFX86RelocationKind::PCRel32GOTLoadRelaxable;
  119. case ELF::R_X86_64_REX_GOTPCRELX:
  120. return ELFX86RelocationKind::PCRel32REXGOTLoadRelaxable;
  121. case ELF::R_X86_64_GOTPCREL64:
  122. return ELFX86RelocationKind::PCRel64GOT;
  123. case ELF::R_X86_64_GOT64:
  124. return ELFX86RelocationKind::GOT64;
  125. case ELF::R_X86_64_GOTOFF64:
  126. return ELFX86RelocationKind::GOTOFF64;
  127. case ELF::R_X86_64_PLT32:
  128. return ELFX86RelocationKind::Branch32;
  129. case ELF::R_X86_64_TLSGD:
  130. return ELFX86RelocationKind::PCRel32TLV;
  131. }
  132. return make_error<JITLinkError>(
  133. "Unsupported x86-64 relocation type " + formatv("{0:d}: ", Type) +
  134. object::getELFRelocationTypeName(ELF::EM_X86_64, Type));
  135. }
  136. Error addRelocations() override {
  137. LLVM_DEBUG(dbgs() << "Processing relocations:\n");
  138. using Base = ELFLinkGraphBuilder<ELFT>;
  139. using Self = ELFLinkGraphBuilder_x86_64;
  140. for (const auto &RelSect : Base::Sections) {
  141. // Validate the section to read relocation entries from.
  142. if (RelSect.sh_type == ELF::SHT_REL)
  143. return make_error<StringError>(
  144. "No SHT_REL in valid x64 ELF object files",
  145. inconvertibleErrorCode());
  146. if (Error Err = Base::forEachRelaRelocation(RelSect, this,
  147. &Self::addSingleRelocation))
  148. return Err;
  149. }
  150. return Error::success();
  151. }
  152. Error addSingleRelocation(const typename ELFT::Rela &Rel,
  153. const typename ELFT::Shdr &FixupSection,
  154. Block &BlockToFix) {
  155. using Base = ELFLinkGraphBuilder<ELFT>;
  156. uint32_t SymbolIndex = Rel.getSymbol(false);
  157. auto ObjSymbol = Base::Obj.getRelocationSymbol(Rel, Base::SymTabSec);
  158. if (!ObjSymbol)
  159. return ObjSymbol.takeError();
  160. Symbol *GraphSymbol = Base::getGraphSymbol(SymbolIndex);
  161. if (!GraphSymbol)
  162. return make_error<StringError>(
  163. formatv("Could not find symbol at given index, did you add it to "
  164. "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",
  165. SymbolIndex, (*ObjSymbol)->st_shndx,
  166. Base::GraphSymbols.size()),
  167. inconvertibleErrorCode());
  168. // Validate the relocation kind.
  169. auto ELFRelocKind = getRelocationKind(Rel.getType(false));
  170. if (!ELFRelocKind)
  171. return ELFRelocKind.takeError();
  172. int64_t Addend = Rel.r_addend;
  173. Edge::Kind Kind = Edge::Invalid;
  174. switch (*ELFRelocKind) {
  175. case PCRel32:
  176. Kind = x86_64::Delta32;
  177. break;
  178. case Delta64:
  179. Kind = x86_64::Delta64;
  180. break;
  181. case Pointer32Signed:
  182. Kind = x86_64::Pointer32Signed;
  183. break;
  184. case Pointer64:
  185. Kind = x86_64::Pointer64;
  186. break;
  187. case PCRel32GOTLoad: {
  188. Kind = x86_64::RequestGOTAndTransformToDelta32;
  189. break;
  190. }
  191. case PCRel32REXGOTLoadRelaxable: {
  192. Kind = x86_64::RequestGOTAndTransformToPCRel32GOTLoadREXRelaxable;
  193. Addend = 0;
  194. break;
  195. }
  196. case PCRel32TLV: {
  197. Kind = x86_64::RequestTLSDescInGOTAndTransformToDelta32;
  198. break;
  199. }
  200. case PCRel32GOTLoadRelaxable: {
  201. Kind = x86_64::RequestGOTAndTransformToPCRel32GOTLoadRelaxable;
  202. Addend = 0;
  203. break;
  204. }
  205. case PCRel64GOT: {
  206. Kind = x86_64::RequestGOTAndTransformToDelta64;
  207. break;
  208. }
  209. case GOT64: {
  210. Kind = x86_64::RequestGOTAndTransformToDelta64FromGOT;
  211. break;
  212. }
  213. case GOTOFF64: {
  214. Kind = x86_64::Delta64FromGOT;
  215. break;
  216. }
  217. case Branch32: {
  218. Kind = x86_64::BranchPCRel32;
  219. // BranchPCRel32 implicitly handles the '-4' PC adjustment, so we have to
  220. // adjust the addend by '+4' to compensate.
  221. Addend += 4;
  222. break;
  223. }
  224. }
  225. auto FixupAddress = orc::ExecutorAddr(FixupSection.sh_addr) + Rel.r_offset;
  226. Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();
  227. Edge GE(Kind, Offset, *GraphSymbol, Addend);
  228. LLVM_DEBUG({
  229. dbgs() << " ";
  230. printEdge(dbgs(), BlockToFix, GE, x86_64::getEdgeKindName(Kind));
  231. dbgs() << "\n";
  232. });
  233. BlockToFix.addEdge(std::move(GE));
  234. return Error::success();
  235. }
  236. public:
  237. ELFLinkGraphBuilder_x86_64(StringRef FileName,
  238. const object::ELFFile<object::ELF64LE> &Obj)
  239. : ELFLinkGraphBuilder(Obj, Triple("x86_64-unknown-linux"), FileName,
  240. x86_64::getEdgeKindName) {}
  241. };
  242. class ELFJITLinker_x86_64 : public JITLinker<ELFJITLinker_x86_64> {
  243. friend class JITLinker<ELFJITLinker_x86_64>;
  244. public:
  245. ELFJITLinker_x86_64(std::unique_ptr<JITLinkContext> Ctx,
  246. std::unique_ptr<LinkGraph> G,
  247. PassConfiguration PassConfig)
  248. : JITLinker(std::move(Ctx), std::move(G), std::move(PassConfig)) {
  249. getPassConfig().PostAllocationPasses.push_back(
  250. [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });
  251. }
  252. private:
  253. Symbol *GOTSymbol = nullptr;
  254. Error getOrCreateGOTSymbol(LinkGraph &G) {
  255. auto DefineExternalGOTSymbolIfPresent =
  256. createDefineExternalSectionStartAndEndSymbolsPass(
  257. [&](LinkGraph &LG, Symbol &Sym) -> SectionRangeSymbolDesc {
  258. if (Sym.getName() == ELFGOTSymbolName)
  259. if (auto *GOTSection = G.findSectionByName(
  260. x86_64::GOTTableManager::getSectionName())) {
  261. GOTSymbol = &Sym;
  262. return {*GOTSection, true};
  263. }
  264. return {};
  265. });
  266. // Try to attach _GLOBAL_OFFSET_TABLE_ to the GOT if it's defined as an
  267. // external.
  268. if (auto Err = DefineExternalGOTSymbolIfPresent(G))
  269. return Err;
  270. // If we succeeded then we're done.
  271. if (GOTSymbol)
  272. return Error::success();
  273. // Otherwise look for a GOT section: If it already has a start symbol we'll
  274. // record it, otherwise we'll create our own.
  275. // If there's a GOT section but we didn't find an external GOT symbol...
  276. if (auto *GOTSection =
  277. G.findSectionByName(x86_64::GOTTableManager::getSectionName())) {
  278. // Check for an existing defined symbol.
  279. for (auto *Sym : GOTSection->symbols())
  280. if (Sym->getName() == ELFGOTSymbolName) {
  281. GOTSymbol = Sym;
  282. return Error::success();
  283. }
  284. // If there's no defined symbol then create one.
  285. SectionRange SR(*GOTSection);
  286. if (SR.empty())
  287. GOTSymbol =
  288. &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,
  289. Linkage::Strong, Scope::Local, true);
  290. else
  291. GOTSymbol =
  292. &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,
  293. Linkage::Strong, Scope::Local, false, true);
  294. }
  295. return Error::success();
  296. }
  297. Error applyFixup(LinkGraph &G, Block &B, const Edge &E) const {
  298. return x86_64::applyFixup(G, B, E, GOTSymbol);
  299. }
  300. };
  301. Expected<std::unique_ptr<LinkGraph>>
  302. createLinkGraphFromELFObject_x86_64(MemoryBufferRef ObjectBuffer) {
  303. LLVM_DEBUG({
  304. dbgs() << "Building jitlink graph for new input "
  305. << ObjectBuffer.getBufferIdentifier() << "...\n";
  306. });
  307. auto ELFObj = object::ObjectFile::createELFObjectFile(ObjectBuffer);
  308. if (!ELFObj)
  309. return ELFObj.takeError();
  310. auto &ELFObjFile = cast<object::ELFObjectFile<object::ELF64LE>>(**ELFObj);
  311. return ELFLinkGraphBuilder_x86_64((*ELFObj)->getFileName(),
  312. ELFObjFile.getELFFile())
  313. .buildGraph();
  314. }
  315. static SectionRangeSymbolDesc
  316. identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym) {
  317. constexpr StringRef StartSymbolPrefix = "__start";
  318. constexpr StringRef EndSymbolPrefix = "__end";
  319. auto SymName = Sym.getName();
  320. if (SymName.startswith(StartSymbolPrefix)) {
  321. if (auto *Sec =
  322. G.findSectionByName(SymName.drop_front(StartSymbolPrefix.size())))
  323. return {*Sec, true};
  324. } else if (SymName.startswith(EndSymbolPrefix)) {
  325. if (auto *Sec =
  326. G.findSectionByName(SymName.drop_front(EndSymbolPrefix.size())))
  327. return {*Sec, false};
  328. }
  329. return {};
  330. }
  331. void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
  332. std::unique_ptr<JITLinkContext> Ctx) {
  333. PassConfiguration Config;
  334. if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) {
  335. Config.PrePrunePasses.push_back(DWARFRecordSectionSplitter(".eh_frame"));
  336. Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
  337. ".eh_frame", x86_64::PointerSize, x86_64::Pointer32, x86_64::Pointer64,
  338. x86_64::Delta32, x86_64::Delta64, x86_64::NegDelta32));
  339. Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame"));
  340. // Construct a JITLinker and run the link function.
  341. // Add a mark-live pass.
  342. if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple()))
  343. Config.PrePrunePasses.push_back(std::move(MarkLive));
  344. else
  345. Config.PrePrunePasses.push_back(markAllSymbolsLive);
  346. // Add an in-place GOT/Stubs/TLSInfoEntry build pass.
  347. Config.PostPrunePasses.push_back(buildTables_ELF_x86_64);
  348. // Resolve any external section start / end symbols.
  349. Config.PostAllocationPasses.push_back(
  350. createDefineExternalSectionStartAndEndSymbolsPass(
  351. identifyELFSectionStartAndEndSymbols));
  352. // Add GOT/Stubs optimizer pass.
  353. Config.PreFixupPasses.push_back(x86_64::optimizeGOTAndStubAccesses);
  354. }
  355. if (auto Err = Ctx->modifyPassConfig(*G, Config))
  356. return Ctx->notifyFailed(std::move(Err));
  357. ELFJITLinker_x86_64::link(std::move(Ctx), std::move(G), std::move(Config));
  358. }
  359. } // end namespace jitlink
  360. } // end namespace llvm