forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			96 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // Implementation of the MC-JIT runtime dynamic linker.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #define DEBUG_TYPE "dyld"
 | |
| #include "RuntimeDyldImpl.h"
 | |
| using namespace llvm;
 | |
| using namespace llvm::object;
 | |
| 
 | |
| // Empty out-of-line virtual destructor as the key function.
 | |
| RTDyldMemoryManager::~RTDyldMemoryManager() {}
 | |
| RuntimeDyldImpl::~RuntimeDyldImpl() {}
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
 | |
|                                       uint8_t *EndAddress) {
 | |
|   // Allocate memory for the function via the memory manager.
 | |
|   uintptr_t Size = EndAddress - StartAddress + 1;
 | |
|   uintptr_t AllocSize = Size;
 | |
|   uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
 | |
|   assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
 | |
|          "Memory manager failed to allocate enough memory!");
 | |
|   // Copy the function payload into the memory block.
 | |
|   memcpy(Mem, StartAddress, Size);
 | |
|   MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
 | |
|   // Remember where we put it.
 | |
|   Functions[Name] = sys::MemoryBlock(Mem, Size);
 | |
|   // Default the assigned address for this symbol to wherever this
 | |
|   // allocated it.
 | |
|   SymbolTable[Name] = Mem;
 | |
|   DEBUG(dbgs() << "    allocated to [" << Mem << ", " << Mem + Size << "]\n");
 | |
| }
 | |
| 
 | |
| // Resolve the relocations for all symbols we currently know about.
 | |
| void RuntimeDyldImpl::resolveRelocations() {
 | |
|   // Just iterate over the symbols in our symbol table and assign their
 | |
|   // addresses.
 | |
|   StringMap<uint8_t*>::iterator i = SymbolTable.begin();
 | |
|   StringMap<uint8_t*>::iterator e = SymbolTable.end();
 | |
|   for (;i != e; ++i)
 | |
|     reassignSymbolAddress(i->getKey(), i->getValue());
 | |
| }
 | |
| 
 | |
| //===----------------------------------------------------------------------===//
 | |
| // RuntimeDyld class implementation
 | |
| RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
 | |
|   Dyld = 0;
 | |
|   MM = mm;
 | |
| }
 | |
| 
 | |
| RuntimeDyld::~RuntimeDyld() {
 | |
|   delete Dyld;
 | |
| }
 | |
| 
 | |
| bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
 | |
|   if (!Dyld) {
 | |
|     if (RuntimeDyldMachO::isKnownFormat(InputBuffer))
 | |
|       Dyld = new RuntimeDyldMachO(MM);
 | |
|     else
 | |
|       report_fatal_error("Unknown object format!");
 | |
|   } else {
 | |
|     if(!Dyld->isCompatibleFormat(InputBuffer))
 | |
|       report_fatal_error("Incompatible object format!");
 | |
|   }
 | |
| 
 | |
|   return Dyld->loadObject(InputBuffer);
 | |
| }
 | |
| 
 | |
| void *RuntimeDyld::getSymbolAddress(StringRef Name) {
 | |
|   return Dyld->getSymbolAddress(Name);
 | |
| }
 | |
| 
 | |
| void RuntimeDyld::resolveRelocations() {
 | |
|   Dyld->resolveRelocations();
 | |
| }
 | |
| 
 | |
| void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
 | |
|   Dyld->reassignSymbolAddress(Name, Addr);
 | |
| }
 | |
| 
 | |
| StringRef RuntimeDyld::getErrorString() {
 | |
|   return Dyld->getErrorString();
 | |
| }
 | |
| 
 | |
| } // end namespace llvm
 |