176463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky//===-- RuntimeDyldMachO.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-=// 276463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// 376463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// The LLVM Compiler Infrastructure 476463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// 576463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// This file is distributed under the University of Illinois Open Source 676463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// License. See LICENSE.TXT for details. 776463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// 876463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky//===----------------------------------------------------------------------===// 976463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// 1076463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// MachO support for MC-JIT runtime dynamic linker. 1176463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky// 1276463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky//===----------------------------------------------------------------------===// 1376463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 1476463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#ifndef LLVM_RUNTIME_DYLD_MACHO_H 1576463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#define LLVM_RUNTIME_DYLD_MACHO_H 1676463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "ObjectImageCommon.h" 18a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "RuntimeDyldImpl.h" 1976463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "llvm/ADT/IndexedMap.h" 202173e1839c2d00f7f980450dd537047b7b376e6bRafael Espindola#include "llvm/Object/MachO.h" 2176463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "llvm/Support/Format.h" 2276463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 2376463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Benderskyusing namespace llvm; 2476463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Benderskyusing namespace llvm::object; 2576463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 2676463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Benderskynamespace llvm { 2776463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Benderskyclass RuntimeDyldMachO : public RuntimeDyldImpl { 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesprivate: 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// Write the least significant 'Size' bytes in 'Value' out at the address 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// pointed to by Addr. 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool applyRelocationValue(uint8_t *Addr, uint64_t Value, unsigned Size) { 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < Size; ++i) { 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Addr++ = (uint8_t)Value; 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Value >>= 8; 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool resolveI386Relocation(const RelocationEntry &RE, uint64_t Value); 42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool resolveX86_64Relocation(const RelocationEntry &RE, uint64_t Value); 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool resolveARMRelocation(const RelocationEntry &RE, uint64_t Value); 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool resolveAArch64Relocation(const RelocationEntry &RE, uint64_t Value); 45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Populate stubs in __jump_table section. 47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection, 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned JTSectionID); 49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Populate __pointers section. 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void populatePointersSection(MachOObjectFile &Obj, const SectionRef &PTSection, 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PTSectionID); 53528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getMaxStubSize() override { 5572be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor if (Arch == Triple::arm || Arch == Triple::thumb) 5672be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor return 8; // 32-bit instruction and 32-bit address 5772be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor else if (Arch == Triple::x86_64) 5872be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor return 8; // GOT entry 5972be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor else 6072be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor return 0; 6172be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor } 6272be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned getStubAlignment() override { return 1; } 6472be32c6332ff9dd38b989d5a0dd80f40996dd10Andrew Kaylor 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator processSECTDIFFRelocation( 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &ObjImg, 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID); 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator processI386ScatteredVANILLA( 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned SectionID, 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator RelI, 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectImage &ObjImg, 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &ObjSectionToID); 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 77528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor struct EHFrameRelatedSections { 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EHFrameRelatedSections() 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : EHFrameSID(RTDYLD_INVALID_SECTION_ID), 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TextSID(RTDYLD_INVALID_SECTION_ID), 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {} 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EHFrameRelatedSections(SID EH, SID T, SID Ex) 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {} 84528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SID EHFrameSID; 85528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SID TextSID; 86528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SID ExceptTabSID; 87528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor }; 88528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor 89528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor // When a module is loaded we save the SectionID of the EH frame section 90528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor // in a table until we receive a request to register all unregistered 91528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor // EH frame sections with the memory manager. 92528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections; 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9476463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Benderskypublic: 9576463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} 9676463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines relocation_iterator 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines processRelocationRef(unsigned SectionID, relocation_iterator RelI, 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SymbolTableMap &Symbols, StubMap &Stubs) override; 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool isCompatibleFile(const object::ObjectFile *Obj) const override; 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void registerEHFrames() override; 105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void finalizeLoad(ObjectImage &ObjImg, 106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjSectionToIDMap &SectionMap) override; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines static ObjectImage *createObjectImage(ObjectBuffer *Buffer); 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static ObjectImage * 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject); 11176463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky}; 11276463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 11376463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky} // end namespace llvm 11476463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 11576463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#endif 116