RuntimeDyldCOFFX86_64.h revision 302408
117680Spst//===-- RuntimeDyldCOFFX86_64.h --- COFF/X86_64 specific code ---*- C++ -*-===// 217680Spst// 317680Spst// The LLVM Compiler Infrastructure 417680Spst// 517680Spst// This file is distributed under the University of Illinois Open Source 617680Spst// License. See LICENSE.TXT for details. 717680Spst// 817680Spst//===----------------------------------------------------------------------===// 917680Spst// 1017680Spst// COFF x86_x64 support for MC-JIT runtime dynamic linker. 1117680Spst// 1217680Spst//===----------------------------------------------------------------------===// 1317680Spst 1417680Spst#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H 1517680Spst#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H 1617680Spst 1717680Spst#include "llvm/Object/COFF.h" 1817680Spst#include "llvm/Support/COFF.h" 1917680Spst#include "../RuntimeDyldCOFF.h" 2017680Spst 2117680Spst#define DEBUG_TYPE "dyld" 2217680Spst 2317680Spstnamespace llvm { 2417680Spst 2517680Spstclass RuntimeDyldCOFFX86_64 : public RuntimeDyldCOFF { 2617680Spst 2717680Spstprivate: 2817680Spst // When a module is loaded we save the SectionID of the unwind 2917680Spst // sections in a table until we receive a request to register all 3017680Spst // unregisteredEH frame sections with the memory manager. 3117680Spst SmallVector<SID, 2> UnregisteredEHFrameSections; 3217680Spst SmallVector<SID, 2> RegisteredEHFrameSections; 3317680Spst 3417680Spstpublic: 3517680Spst RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM, 3617680Spst RuntimeDyld::SymbolResolver &Resolver) 3717680Spst : RuntimeDyldCOFF(MM, Resolver) {} 3817680Spst 3917680Spst unsigned getMaxStubSize() override { 4017680Spst return 6; // 2-byte jmp instruction + 32-bit relative address 4117680Spst } 4217680Spst 4317680Spst // The target location for the relocation is described by RE.SectionID and 4417680Spst // RE.Offset. RE.SectionID can be used to find the SectionEntry. Each 4517680Spst // SectionEntry has three members describing its location. 4617680Spst // SectionEntry::Address is the address at which the section has been loaded 4717680Spst // into memory in the current (host) process. SectionEntry::LoadAddress is 4817680Spst // the address that the section will have in the target process. 4917680Spst // SectionEntry::ObjAddress is the address of the bits for this section in the 5017680Spst // original emitted object image (also in the current address space). 5117680Spst // 5217680Spst // Relocations will be applied as if the section were loaded at 5317680Spst // SectionEntry::LoadAddress, but they will be applied at an address based 5417680Spst // on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer 5517680Spst // to Target memory contents if they are required for value calculations. 5617680Spst // 5717680Spst // The Value parameter here is the load address of the symbol for the 5817680Spst // relocation to be applied. For relocations which refer to symbols in the 5917680Spst // current object Value will be the LoadAddress of the section in which 6017680Spst // the symbol resides (RE.Addend provides additional information about the 6117680Spst // symbol location). For external symbols, Value will be the address of the 6217680Spst // symbol in the target address space. 6317680Spst void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override { 6417680Spst const SectionEntry &Section = Sections[RE.SectionID]; 6517680Spst uint8_t *Target = Section.getAddressWithOffset(RE.Offset); 6617680Spst 6717680Spst switch (RE.RelType) { 6817680Spst 6917680Spst case COFF::IMAGE_REL_AMD64_REL32: 7017680Spst case COFF::IMAGE_REL_AMD64_REL32_1: 7117680Spst case COFF::IMAGE_REL_AMD64_REL32_2: 7217680Spst case COFF::IMAGE_REL_AMD64_REL32_3: 7317680Spst case COFF::IMAGE_REL_AMD64_REL32_4: 7417680Spst case COFF::IMAGE_REL_AMD64_REL32_5: { 7517680Spst uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.Offset); 7617680Spst // Delta is the distance from the start of the reloc to the end of the 7717680Spst // instruction with the reloc. 7817680Spst uint64_t Delta = 4 + (RE.RelType - COFF::IMAGE_REL_AMD64_REL32); 7917680Spst Value -= FinalAddress + Delta; 8017680Spst uint64_t Result = Value + RE.Addend; 8117680Spst assert(((int64_t)Result <= INT32_MAX) && "Relocation overflow"); 8217680Spst assert(((int64_t)Result >= INT32_MIN) && "Relocation underflow"); 8317680Spst writeBytesUnaligned(Result, Target, 4); 8417680Spst break; 8517680Spst } 8617680Spst 8717680Spst case COFF::IMAGE_REL_AMD64_ADDR32NB: { 8817680Spst // Note ADDR32NB requires a well-established notion of 8917680Spst // image base. This address must be less than or equal 9017680Spst // to every section's load address, and all sections must be 9117680Spst // within a 32 bit offset from the base. 9217680Spst // 9317680Spst // For now we just set these to zero. 9417680Spst writeBytesUnaligned(0, Target, 4); 9517680Spst break; 9617680Spst } 9717680Spst 9817680Spst case COFF::IMAGE_REL_AMD64_ADDR64: { 9917680Spst writeBytesUnaligned(Value + RE.Addend, Target, 8); 10017680Spst break; 10117680Spst } 10217680Spst 10317680Spst default: 10417680Spst llvm_unreachable("Relocation type not implemented yet!"); 10517680Spst break; 10617680Spst } 10717680Spst } 10817680Spst 10917680Spst relocation_iterator processRelocationRef(unsigned SectionID, 110 relocation_iterator RelI, 111 const ObjectFile &Obj, 112 ObjSectionToIDMap &ObjSectionToID, 113 StubMap &Stubs) override { 114 // If possible, find the symbol referred to in the relocation, 115 // and the section that contains it. 116 symbol_iterator Symbol = RelI->getSymbol(); 117 if (Symbol == Obj.symbol_end()) 118 report_fatal_error("Unknown symbol in relocation"); 119 section_iterator SecI = *Symbol->getSection(); 120 // If there is no section, this must be an external reference. 121 const bool IsExtern = SecI == Obj.section_end(); 122 123 // Determine the Addend used to adjust the relocation value. 124 uint64_t RelType = RelI->getType(); 125 uint64_t Offset = RelI->getOffset(); 126 uint64_t Addend = 0; 127 SectionEntry &Section = Sections[SectionID]; 128 uintptr_t ObjTarget = Section.getObjAddress() + Offset; 129 130 switch (RelType) { 131 132 case COFF::IMAGE_REL_AMD64_REL32: 133 case COFF::IMAGE_REL_AMD64_REL32_1: 134 case COFF::IMAGE_REL_AMD64_REL32_2: 135 case COFF::IMAGE_REL_AMD64_REL32_3: 136 case COFF::IMAGE_REL_AMD64_REL32_4: 137 case COFF::IMAGE_REL_AMD64_REL32_5: 138 case COFF::IMAGE_REL_AMD64_ADDR32NB: { 139 uint8_t *Displacement = (uint8_t *)ObjTarget; 140 Addend = readBytesUnaligned(Displacement, 4); 141 break; 142 } 143 144 case COFF::IMAGE_REL_AMD64_ADDR64: { 145 uint8_t *Displacement = (uint8_t *)ObjTarget; 146 Addend = readBytesUnaligned(Displacement, 8); 147 break; 148 } 149 150 default: 151 break; 152 } 153 154 ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); 155 if (std::error_code EC = TargetNameOrErr.getError()) 156 report_fatal_error(EC.message()); 157 StringRef TargetName = *TargetNameOrErr; 158 159 DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset 160 << " RelType: " << RelType << " TargetName: " << TargetName 161 << " Addend " << Addend << "\n"); 162 163 if (IsExtern) { 164 RelocationEntry RE(SectionID, Offset, RelType, Addend); 165 addRelocationForSymbol(RE, TargetName); 166 } else { 167 bool IsCode = SecI->isText(); 168 unsigned TargetSectionID = 169 findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID); 170 uint64_t TargetOffset = getSymbolOffset(*Symbol); 171 RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend); 172 addRelocationForSection(RE, TargetSectionID); 173 } 174 175 return ++RelI; 176 } 177 178 unsigned getStubAlignment() override { return 1; } 179 void registerEHFrames() override { 180 for (auto const &EHFrameSID : UnregisteredEHFrameSections) { 181 uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress(); 182 uint64_t EHFrameLoadAddr = Sections[EHFrameSID].getLoadAddress(); 183 size_t EHFrameSize = Sections[EHFrameSID].getSize(); 184 MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize); 185 RegisteredEHFrameSections.push_back(EHFrameSID); 186 } 187 UnregisteredEHFrameSections.clear(); 188 } 189 void deregisterEHFrames() override { 190 // Stub 191 } 192 void finalizeLoad(const ObjectFile &Obj, 193 ObjSectionToIDMap &SectionMap) override { 194 // Look for and record the EH frame section IDs. 195 for (const auto &SectionPair : SectionMap) { 196 const SectionRef &Section = SectionPair.first; 197 StringRef Name; 198 Check(Section.getName(Name)); 199 // Note unwind info is split across .pdata and .xdata, so this 200 // may not be sufficiently general for all users. 201 if (Name == ".xdata") { 202 UnregisteredEHFrameSections.push_back(SectionPair.second); 203 } 204 } 205 } 206}; 207 208} // end namespace llvm 209 210#undef DEBUG_TYPE 211 212#endif 213