1e0934bee3a4f40731169bc42b15a39ce39978175Jim Grosbach//===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ----*- C++ -*-===// 26e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// 36e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// The LLVM Compiler Infrastructure 46e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// 56e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// This file is distributed under the University of Illinois Open Source 66e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// License. See LICENSE.TXT for details. 76e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// 86e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach//===----------------------------------------------------------------------===// 96e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// 106e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// Implementation of the MC-JIT runtime dynamic linker. 116e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// 126e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach//===----------------------------------------------------------------------===// 136e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ExecutionEngine/RuntimeDyld.h" 15354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka#include "JITRegistrar.h" 163f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "ObjectImageCommon.h" 1776463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "RuntimeDyldELF.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "RuntimeDyldImpl.h" 1976463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky#include "RuntimeDyldMachO.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/ELF.h" 21f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover#include "llvm/Support/MathExtras.h" 226169453ba37ac353655f2475f336e66f31276752Andrew Kaylor#include "llvm/Support/MutexGuard.h" 2376463fdeb603e1d89b05f094bfd6fe73b90d0b61Eli Bendersky 246e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbachusing namespace llvm; 256e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbachusing namespace llvm::object; 266e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "dyld" 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2953c5e7b2e7e36d70bd943cb2d576121435bd5b3fChandler Carruth// Empty out-of-line virtual destructor as the key function. 30cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevRuntimeDyldImpl::~RuntimeDyldImpl() {} 3153c5e7b2e7e36d70bd943cb2d576121435bd5b3fChandler Carruth 32354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka// Pin the JITRegistrar's and ObjectImage*'s vtables to this file. 33354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid JITRegistrar::anchor() {} 34354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid ObjectImage::anchor() {} 35354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid ObjectImageCommon::anchor() {} 36354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka 376e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbachnamespace llvm { 386e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid RuntimeDyldImpl::registerEHFrames() {} 40a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid RuntimeDyldImpl::deregisterEHFrames() {} 4243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 43f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach// Resolve the relocations for all symbols we currently know about. 44f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbachvoid RuntimeDyldImpl::resolveRelocations() { 456169453ba37ac353655f2475f336e66f31276752Andrew Kaylor MutexGuard locked(lock); 466169453ba37ac353655f2475f336e66f31276752Andrew Kaylor 47c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // First, resolve relocations associated with external symbols. 4837bc5a200092f1b41da799c75da70258015e43a4Eli Bendersky resolveExternalSymbols(); 490e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 5061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // Just iterate over the sections we have and resolve all the relocations 5161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach // in them. Gross overkill, but it gets the job done. 5261425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach for (int i = 0, e = Sections.size(); i != e; ++i) { 5332bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor // The Section here (Sections[i]) refers to the section in which the 5432bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor // symbol for the relocation is located. The SectionID in the relocation 5532bd10b1a33df2cc4d067a16901d56665f4ba085Andrew Kaylor // entry provides the section to which the relocation will be applied. 5628989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor uint64_t Addr = Sections[i].LoadAddress; 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t" 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p", (uint8_t *)Addr) << "\n"); 5928989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor resolveRelocationList(Relocations[i], Addr); 608e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor Relocations.erase(i); 6161425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach } 62f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach} 63f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach 64e940c1bb6c976539f07d6f440aeaacf7c25e1ddcJim Grosbachvoid RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, 65020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach uint64_t TargetAddress) { 666169453ba37ac353655f2475f336e66f31276752Andrew Kaylor MutexGuard locked(lock); 670e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev for (unsigned i = 0, e = Sections.size(); i != e; ++i) { 680e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (Sections[i].Address == LocalAddress) { 690e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev reassignSectionAddress(i, TargetAddress); 700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev return; 710e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 720e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev llvm_unreachable("Attempting to remap address of unknown section!"); 740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Address; 78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = Sym.getAddress(Address)) 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Address == UnknownAddressOrSize) { 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Result = UnknownAddressOrSize; 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return object_error::success; 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const ObjectFile *Obj = Sym.getObject(); 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines section_iterator SecI(Obj->section_begin()); 88cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = Sym.getSection(SecI)) 89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (SecI == Obj->section_end()) { 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Result = UnknownAddressOrSize; 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return object_error::success; 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectionAddress; 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = SecI->getAddress(SectionAddress)) 98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Result = Address - SectionAddress; 101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return object_error::success; 102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { 1056169453ba37ac353655f2475f336e66f31276752Andrew Kaylor MutexGuard locked(lock); 1066169453ba37ac353655f2475f336e66f31276752Andrew Kaylor 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectImage> Obj(InputObject); 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Obj) 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 1100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 111ab950f5f334d30a7b5bfb1e009846dfb0b47f61cAndrew Kaylor // Save information about our target 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Arch = (Triple::ArchType)Obj->getArch(); 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian(); 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Compute the memory size required to load all sections to be loaded 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // and pass this information to the memory manager 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MemMgr->needsToReserveAllocationSpace()) { 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0; 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 1220e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 123d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky // Symbols found in this object 124d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky StringMap<SymbolLoc> LocalSymbols; 125d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky // Used sections from the object file 126d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky ObjSectionToIDMap LocalSections; 127d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky 128f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover // Common symbols requiring allocation, with their sizes and alignments 129d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky CommonSymbolMap CommonSymbols; 130f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover // Maximum required total memory to allocate all common symbols 131d98c9e918c9750d965c1efe9efcc9e13feacbe13Eli Bendersky uint64_t CommonSize = 0; 1320e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 1330e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Parse symbols 1340e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << "Parse symbols:\n"); 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E; 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++I) { 1370e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev object::SymbolRef::Type SymType; 1380e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef Name; 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(I->getType(SymType)); 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(I->getName(Name)); 1410e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Flags = I->getFlags(); 143c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCommon = Flags & SymbolRef::SF_Common; 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsCommon) { 146c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Add the common symbols to a list. We'll allocate them all below. 147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!GlobalSymbolTable.count(Name)) { 148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t Align; 149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Check(I->getAlignment(Align)); 150dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Size = 0; 151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Check(I->getSize(Size)); 152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CommonSize += Size + Align; 153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CommonSymbols[*I] = CommonSymbolInfo(Size, Align); 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 155c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd } else { 156c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (SymType == object::SymbolRef::ST_Function || 157b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka SymType == object::SymbolRef::ST_Data || 158b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka SymType == object::SymbolRef::ST_Unknown) { 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t SectOffset; 1605fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky StringRef SectionData; 161788221398a2cdb219c37625b5176211e7c7d44a6Tim Northover bool IsCode; 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator SI = Obj->end_sections(); 163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Check(getOffset(*I, SectOffset)); 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(I->getSection(SI)); 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SI == Obj->end_sections()) 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(SI->getContents(SectionData)); 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(SI->isText(IsCode)); 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned SectionID = 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findOrEmitSection(*Obj, *SI, IsCode, LocalSections); 171c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset); 172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset) 173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << " flags: " << Flags << " SID: " << SectionID); 174098d6d57346322c7f71f4e3e45bbea81039386c4Amara Emerson GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); 175c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd } 1760e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 1770e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"); 1780e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 1790e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 180c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Allocate common symbols 181c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (CommonSize != 0) 182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable); 183c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 1845fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky // Parse and process relocations 1850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev DEBUG(dbgs() << "Parse relocations:\n"); 18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections(); 18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SI != SE; ++SI) { 1880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned SectionID = 0; 1890e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StubMap Stubs; 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator RelocatedSection = SI->getRelocatedSection(); 1910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator I = SI->relocation_begin(); 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines relocation_iterator E = SI->relocation_end(); 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (I == E && !ProcessAllSections) 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCode = false; 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(RelocatedSection->isText(IsCode)); 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionID = 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections); 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 204dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (; I != E;) 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols, 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Stubs); 2070e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 208689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd 209ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // Give the subclasses a chance to tie-up any loose ends. 210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines finalizeLoad(*Obj, LocalSections); 211ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Obj.release(); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// A helper method for computeTotalAllocSize. 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Computes the memory size required to allocate sections with the given sizes, 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// assuming that all sections are allocated with the given alignment 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint64_t 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinescomputeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes, 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Alignment) { 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t TotalSize = 0; 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (size_t Idx = 0, Cnt = SectionSizes.size(); Idx < Cnt; Idx++) { 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t AlignedSize = 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (SectionSizes[Idx] + Alignment - 1) / Alignment * Alignment; 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TotalSize += AlignedSize; 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TotalSize; 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Compute an upper bound of the memory size that is required to load all 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// sections 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj, 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t &CodeSize, 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t &DataSizeRO, 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t &DataSizeRW) { 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Compute the size of all sections required for execution 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<uint64_t> CodeSectionSizes; 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<uint64_t> ROSectionSizes; 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<uint64_t> RWSectionSizes; 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t MaxAlignment = sizeof(void *); 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Collect sizes of all sections to be loaded; 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // also determine the max alignment of all sections 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SI != SE; ++SI) { 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SectionRef &Section = *SI; 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsRequired; 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.isRequiredForExecution(IsRequired)); 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Consider only the sections that are required to be loaded for execution 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsRequired) { 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t DataSize = 0; 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Alignment64 = 0; 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsCode = false; 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsReadOnly = false; 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name; 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.getSize(DataSize)); 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.getAlignment(Alignment64)); 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.isText(IsCode)); 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.isReadOnlyData(IsReadOnly)); 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.getName(Name)); 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section); 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SectionSize = DataSize + StubBufSize; 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The .eh_frame section (at least on Linux) needs an extra four bytes 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // padded 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // with zeroes added at the end. For MachO objects, this section has a 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // slightly different name, so this won't have any effect for MachO 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // objects. 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Name == ".eh_frame") 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionSize += 4; 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SectionSize > 0) { 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // save the total size of the section 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IsCode) { 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CodeSectionSizes.push_back(SectionSize); 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (IsReadOnly) { 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ROSectionSizes.push_back(SectionSize); 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RWSectionSizes.push_back(SectionSize); 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // update the max alignment 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Alignment > MaxAlignment) { 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MaxAlignment = Alignment; 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Compute the size of all common symbols 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t CommonSize = 0; 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E; 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++I) { 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Flags = I->getFlags(); 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Flags & SymbolRef::SF_Common) { 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Add the common symbols to a list. We'll allocate them all below. 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Size = 0; 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(I->getSize(Size)); 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CommonSize += Size; 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CommonSize != 0) { 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RWSectionSizes.push_back(CommonSize); 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Compute the required allocation space for each different type of sections 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // (code, read-only data, read-write data) assuming that all sections are 31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // allocated with the max alignment. Note that we cannot compute with the 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // individual alignments of the sections, because then the required size 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // depends on the order, in which the sections are allocated. 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CodeSize = computeAllocationSizeForSections(CodeSectionSizes, MaxAlignment); 31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataSizeRO = computeAllocationSizeForSections(ROSectionSizes, MaxAlignment); 31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment); 31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// compute stub buffer size for the given section 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj, 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SectionRef &Section) { 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned StubSize = getMaxStubSize(); 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StubSize == 0) { 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 0; 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: this is an inefficient way to handle this. We should computed the 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // necessary section allocation size in loadObject by walking all the sections 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // once. 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned StubBufSize = 0; 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SI != SE; ++SI) { 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator RelSecI = SI->getRelocatedSection(); 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!(RelSecI == Section)) 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const RelocationRef &Reloc : SI->relocations()) { 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (void)Reloc; 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubBufSize += StubSize; 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get section data size and alignment 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Alignment64; 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t DataSize; 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.getSize(DataSize)); 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Check(Section.getAlignment(Alignment64)); 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Add stubbuf size alignment 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned StubAlignment = getStubAlignment(); 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StubAlignment > EndAlignment) 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubBufSize += StubAlignment - EndAlignment; 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return StubBufSize; 355020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach} 356020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach 357c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Benderskyvoid RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, 358c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky const CommonSymbolMap &CommonSymbols, 359c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky uint64_t TotalSize, 360c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky SymbolTableMap &SymbolTable) { 361c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Allocate memory for the section 362c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd unsigned SectionID = Sections.size(); 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *), 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionID, StringRef(), false); 365c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (!Addr) 366c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd report_fatal_error("Unable to allocate memory for common symbols!"); 367c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd uint64_t Offset = 0; 368a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Sections.push_back(SectionEntry(StringRef(), Addr, TotalSize, 0)); 369c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd memset(Addr, 0, TotalSize); 370c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: " 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p", Addr) << " DataSize: " << TotalSize << "\n"); 373c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 374c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Assign the address of each symbol 375c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(), 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines itEnd = CommonSymbols.end(); it != itEnd; ++it) { 377f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover uint64_t Size = it->second.first; 378f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover uint64_t Align = it->second.second; 379c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd StringRef Name; 380c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd it->first.getName(Name); 381f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover if (Align) { 382f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover // This symbol has an alignment requirement. 383f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align); 384f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover Addr += AlignOffset; 385f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover Offset += AlignOffset; 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Allocating common symbol " << Name << " address " 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%p\n", Addr)); 388f00677d74f1be5b4c7c73e1681a64c9062f4c7eeTim Northover } 389689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd Obj.updateSymbolAddress(it->first, (uint64_t)Addr); 390c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); 391c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Offset += Size; 392c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Addr += Size; 393c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd } 394c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd} 395c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 396689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurdunsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SectionRef &Section, bool IsCode) { 3987486d92a6c949a193bb75c0ffa0170eeb2fabb80Rafael Espindola 3990e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef data; 4000e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Alignment64; 4010e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Check(Section.getContents(data)); 4020e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Check(Section.getAlignment(Alignment64)); 4030e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 4040e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; 405c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool IsRequired; 406c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool IsVirtual; 407c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd bool IsZeroInit; 40853608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor bool IsReadOnly; 409c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd uint64_t DataSize; 41028a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor unsigned PaddingSize = 0; 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned StubBufSize = 0; 4126e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella StringRef Name; 413c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Check(Section.isRequiredForExecution(IsRequired)); 414c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Check(Section.isVirtual(IsVirtual)); 415c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Check(Section.isZeroInit(IsZeroInit)); 41653608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor Check(Section.isReadOnlyData(IsReadOnly)); 417c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Check(Section.getSize(DataSize)); 4186e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella Check(Section.getName(Name)); 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubBufSize = computeSectionStubBufSize(Obj, Section); 421c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 42228a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor // The .eh_frame section (at least on Linux) needs an extra four bytes padded 42328a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor // with zeroes added at the end. For MachO objects, this section has a 42428a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor // slightly different name, so this won't have any effect for MachO objects. 42528a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor if (Name == ".eh_frame") 42628a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor PaddingSize = 4; 42728a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uintptr_t Allocate; 4290e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned SectionID = Sections.size(); 430c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd uint8_t *Addr; 431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *pData = nullptr; 432c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 433c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Some sections, such as debug info, don't need to be loaded for execution. 434c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Leave those where they are. 435c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (IsRequired) { 43628a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor Allocate = DataSize + PaddingSize + StubBufSize; 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Name) 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Name, IsReadOnly); 441c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (!Addr) 442c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd report_fatal_error("Unable to allocate section memory!"); 443c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 444c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Virtual sections have no data in the object image, so leave pData = 0 445c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (!IsVirtual) 446c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd pData = data.data(); 447c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 448c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Zero-initialize or copy the data from the image 449c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd if (IsZeroInit || IsVirtual) 450c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd memset(Addr, 0, DataSize); 451c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd else 452c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd memcpy(Addr, pData, DataSize); 453c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 45428a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor // Fill in any extra bytes we allocated for padding 45528a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor if (PaddingSize != 0) { 45628a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor memset(Addr + DataSize, 0, PaddingSize); 45728a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor // Update the DataSize variable so that the stub offset is set correctly. 45828a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor DataSize += PaddingSize; 45928a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor } 46028a765542c7a57821fc4c06454c1326e2f66a1d9Andrew Kaylor 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name 462c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd << " obj addr: " << format("%p", pData) 463c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd << " new addr: " << format("%p", Addr) 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " Allocate: " << Allocate << "\n"); 466689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd Obj.updateSectionAddress(Section, (uint64_t)Addr); 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 468c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd // Even if we didn't load the section, we need to record an entry for it 4695fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky // to handle later processing (and by 'handle' I mean don't do anything 4705fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky // with these sections). 471c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd Allocate = 0; 472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Addr = nullptr; 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " obj addr: " << format("%p", data.data()) << " new addr: 0" 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << " Allocate: " << Allocate << "\n"); 477c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd } 478c68dda815e64fb2fb463318d1eaa304e22199d50Preston Gurd 479a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); 4800e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev return SectionID; 4810e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 4820e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 483689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurdunsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, 484689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd const SectionRef &Section, 4850e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev bool IsCode, 4860e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap &LocalSections) { 4870e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 4880e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev unsigned SectionID = 0; 4890e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev ObjSectionToIDMap::iterator i = LocalSections.find(Section); 4900e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev if (i != LocalSections.end()) 4910e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev SectionID = i->second; 4920e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev else { 493689ff9c00f4f3dcf3491778bcdbda79e19e2285dPreston Gurd SectionID = emitSection(Obj, Section, IsCode); 4940e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev LocalSections[Section] = SectionID; 4950e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 4960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev return SectionID; 4970e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 4980e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 499c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Benderskyvoid RuntimeDyldImpl::addRelocationForSection(const RelocationEntry &RE, 500c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky unsigned SectionID) { 501c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky Relocations[SectionID].push_back(RE); 502c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky} 5030e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 504c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Benderskyvoid RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE, 505c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky StringRef SymbolName) { 506c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Relocation by symbol. If the symbol is found in the global symbol table, 507c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // create an appropriate section relocation. Otherwise, add it to 508c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // ExternalSymbolRelocations. 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName); 510c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky if (Loc == GlobalSymbolTable.end()) { 511c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky ExternalSymbolRelocations[SymbolName].push_back(RE); 51237bc5a200092f1b41da799c75da70258015e43a4Eli Bendersky } else { 513c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky // Copy the RE since we want to modify its addend. 514c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RelocationEntry RECopy = RE; 515c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky RECopy.Addend += Loc->second.second; 516c201e6eaf165c83f0092c43b371e509fa8eaf4ccEli Bendersky Relocations[Loc->second.first].push_back(RECopy); 51737bc5a200092f1b41da799c75da70258015e43a4Eli Bendersky } 5180e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 5190e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 5200e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevuint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) { 521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be || 522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Arch == Triple::arm64 || Arch == Triple::arm64_be) { 5234a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // This stub has to be able to access the full address space, 5244a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // since symbol lookup won't necessarily find a handy, in-range, 5254a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // PLT stub for functions which could be anywhere. 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *StubAddr = (uint32_t *)Addr; 5274a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 5284a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover // Stub can use ip0 (== x16) to calculate address 5294a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr> 5304a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubAddr++; 5314a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:<addr> 5324a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubAddr++; 5334a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:<addr> 5344a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubAddr++; 5354a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:<addr> 5364a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover StubAddr++; 5374a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover *StubAddr = 0xd61f0200; // br ip0 5384a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover 5394a9b6b798d5ea335f5f29d278db83b830ae4a564Tim Northover return Addr; 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Arch == Triple::arm || Arch == Triple::armeb) { 541b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // TODO: There is only ARM far stub now. We should add the Thumb stub, 542b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // and stubs for branches Thumb - ARM and ARM - Thumb. 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *StubAddr = (uint32_t *)Addr; 5440e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev *StubAddr = 0xe51ff004; // ldr pc,<label> 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return (uint8_t *)++StubAddr; 5464af1ca5229a149c1d8e5e89bc2f13209da33221cNAKAMURA Takumi } else if (Arch == Triple::mipsel || Arch == Triple::mips) { 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t *StubAddr = (uint32_t *)Addr; 548b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // 0: 3c190000 lui t9,%hi(addr). 549b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // 4: 27390000 addiu t9,t9,%lo(addr). 550b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // 8: 03200008 jr t9. 551b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka // c: 00000000 nop. 552b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000; 553b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0; 554b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka 555b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka *StubAddr = LuiT9Instr; 556b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka StubAddr++; 557b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka *StubAddr = AdduiT9Instr; 558b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka StubAddr++; 559b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka *StubAddr = JrT9Instr; 560b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka StubAddr++; 561b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka *StubAddr = NopInstr; 5620e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev return Addr; 563f38cc38fa647d4e72c053c39bbe0cdec1342535fBill Schmidt } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { 5646e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // PowerPC64 stub: the address points to a function descriptor 5656e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // instead of the function itself. Load the function address 5666e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // on r11 and sets it to control register. Also loads the function 5676e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella // TOC in r2 and environment pointer to r11. 5686e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr, 0x3D800000); // lis r12, highest(addr) 5696e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+4, 0x618C0000); // ori r12, higher(addr) 5706e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+8, 0x798C07C6); // sldi r12, r12, 32 5716e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+12, 0x658C0000); // oris r12, r12, h(addr) 5726e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+16, 0x618C0000); // ori r12, r12, l(addr) 5736e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+20, 0xF8410028); // std r2, 40(r1) 5746e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+24, 0xE96C0000); // ld r11, 0(r12) 5756e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+28, 0xE84C0008); // ld r2, 0(r12) 5766e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+32, 0x7D6903A6); // mtctr r11 5776e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+36, 0xE96C0010); // ld r11, 16(r2) 5786e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella writeInt32BE(Addr+40, 0x4E800420); // bctr 5795fc8c7cb8571f99b69264aeba48c45eed1c69f6aAndrew Kaylor 5806e8946c5280ad6071d21013651745a9478f063edAdhemerval Zanella return Addr; 5816fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford } else if (Arch == Triple::systemz) { 5826fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt16BE(Addr, 0xC418); // lgrl %r1,.+8 5836fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt16BE(Addr+2, 0x0000); 5846fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt16BE(Addr+4, 0x0004); 5856fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford writeInt16BE(Addr+6, 0x07F1); // brc 15,%r1 5866fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford // 8-byte address stored at Addr + 8 5876fc2ad62e23673ef829c9c4bbf62743d30928a5bRichard Sandiford return Addr; 588ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor } else if (Arch == Triple::x86_64) { 589ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor *Addr = 0xFF; // jmp 590ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor *(Addr+1) = 0x25; // rip 591ff9fa05905be716435460b5f6d32689041bf895bAndrew Kaylor // 32-bit PC-relative address of the GOT entry will be stored at Addr+2 592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (Arch == Triple::x86) { 593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines *Addr = 0xE9; // 32-bit pc-relative jump. 594b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka } 595b889e0cd2fea4afee623d5be603b912b955a2ecaAkira Hatanaka return Addr; 5960e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 5970e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 5980e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev// Assign an address to a symbol name and resolve all the relocations 5990e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev// associated with it. 6000e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevvoid RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID, 6010e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Addr) { 6020e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // The address to use for relocation resolution is not 6030e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // the address of the local section buffer. We must be doing 60428989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // a remote execution environment of some sort. Relocations can't 60528989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // be applied until all the sections have been moved. The client must 60628989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // trigger this with a call to MCJIT::finalize() or 60728989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor // RuntimeDyld::resolveRelocations(). 6080e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // 6090e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // Addr is a uint64_t because we can't assume the pointer width 6100e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // of the target is the same as that of the host. Just use a generic 6110e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev // "big enough" type. 6120e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev Sections[SectionID].LoadAddress = Addr; 6130e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 6140e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 6150e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshevvoid RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs, 6160e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev uint64_t Value) { 6170e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 61887b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola const RelocationEntry &RE = Relocs[i]; 61987b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola // Ignore relocations for sections that were not loaded 620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Sections[RE.SectionID].Address == nullptr) 62187b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola continue; 62287b5017139e9d8ac9b046b3284a9cc68c76185d6Rafael Espindola resolveRelocation(RE, Value); 6230e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 6240e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 6250e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 62637bc5a200092f1b41da799c75da70258015e43a4Eli Benderskyvoid RuntimeDyldImpl::resolveExternalSymbols() { 62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (!ExternalSymbolRelocations.empty()) { 6288e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin(); 6298e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 6300e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev StringRef Name = i->first(); 6318e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Name.size() == 0) { 6328e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // This is an absolute symbol, use an address of zero. 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Resolving absolute relocations." 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << "\n"); 635559d409633ce22574dcab56d4f600b6eb1304652Andrew Kaylor RelocationList &Relocs = i->second; 6368e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor resolveRelocationList(Relocs, 0); 6378e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor } else { 6388e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor uint64_t Addr = 0; 6398e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); 6408e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (Loc == GlobalSymbolTable.end()) { 64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This is an external symbol, try to get its address from 64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // MemoryManager. 64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Addr = MemMgr->getSymbolAddress(Name.data()); 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The call to getSymbolAddress may have caused additional modules to 64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // be loaded, which may have added new entries to the 64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // ExternalSymbolRelocations map. Consquently, we need to update our 64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // iterator. This is also why retrieval of the relocation list 64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // associated with this symbol is deferred until below this point. 64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // New entries may have been added to the relocation list. 65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines i = ExternalSymbolRelocations.find(Name); 65129fe150bff0f167e85e1b44efe344bf28cb7fe0fAndrew Kaylor } else { 6528e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // We found the symbol in our global table. It was probably in a 6538e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // Module that we loaded previously. 6544805bf59b9e41a95336c066ec58194ff6801694aYaron Keren SymbolLoc SymLoc = Loc->second; 6558e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second; 6567b170500dcfce130c1e5af1c9150014e69e56819Andrew Kaylor } 6578e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 6588e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor // FIXME: Implement error handling that doesn't kill the host program! 6598e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (!Addr) 6608e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor report_fatal_error("Program used external function '" + Name + 66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "' which could not be resolved!"); 6628e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 6638e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor updateGOTEntries(Name, Addr); 66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t" 66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("0x%lx", Addr) << "\n"); 666559d409633ce22574dcab56d4f600b6eb1304652Andrew Kaylor // This list may have been updated when we called getSymbolAddress, so 667559d409633ce22574dcab56d4f600b6eb1304652Andrew Kaylor // don't change this code to get the list earlier. 668559d409633ce22574dcab56d4f600b6eb1304652Andrew Kaylor RelocationList &Relocs = i->second; 6698e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor resolveRelocationList(Relocs, Addr); 6700e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 6718e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor 672559d409633ce22574dcab56d4f600b6eb1304652Andrew Kaylor ExternalSymbolRelocations.erase(i); 6730e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev } 6740e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev} 6750e4fa5ff365fccff46870b7d5d8d4d1d46e77986Danil Malyshev 6766e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach//===----------------------------------------------------------------------===// 6776e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach// RuntimeDyld class implementation 678cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevRuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 67953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // FIXME: There's a potential issue lurking here if a single instance of 68053608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // RuntimeDyld is used to load multiple objects. The current implementation 68153608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // associates a single memory manager with a RuntimeDyld instance. Even 68253608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // though the public class spawns a new 'impl' instance for each load, 68353608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // they share a single memory manager. This can become a problem when page 68453608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor // permissions are applied. 685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Dyld = nullptr; 686cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev MM = mm; 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ProcessAllSections = false; 68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRuntimeDyld::~RuntimeDyld() { delete Dyld; } 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic std::unique_ptr<RuntimeDyldELF> 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinescreateRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections) { 69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM)); 69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld->setProcessAllSections(ProcessAllSections); 69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Dyld; 6976e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach} 6986e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic std::unique_ptr<RuntimeDyldMachO> 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinescreateRuntimeDyldMachO(RTDyldMemoryManager *MM, bool ProcessAllSections) { 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<RuntimeDyldMachO> Dyld(new RuntimeDyldMachO(MM)); 70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld->setProcessAllSections(ProcessAllSections); 70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Dyld; 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 706dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesObjectImage *RuntimeDyld::loadObject(std::unique_ptr<ObjectFile> InputObject) { 70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectImage> InputImage; 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 709dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ObjectFile &Obj = *InputObject; 710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (InputObject->isELF()) { 712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject))); 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Dyld) 71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release(); 71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (InputObject->isMachO()) { 716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject))); 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Dyld) 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release(); 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Incompatible object format!"); 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 722dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Dyld->isCompatibleFile(&Obj)) 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Incompatible object format!"); 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld->loadObject(InputImage.get()); 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return InputImage.release(); 7276e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach} 7286e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 7293f23cef24fc9200def464bd4bce820678b5715deAndrew KaylorObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) { 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectImage> InputImage; 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines sys::fs::file_magic Type = sys::fs::identify_magic(InputBuffer->getBuffer()); 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Type) { 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::elf_relocatable: 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::elf_executable: 73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::elf_shared_object: 73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::elf_core: 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InputImage.reset(RuntimeDyldELF::createObjectImage(InputBuffer)); 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Dyld) 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld = createRuntimeDyldELF(MM, ProcessAllSections).release(); 74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_object: 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_executable: 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_core: 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_preload_executable: 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_dynamically_linked_shared_lib: 74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_dynamic_linker: 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_bundle: 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_dsym_companion: 75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InputImage.reset(RuntimeDyldMachO::createObjectImage(InputBuffer)); 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Dyld) 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld = createRuntimeDyldMachO(MM, ProcessAllSections).release(); 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::unknown: 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::bitcode: 75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::archive: 75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::coff_object: 76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::coff_import_library: 76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::pecoff_executable: 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::macho_universal_binary: 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case sys::fs::file_magic::windows_resource: 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Incompatible object format!"); 765cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 766cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Dyld->isCompatibleFormat(InputBuffer)) 76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines report_fatal_error("Incompatible object format!"); 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Dyld->loadObject(InputImage.get()); 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return InputImage.release(); 7726e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach} 7736e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 774b027105fa50c864d44873dc78daafb3db3ec9c14Jim Grosbachvoid *RuntimeDyld::getSymbolAddress(StringRef Name) { 7758e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (!Dyld) 776dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 7776e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach return Dyld->getSymbolAddress(Name); 7786e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach} 7796e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach 78035ed842773da41779d57d3ed23f440202d0be198Jim Grosbachuint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) { 7818e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor if (!Dyld) 7828e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor return 0; 78335ed842773da41779d57d3ed23f440202d0be198Jim Grosbach return Dyld->getSymbolLoadAddress(Name); 78435ed842773da41779d57d3ed23f440202d0be198Jim Grosbach} 78535ed842773da41779d57d3ed23f440202d0be198Jim Grosbach 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); } 787f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) { 78961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach Dyld->reassignSectionAddress(SectionID, Addr); 790f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach} 791f8c1c8465ff097ad5b87331b6d9a2576167f1402Jim Grosbach 792e940c1bb6c976539f07d6f440aeaacf7c25e1ddcJim Grosbachvoid RuntimeDyld::mapSectionAddress(const void *LocalAddress, 793020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach uint64_t TargetAddress) { 794020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach Dyld->mapSectionAddress(LocalAddress, TargetAddress); 795020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach} 796020f4e861a9a32059f76377e787703c92ba55a98Jim Grosbach 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RuntimeDyld::hasError() { return Dyld->hasError(); } 79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStringRef RuntimeDyld::getErrorString() { return Dyld->getErrorString(); } 800b3eecaf19e81f0cccffdeff940afbfd1a3754af2Jim Grosbach 801528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylorvoid RuntimeDyld::registerEHFrames() { 80243507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (Dyld) 80343507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Dyld->registerEHFrames(); 80443507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor} 80543507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor 80643507d026bef31100cb0c35614bcf419029a265bAndrew Kaylorvoid RuntimeDyld::deregisterEHFrames() { 80743507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor if (Dyld) 80843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor Dyld->deregisterEHFrames(); 809a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola} 810a2e40fbd624916c187a95ed76939ca7f02ed3e53Rafael Espindola 8116e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach} // end namespace llvm 812