RuntimeDyldCOFF.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //===-- RuntimeDyldCOFF.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-==//
  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. // Implementation of COFF support for the MC-JIT runtime dynamic linker.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "RuntimeDyldCOFF.h"
  13. #include "Targets/RuntimeDyldCOFFAArch64.h"
  14. #include "Targets/RuntimeDyldCOFFI386.h"
  15. #include "Targets/RuntimeDyldCOFFThumb.h"
  16. #include "Targets/RuntimeDyldCOFFX86_64.h"
  17. #include "llvm/ADT/STLExtras.h"
  18. #include "llvm/ADT/Triple.h"
  19. #include "llvm/Object/ObjectFile.h"
  20. #include "llvm/Support/FormatVariadic.h"
  21. using namespace llvm;
  22. using namespace llvm::object;
  23. #define DEBUG_TYPE "dyld"
  24. namespace {
  25. class LoadedCOFFObjectInfo final
  26. : public LoadedObjectInfoHelper<LoadedCOFFObjectInfo,
  27. RuntimeDyld::LoadedObjectInfo> {
  28. public:
  29. LoadedCOFFObjectInfo(
  30. RuntimeDyldImpl &RTDyld,
  31. RuntimeDyld::LoadedObjectInfo::ObjSectionToIDMap ObjSecToIDMap)
  32. : LoadedObjectInfoHelper(RTDyld, std::move(ObjSecToIDMap)) {}
  33. OwningBinary<ObjectFile>
  34. getObjectForDebug(const ObjectFile &Obj) const override {
  35. return OwningBinary<ObjectFile>();
  36. }
  37. };
  38. }
  39. namespace llvm {
  40. std::unique_ptr<RuntimeDyldCOFF>
  41. llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,
  42. RuntimeDyld::MemoryManager &MemMgr,
  43. JITSymbolResolver &Resolver) {
  44. switch (Arch) {
  45. default: llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");
  46. case Triple::x86:
  47. return std::make_unique<RuntimeDyldCOFFI386>(MemMgr, Resolver);
  48. case Triple::thumb:
  49. return std::make_unique<RuntimeDyldCOFFThumb>(MemMgr, Resolver);
  50. case Triple::x86_64:
  51. return std::make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);
  52. case Triple::aarch64:
  53. return std::make_unique<RuntimeDyldCOFFAArch64>(MemMgr, Resolver);
  54. }
  55. }
  56. std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
  57. RuntimeDyldCOFF::loadObject(const object::ObjectFile &O) {
  58. if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) {
  59. return std::make_unique<LoadedCOFFObjectInfo>(*this, *ObjSectionToIDOrErr);
  60. } else {
  61. HasError = true;
  62. raw_string_ostream ErrStream(ErrorStr);
  63. logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream);
  64. return nullptr;
  65. }
  66. }
  67. uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) {
  68. // The value in a relocatable COFF object is the offset.
  69. return cantFail(Sym.getValue());
  70. }
  71. uint64_t RuntimeDyldCOFF::getDLLImportOffset(unsigned SectionID, StubMap &Stubs,
  72. StringRef Name,
  73. bool SetSectionIDMinus1) {
  74. LLVM_DEBUG(dbgs() << "Getting DLLImport entry for " << Name << "... ");
  75. assert(Name.startswith(getImportSymbolPrefix()) && "Not a DLLImport symbol?");
  76. RelocationValueRef Reloc;
  77. Reloc.SymbolName = Name.data();
  78. auto I = Stubs.find(Reloc);
  79. if (I != Stubs.end()) {
  80. LLVM_DEBUG(dbgs() << format("{0:x8}", I->second) << "\n");
  81. return I->second;
  82. }
  83. assert(SectionID < Sections.size() && "SectionID out of range");
  84. auto &Sec = Sections[SectionID];
  85. auto EntryOffset = alignTo(Sec.getStubOffset(), PointerSize);
  86. Sec.advanceStubOffset(EntryOffset + PointerSize - Sec.getStubOffset());
  87. Stubs[Reloc] = EntryOffset;
  88. RelocationEntry RE(SectionID, EntryOffset, PointerReloc, 0, false,
  89. Log2_64(PointerSize));
  90. // Hack to tell I386/Thumb resolveRelocation that this isn't section relative.
  91. if (SetSectionIDMinus1)
  92. RE.Sections.SectionA = -1;
  93. addRelocationForSymbol(RE, Name.drop_front(getImportSymbolPrefix().size()));
  94. LLVM_DEBUG({
  95. dbgs() << "Creating entry at "
  96. << formatv("{0:x16} + {1:x8} ( {2:x16} )", Sec.getLoadAddress(),
  97. EntryOffset, Sec.getLoadAddress() + EntryOffset)
  98. << "\n";
  99. });
  100. return EntryOffset;
  101. }
  102. bool RuntimeDyldCOFF::isCompatibleFile(const object::ObjectFile &Obj) const {
  103. return Obj.isCOFF();
  104. }
  105. } // namespace llvm