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