brintos

brintos / llvm-project-archived public Read only

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