ELF_x86_64.cpp 15 KB

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