mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
ae80577a24
Add handling for tracking the relocations on symbols and resolving them. Keep track of the relocations even after they are resolved so that if the RuntimeDyld client moves the object, it can update the address and any relocations to that object will be updated. For our trival object file load/run test harness (llvm-rtdyld), this enables relocations between functions located in the same object module. It should be trivially extendable to load multiple objects with mutual references. As a simple example, the following now works (running on x86_64 Darwin 10.6): $ cat t.c int bar() { return 65; } int main() { return bar(); } $ clang t.c -fno-asynchronous-unwind-tables -o t.o -c $ otool -vt t.o t.o: (__TEXT,__text) section _bar: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp,%rbp 0000000000000004 movl $0x00000041,%eax 0000000000000009 popq %rbp 000000000000000a ret 000000000000000b nopl 0x00(%rax,%rax) _main: 0000000000000010 pushq %rbp 0000000000000011 movq %rsp,%rbp 0000000000000014 subq $0x10,%rsp 0000000000000018 movl $0x00000000,0xfc(%rbp) 000000000000001f callq 0x00000024 0000000000000024 addq $0x10,%rsp 0000000000000028 popq %rbp 0000000000000029 ret $ llvm-rtdyld t.o -debug-only=dyld ; echo $? Function sym: '_bar' @ 0 Function sym: '_main' @ 16 Extracting function: _bar from [0, 15] allocated to 0x100153000 Extracting function: _main from [16, 41] allocated to 0x100154000 Relocation at '_main' + 16 from '_bar(Word1: 0x2d000000) Resolving relocation at '_main' + 16 (0x100154010) from '_bar (0x100153000)(pcrel, type: 2, Size: 4). loaded '_main' at: 0x100154000 65 $ llvm-svn: 129388
76 lines
2.7 KiB
C++
76 lines
2.7 KiB
C++
//===-- RuntimeDyld.h - 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Interface for the runtime dynamic linker facilities of the MC-JIT.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_RUNTIME_DYLD_H
|
|
#define LLVM_RUNTIME_DYLD_H
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Memory.h"
|
|
|
|
namespace llvm {
|
|
|
|
class RuntimeDyldImpl;
|
|
class MemoryBuffer;
|
|
|
|
// RuntimeDyld clients often want to handle the memory management of
|
|
// what gets placed where. For JIT clients, this is an abstraction layer
|
|
// over the JITMemoryManager, which references objects by their source
|
|
// representations in LLVM IR.
|
|
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
|
|
// for the varying types of objects to be allocated.
|
|
class RTDyldMemoryManager {
|
|
RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
|
|
void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT
|
|
public:
|
|
RTDyldMemoryManager() {}
|
|
virtual ~RTDyldMemoryManager();
|
|
|
|
// Allocate ActualSize bytes, or more, for the named function. Return
|
|
// a pointer to the allocated memory and update Size to reflect how much
|
|
// memory was acutally allocated.
|
|
virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0;
|
|
|
|
// Mark the end of the function, including how much of the allocated
|
|
// memory was actually used.
|
|
virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart,
|
|
uint8_t *FunctionEnd) = 0;
|
|
};
|
|
|
|
class RuntimeDyld {
|
|
RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT
|
|
void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT
|
|
|
|
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
|
|
// interface.
|
|
RuntimeDyldImpl *Dyld;
|
|
public:
|
|
RuntimeDyld(RTDyldMemoryManager*);
|
|
~RuntimeDyld();
|
|
|
|
bool loadObject(MemoryBuffer *InputBuffer);
|
|
// Get the address of our local copy of the symbol. This may or may not
|
|
// be the address used for relocation (clients can copy the data around
|
|
// and resolve relocatons based on where they put it).
|
|
void *getSymbolAddress(StringRef Name);
|
|
// Resolve the relocations for all symbols we currently know about.
|
|
void resolveRelocations();
|
|
// Change the address associated with a symbol when resolving relocations.
|
|
// Any relocations already associated with the symbol will be re-resolved.
|
|
void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
|
|
StringRef getErrorString();
|
|
};
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif
|