[llvm-commits] [llvm] r128173 - /llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
Jim Grosbach
grosbach at apple.com
Wed Mar 23 15:06:06 PDT 2011
Author: grosbach
Date: Wed Mar 23 17:06:06 2011
New Revision: 128173
URL: http://llvm.org/viewvc/llvm-project?rev=128173&view=rev
Log:
Split out relocation resolution into target-specific bits.
Modified:
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=128173&r1=128172&r2=128173&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Wed Mar 23 17:06:06 2011
@@ -31,6 +31,9 @@
namespace llvm {
class RuntimeDyldImpl {
+ unsigned CPUType;
+ unsigned CPUSubtype;
+
// Master symbol table. As modules are loaded and external symbols are
// resolved, their addresses are stored here.
StringMap<void*> SymbolTable;
@@ -52,6 +55,10 @@
bool resolveRelocation(uint32_t BaseSection, macho::RelocationEntry RE,
SmallVectorImpl<void *> &SectionBases,
SmallVectorImpl<StringRef> &SymbolNames);
+ bool resolveX86_64Relocation(intptr_t Address, intptr_t Value, bool isPCRel,
+ unsigned Type, unsigned Size);
+ bool resolveARMRelocation(intptr_t Address, intptr_t Value, bool isPCRel,
+ unsigned Type, unsigned Size);
bool loadSegment32(const MachOObject *Obj,
const MachOObject::LoadCommandInfo *SegmentLCI,
@@ -128,6 +135,20 @@
Value = (intptr_t)SectionBases[SymbolNum - 1];
}
+ unsigned Size = 1 << Log2Size;
+ switch (CPUType) {
+ default: assert(0 && "Unsupported CPU type!");
+ case mach::CTM_x86_64:
+ return resolveX86_64Relocation(Address, Value, isPCRel, Type, Size);
+ case mach::CTM_ARM:
+ return resolveARMRelocation(Address, Value, isPCRel, Type, Size);
+ }
+ llvm_unreachable("");
+}
+
+bool RuntimeDyldImpl::resolveX86_64Relocation(intptr_t Address, intptr_t Value,
+ bool isPCRel, unsigned Type,
+ unsigned Size) {
// If the relocation is PC-relative, the value to be encoded is the
// pointer difference.
if (isPCRel)
@@ -142,9 +163,8 @@
case macho::RIT_X86_64_Branch: {
// Mask in the target value a byte at a time (we don't have an alignment
// guarantee for the target address, so this is safest).
- unsigned Len = 1 << Log2Size;
uint8_t *p = (uint8_t*)Address;
- for (unsigned i = 0; i < Len; ++i) {
+ for (unsigned i = 0; i < Size; ++i) {
*p++ = (uint8_t)Value;
Value >>= 8;
}
@@ -163,6 +183,46 @@
return false;
}
+bool RuntimeDyldImpl::resolveARMRelocation(intptr_t Address, intptr_t Value,
+ bool isPCRel, unsigned Type,
+ unsigned Size) {
+ // If the relocation is PC-relative, the value to be encoded is the
+ // pointer difference.
+ if (isPCRel) {
+ Value -= Address;
+ // ARM PCRel relocations have an effective-PC offset of two instructions
+ // (four bytes in Thumb mode, 8 bytes in ARM mode).
+ // FIXME: For now, assume ARM mode.
+ Value -= 8;
+ }
+
+ switch(Type) {
+ default:
+ case macho::RIT_Vanilla: {
+ llvm_unreachable("Invalid relocation type!");
+ // Mask in the target value a byte at a time (we don't have an alignment
+ // guarantee for the target address, so this is safest).
+ uint8_t *p = (uint8_t*)Address;
+ for (unsigned i = 0; i < Size; ++i) {
+ *p++ = (uint8_t)Value;
+ Value >>= 8;
+ }
+ return false;
+ }
+ case macho::RIT_Pair:
+ case macho::RIT_Difference:
+ case macho::RIT_ARM_LocalDifference:
+ case macho::RIT_ARM_PreboundLazyPointer:
+ case macho::RIT_ARM_Branch24Bit:
+ case macho::RIT_ARM_ThumbBranch22Bit:
+ case macho::RIT_ARM_ThumbBranch32Bit:
+ case macho::RIT_ARM_Half:
+ case macho::RIT_ARM_HalfDifference:
+ return Error("Relocation type not implemented yet!");
+ }
+ return false;
+}
+
bool RuntimeDyldImpl::
loadSegment32(const MachOObject *Obj,
const MachOObject::LoadCommandInfo *SegmentLCI,
@@ -352,10 +412,18 @@
if (!Obj)
return Error("unable to load object: '" + ErrorStr + "'");
+ // Get the CPU type information from the header.
+ const macho::Header &Header = Obj->getHeader();
+
+ // FIXME: Error checking that the loaded object is compatible with
+ // the system we're running on.
+ CPUType = Header.CPUType;
+ CPUSubtype = Header.CPUSubtype;
+
// Validate that the load commands match what we expect.
const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
*DysymtabLCI = 0;
- for (unsigned i = 0; i != Obj->getHeader().NumLoadCommands; ++i) {
+ for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
switch (LCI.Command.Type) {
case macho::LCT_Segment:
More information about the llvm-commits
mailing list