1*9880d681SAndroid Build Coastguard Worker //===--- RuntimeDyldCOFFI386.h --- COFF/X86_64 specific code ---*- C++ --*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // COFF x86 support for MC-JIT runtime dynamic linker. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H 15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFI386_H 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFF.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/COFF.h" 19*9880d681SAndroid Build Coastguard Worker #include "../RuntimeDyldCOFF.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "dyld" 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker namespace llvm { 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF { 26*9880d681SAndroid Build Coastguard Worker public: RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager & MM,RuntimeDyld::SymbolResolver & Resolver)27*9880d681SAndroid Build Coastguard Worker RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM, 28*9880d681SAndroid Build Coastguard Worker RuntimeDyld::SymbolResolver &Resolver) 29*9880d681SAndroid Build Coastguard Worker : RuntimeDyldCOFF(MM, Resolver) {} 30*9880d681SAndroid Build Coastguard Worker getMaxStubSize()31*9880d681SAndroid Build Coastguard Worker unsigned getMaxStubSize() override { 32*9880d681SAndroid Build Coastguard Worker return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad 33*9880d681SAndroid Build Coastguard Worker } 34*9880d681SAndroid Build Coastguard Worker getStubAlignment()35*9880d681SAndroid Build Coastguard Worker unsigned getStubAlignment() override { return 1; } 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker Expected<relocation_iterator> processRelocationRef(unsigned SectionID,relocation_iterator RelI,const ObjectFile & Obj,ObjSectionToIDMap & ObjSectionToID,StubMap & Stubs)38*9880d681SAndroid Build Coastguard Worker processRelocationRef(unsigned SectionID, 39*9880d681SAndroid Build Coastguard Worker relocation_iterator RelI, 40*9880d681SAndroid Build Coastguard Worker const ObjectFile &Obj, 41*9880d681SAndroid Build Coastguard Worker ObjSectionToIDMap &ObjSectionToID, 42*9880d681SAndroid Build Coastguard Worker StubMap &Stubs) override { 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker auto Symbol = RelI->getSymbol(); 45*9880d681SAndroid Build Coastguard Worker if (Symbol == Obj.symbol_end()) 46*9880d681SAndroid Build Coastguard Worker report_fatal_error("Unknown symbol in relocation"); 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker Expected<StringRef> TargetNameOrErr = Symbol->getName(); 49*9880d681SAndroid Build Coastguard Worker if (!TargetNameOrErr) 50*9880d681SAndroid Build Coastguard Worker return TargetNameOrErr.takeError(); 51*9880d681SAndroid Build Coastguard Worker StringRef TargetName = *TargetNameOrErr; 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker auto SectionOrErr = Symbol->getSection(); 54*9880d681SAndroid Build Coastguard Worker if (!SectionOrErr) 55*9880d681SAndroid Build Coastguard Worker return SectionOrErr.takeError(); 56*9880d681SAndroid Build Coastguard Worker auto Section = *SectionOrErr; 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker uint64_t RelType = RelI->getType(); 59*9880d681SAndroid Build Coastguard Worker uint64_t Offset = RelI->getOffset(); 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker // Determine the Addend used to adjust the relocation value. 62*9880d681SAndroid Build Coastguard Worker uint64_t Addend = 0; 63*9880d681SAndroid Build Coastguard Worker SectionEntry &AddendSection = Sections[SectionID]; 64*9880d681SAndroid Build Coastguard Worker uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset; 65*9880d681SAndroid Build Coastguard Worker uint8_t *Displacement = (uint8_t *)ObjTarget; 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker switch (RelType) { 68*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32: 69*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32NB: 70*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_SECREL: 71*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_REL32: { 72*9880d681SAndroid Build Coastguard Worker Addend = readBytesUnaligned(Displacement, 4); 73*9880d681SAndroid Build Coastguard Worker break; 74*9880d681SAndroid Build Coastguard Worker } 75*9880d681SAndroid Build Coastguard Worker default: 76*9880d681SAndroid Build Coastguard Worker break; 77*9880d681SAndroid Build Coastguard Worker } 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) 80*9880d681SAndroid Build Coastguard Worker SmallString<32> RelTypeName; 81*9880d681SAndroid Build Coastguard Worker RelI->getTypeName(RelTypeName); 82*9880d681SAndroid Build Coastguard Worker #endif 83*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset 84*9880d681SAndroid Build Coastguard Worker << " RelType: " << RelTypeName << " TargetName: " << TargetName 85*9880d681SAndroid Build Coastguard Worker << " Addend " << Addend << "\n"); 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker unsigned TargetSectionID = -1; 88*9880d681SAndroid Build Coastguard Worker if (Section == Obj.section_end()) { 89*9880d681SAndroid Build Coastguard Worker RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0); 90*9880d681SAndroid Build Coastguard Worker addRelocationForSymbol(RE, TargetName); 91*9880d681SAndroid Build Coastguard Worker } else { 92*9880d681SAndroid Build Coastguard Worker if (auto TargetSectionIDOrErr = 93*9880d681SAndroid Build Coastguard Worker findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID)) 94*9880d681SAndroid Build Coastguard Worker TargetSectionID = *TargetSectionIDOrErr; 95*9880d681SAndroid Build Coastguard Worker else 96*9880d681SAndroid Build Coastguard Worker return TargetSectionIDOrErr.takeError(); 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker switch (RelType) { 99*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_ABSOLUTE: 100*9880d681SAndroid Build Coastguard Worker // This relocation is ignored. 101*9880d681SAndroid Build Coastguard Worker break; 102*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32: 103*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32NB: 104*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_REL32: { 105*9880d681SAndroid Build Coastguard Worker RelocationEntry RE = 106*9880d681SAndroid Build Coastguard Worker RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, 107*9880d681SAndroid Build Coastguard Worker getSymbolOffset(*Symbol), 0, 0, false, 0); 108*9880d681SAndroid Build Coastguard Worker addRelocationForSection(RE, TargetSectionID); 109*9880d681SAndroid Build Coastguard Worker break; 110*9880d681SAndroid Build Coastguard Worker } 111*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_SECTION: { 112*9880d681SAndroid Build Coastguard Worker RelocationEntry RE = 113*9880d681SAndroid Build Coastguard Worker RelocationEntry(TargetSectionID, Offset, RelType, 0); 114*9880d681SAndroid Build Coastguard Worker addRelocationForSection(RE, TargetSectionID); 115*9880d681SAndroid Build Coastguard Worker break; 116*9880d681SAndroid Build Coastguard Worker } 117*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_SECREL: { 118*9880d681SAndroid Build Coastguard Worker RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, 119*9880d681SAndroid Build Coastguard Worker getSymbolOffset(*Symbol) + Addend); 120*9880d681SAndroid Build Coastguard Worker addRelocationForSection(RE, TargetSectionID); 121*9880d681SAndroid Build Coastguard Worker break; 122*9880d681SAndroid Build Coastguard Worker } 123*9880d681SAndroid Build Coastguard Worker default: 124*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unsupported relocation type"); 125*9880d681SAndroid Build Coastguard Worker } 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker } 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker return ++RelI; 130*9880d681SAndroid Build Coastguard Worker } 131*9880d681SAndroid Build Coastguard Worker resolveRelocation(const RelocationEntry & RE,uint64_t Value)132*9880d681SAndroid Build Coastguard Worker void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override { 133*9880d681SAndroid Build Coastguard Worker const auto Section = Sections[RE.SectionID]; 134*9880d681SAndroid Build Coastguard Worker uint8_t *Target = Section.getAddressWithOffset(RE.Offset); 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker switch (RE.RelType) { 137*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_ABSOLUTE: 138*9880d681SAndroid Build Coastguard Worker // This relocation is ignored. 139*9880d681SAndroid Build Coastguard Worker break; 140*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32: { 141*9880d681SAndroid Build Coastguard Worker // The target's 32-bit VA. 142*9880d681SAndroid Build Coastguard Worker uint64_t Result = 143*9880d681SAndroid Build Coastguard Worker RE.Sections.SectionA == static_cast<uint32_t>(-1) 144*9880d681SAndroid Build Coastguard Worker ? Value 145*9880d681SAndroid Build Coastguard Worker : Sections[RE.Sections.SectionA].getLoadAddressWithOffset( 146*9880d681SAndroid Build Coastguard Worker RE.Addend); 147*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) <= INT32_MAX && 148*9880d681SAndroid Build Coastguard Worker "relocation overflow"); 149*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) >= INT32_MIN && 150*9880d681SAndroid Build Coastguard Worker "relocation underflow"); 151*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tOffset: " << RE.Offset 152*9880d681SAndroid Build Coastguard Worker << " RelType: IMAGE_REL_I386_DIR32" 153*9880d681SAndroid Build Coastguard Worker << " TargetSection: " << RE.Sections.SectionA 154*9880d681SAndroid Build Coastguard Worker << " Value: " << format("0x%08" PRIx32, Result) << '\n'); 155*9880d681SAndroid Build Coastguard Worker writeBytesUnaligned(Result, Target, 4); 156*9880d681SAndroid Build Coastguard Worker break; 157*9880d681SAndroid Build Coastguard Worker } 158*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_DIR32NB: { 159*9880d681SAndroid Build Coastguard Worker // The target's 32-bit RVA. 160*9880d681SAndroid Build Coastguard Worker // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase 161*9880d681SAndroid Build Coastguard Worker uint64_t Result = 162*9880d681SAndroid Build Coastguard Worker Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) - 163*9880d681SAndroid Build Coastguard Worker Sections[0].getLoadAddress(); 164*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) <= INT32_MAX && 165*9880d681SAndroid Build Coastguard Worker "relocation overflow"); 166*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) >= INT32_MIN && 167*9880d681SAndroid Build Coastguard Worker "relocation underflow"); 168*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tOffset: " << RE.Offset 169*9880d681SAndroid Build Coastguard Worker << " RelType: IMAGE_REL_I386_DIR32NB" 170*9880d681SAndroid Build Coastguard Worker << " TargetSection: " << RE.Sections.SectionA 171*9880d681SAndroid Build Coastguard Worker << " Value: " << format("0x%08" PRIx32, Result) << '\n'); 172*9880d681SAndroid Build Coastguard Worker writeBytesUnaligned(Result, Target, 4); 173*9880d681SAndroid Build Coastguard Worker break; 174*9880d681SAndroid Build Coastguard Worker } 175*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_REL32: { 176*9880d681SAndroid Build Coastguard Worker // 32-bit relative displacement to the target. 177*9880d681SAndroid Build Coastguard Worker uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1) 178*9880d681SAndroid Build Coastguard Worker ? Value 179*9880d681SAndroid Build Coastguard Worker : Sections[RE.Sections.SectionA].getLoadAddress(); 180*9880d681SAndroid Build Coastguard Worker Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset; 181*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) <= INT32_MAX && 182*9880d681SAndroid Build Coastguard Worker "relocation overflow"); 183*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(Result) >= INT32_MIN && 184*9880d681SAndroid Build Coastguard Worker "relocation underflow"); 185*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tOffset: " << RE.Offset 186*9880d681SAndroid Build Coastguard Worker << " RelType: IMAGE_REL_I386_REL32" 187*9880d681SAndroid Build Coastguard Worker << " TargetSection: " << RE.Sections.SectionA 188*9880d681SAndroid Build Coastguard Worker << " Value: " << format("0x%08" PRIx32, Result) << '\n'); 189*9880d681SAndroid Build Coastguard Worker writeBytesUnaligned(Result, Target, 4); 190*9880d681SAndroid Build Coastguard Worker break; 191*9880d681SAndroid Build Coastguard Worker } 192*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_SECTION: 193*9880d681SAndroid Build Coastguard Worker // 16-bit section index of the section that contains the target. 194*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(RE.SectionID) <= INT16_MAX && 195*9880d681SAndroid Build Coastguard Worker "relocation overflow"); 196*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(RE.SectionID) >= INT16_MIN && 197*9880d681SAndroid Build Coastguard Worker "relocation underflow"); 198*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tOffset: " << RE.Offset 199*9880d681SAndroid Build Coastguard Worker << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID 200*9880d681SAndroid Build Coastguard Worker << '\n'); 201*9880d681SAndroid Build Coastguard Worker writeBytesUnaligned(RE.SectionID, Target, 2); 202*9880d681SAndroid Build Coastguard Worker break; 203*9880d681SAndroid Build Coastguard Worker case COFF::IMAGE_REL_I386_SECREL: 204*9880d681SAndroid Build Coastguard Worker // 32-bit offset of the target from the beginning of its section. 205*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX && 206*9880d681SAndroid Build Coastguard Worker "relocation overflow"); 207*9880d681SAndroid Build Coastguard Worker assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN && 208*9880d681SAndroid Build Coastguard Worker "relocation underflow"); 209*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\t\tOffset: " << RE.Offset 210*9880d681SAndroid Build Coastguard Worker << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend 211*9880d681SAndroid Build Coastguard Worker << '\n'); 212*9880d681SAndroid Build Coastguard Worker writeBytesUnaligned(RE.Addend, Target, 2); 213*9880d681SAndroid Build Coastguard Worker break; 214*9880d681SAndroid Build Coastguard Worker default: 215*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unsupported relocation type"); 216*9880d681SAndroid Build Coastguard Worker } 217*9880d681SAndroid Build Coastguard Worker } 218*9880d681SAndroid Build Coastguard Worker registerEHFrames()219*9880d681SAndroid Build Coastguard Worker void registerEHFrames() override {} deregisterEHFrames()220*9880d681SAndroid Build Coastguard Worker void deregisterEHFrames() override {} 221*9880d681SAndroid Build Coastguard Worker }; 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker } 224*9880d681SAndroid Build Coastguard Worker 225*9880d681SAndroid Build Coastguard Worker #endif 226*9880d681SAndroid Build Coastguard Worker 227