RuntimeDyldMachO.cpp revision cf852dc49bfadb79a27455f8773dbfda2b96f4f6
1cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===-- RuntimeDyldMachO.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===// 2cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 3cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// The LLVM Compiler Infrastructure 4cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 5cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// This file is distributed under the University of Illinois Open Source 6cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// License. See LICENSE.TXT for details. 7cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 8cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===// 9cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 10cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Implementation of the MC-JIT runtime dynamic linker. 11cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// 12cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev//===----------------------------------------------------------------------===// 13cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 14cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#define DEBUG_TYPE "dyld" 15cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/OwningPtr.h" 16cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/StringRef.h" 17cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "llvm/ADT/STLExtras.h" 18cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev#include "RuntimeDyldImpl.h" 19cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm; 20cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevusing namespace llvm::object; 21cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 22cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevnamespace llvm { 23cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 24cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 25cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevresolveRelocation(uint8_t *Address, uint8_t *Value, bool isPCRel, 26cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Type, unsigned Size) { 27cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // This just dispatches to the proper target specific routine. 28cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (CPUType) { 29cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: assert(0 && "Unsupported CPU type!"); 30cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_x86_64: 31cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return resolveX86_64Relocation((uintptr_t)Address, (uintptr_t)Value, 32cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev isPCRel, Type, Size); 33cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case mach::CTM_ARM: 34cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return resolveARMRelocation((uintptr_t)Address, (uintptr_t)Value, 35cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev isPCRel, Type, Size); 36cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 37cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable(""); 38cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 39cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 40cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 41cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevresolveX86_64Relocation(uintptr_t Address, uintptr_t Value, 42cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isPCRel, unsigned Type, 43cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Size) { 44cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 45cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 46cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) 47cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: It seems this value needs to be adjusted by 4 for an effective PC 48cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // address. Is that expected? Only for branches, perhaps? 49cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= Address + 4; 50cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 51cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 52cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 53cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 54cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Unsigned: 55cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Branch: { 56cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 57cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 58cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *p = (uint8_t*)Address; 59cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 60cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 61cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 62cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 63cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 64cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 65cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Signed: 66cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOTLoad: 67cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_GOT: 68cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Subtractor: 69cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Signed1: 70cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Signed2: 71cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_Signed4: 72cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_X86_64_TLV: 73cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 74cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 75cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 76cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 77cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 78cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::resolveARMRelocation(uintptr_t Address, uintptr_t Value, 79cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isPCRel, unsigned Type, 80cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Size) { 81cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the relocation is PC-relative, the value to be encoded is the 82cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // pointer difference. 83cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (isPCRel) { 84cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= Address; 85cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // ARM PCRel relocations have an effective-PC offset of two instructions 86cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (four bytes in Thumb mode, 8 bytes in ARM mode). 87cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For now, assume ARM mode. 88cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value -= 8; 89cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 90cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 91cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch(Type) { 92cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 93cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 94cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Vanilla: { 95cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev llvm_unreachable("Invalid relocation type!"); 96cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask in the target value a byte at a time (we don't have an alignment 97cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // guarantee for the target address, so this is safest). 98cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *p = (uint8_t*)Address; 99cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i < Size; ++i) { 100cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p++ = (uint8_t)Value; 101cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 8; 102cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 103cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 104cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 105cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Branch24Bit: { 106cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value into the target address. We know instructions are 107cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // 32-bit aligned, so we can do it all at once. 108cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t *p = (uint32_t*)Address; 109cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The low two bits of the value are not encoded. 110cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value >>= 2; 111cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Mask the value to 24 bits. 112cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Value &= 0xffffff; 113cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: If the destination is a Thumb function (and the instruction 114cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // is a non-predicated BL instruction), we need to change it to a BLX 115cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // instruction instead. 116cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 117cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Insert the value into the instruction. 118cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *p = (*p & ~0xffffff) | Value; 119cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 120cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 121cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch22Bit: 122cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_ThumbBranch32Bit: 123cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_Half: 124cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_HalfDifference: 125cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Pair: 126cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_Difference: 127cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_LocalDifference: 128cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::RIT_ARM_PreboundLazyPointer: 129cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Relocation type not implemented yet!"); 130cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 131cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 132cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 133cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 134cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 135cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment32(const MachOObject *Obj, 136cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 137cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 138cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SegmentLoadCommand> SegmentLC; 139cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegmentLoadCommand(*SegmentLCI, SegmentLC); 140cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLC) 141cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 142cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 143cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { 144cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section> Sect; 145cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection(*SegmentLCI, SectNum, Sect); 146cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 147cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 148cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 149cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For the time being, we're only loading text segments. 150cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Sect->Flags != 0x80000400) 151cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 152cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 153cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Address and names of symbols in the section. 154cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev typedef std::pair<uint64_t, StringRef> SymbolEntry; 155cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SmallVector<SymbolEntry, 64> Symbols; 156cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Index of all the names, in this section or not. Used when we're 157cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // dealing with relocation entries. 158cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SmallVector<StringRef, 64> SymbolNames; 159cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 160cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SymbolTableEntry> STE; 161cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE); 162cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!STE) 163cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to read symbol: '" + Twine(i) + "'"); 164cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->SectionIndex > SegmentLC->NumSections) 165cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("invalid section index for symbol: '" + Twine(i) + "'"); 166cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the symbol name. 167cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 168cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymbolNames.push_back(Name); 169cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 170cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Just skip symbols not defined in this section. 171cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if ((unsigned)STE->SectionIndex - 1 != SectNum) 172cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 173cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 174cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Check the symbol type and flags. 175cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->Type != 0xF) // external, defined in this section. 176cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 177cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Flags == 0x8 marks a thumb function for ARM, which is fine as it 178cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // doesn't require any special handling here. 179cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->Flags != 0x0 && STE->Flags != 0x8) 180cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 181cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 182cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Remember the symbol. 183cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Symbols.push_back(SymbolEntry(STE->Value, Name)); 184cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 185cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Function sym: '" << Name << "' @ " << 186cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev (Sect->Address + STE->Value) << "\n"); 187cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 188cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Sort the symbols by address, just in case they didn't come in that way. 189cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev array_pod_sort(Symbols.begin(), Symbols.end()); 190cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 191cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If there weren't any functions (odd, but just in case...) 192cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Symbols.size()) 193cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 194cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 195cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Extract the function data. 196cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset, 197cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SegmentLC->FileSize).data(); 198cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0, e = Symbols.size() - 1; i != e; ++i) { 199cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t StartOffset = Sect->Address + Symbols[i].first; 200cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t EndOffset = Symbols[i + 1].first - 1; 201cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Extracting function: " << Symbols[i].second 202cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from [" << StartOffset << ", " << EndOffset << "]\n"); 203cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev extractFunction(Symbols[i].second, Base + StartOffset, Base + EndOffset); 204cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 205cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The last symbol we do after since the end address is calculated 206cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // differently because there is no next symbol to reference. 207cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t StartOffset = Symbols[Symbols.size() - 1].first; 208cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t EndOffset = Sect->Size - 1; 209cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Extracting function: " << Symbols[Symbols.size()-1].second 210cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from [" << StartOffset << ", " << EndOffset << "]\n"); 211cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev extractFunction(Symbols[Symbols.size()-1].second, 212cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Base + StartOffset, Base + EndOffset); 213cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 214cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Now extract the relocation information for each function and process it. 215cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 216cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 217cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 218cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 219cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 220cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 221cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 222cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 223cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 224cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Look for the function containing the address. This is used for JIT 225cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // code, so the number of functions in section is almost always going 226cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // to be very small (usually just one), so until we have use cases 227cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // where that's not true, just use a trivial linear search. 228cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned SymbolNum; 229cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned NumSymbols = Symbols.size(); 230cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev assert(NumSymbols > 0 && Symbols[0].first <= Offset && 231cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev "No symbol containing relocation!"); 232cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (SymbolNum = 0; SymbolNum < NumSymbols - 1; ++SymbolNum) 233cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Symbols[SymbolNum + 1].first > Offset) 234cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 235cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Adjust the offset to be relative to the symbol. 236cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Offset -= Symbols[SymbolNum].first; 237cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the name of the symbol containing the relocation. 238cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef TargetName = SymbolNames[SymbolNum]; 239cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 240cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 241cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 242cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 243cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 244cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 245cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Some targets (ARM) use internal relocations even for 246cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // externally visible symbols, if the definition is in the same 247cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // file as the reference. We need to convert those back to by-name 248cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // references. We can resolve the address based on the section 249cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset and see if we have a symbol at that address. If we do, 250cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // use that; otherwise, puke. 251cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!isExtern) 252cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Internal relocations not supported."); 253cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 254cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef SourceName = SymbolNames[SourceNum]; 255cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 256cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Get the relocation addend from the target address. 257cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 258cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Now store the relocation information. Associate it with the source 259cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // symbol. 260cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Relocations[SourceName].push_back(RelocationEntry(TargetName, 261cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Offset, 262cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RE->Word1, 263cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 0 /*Addend*/)); 264cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Relocation at '" << TargetName << "' + " << Offset 265cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from '" << SourceName << "(Word1: " 266cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << format("0x%x", RE->Word1) << ")\n"); 267cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 268cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 269cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 270cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 271cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 272cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 273cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO:: 274cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil MalyshevloadSegment64(const MachOObject *Obj, 275cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI, 276cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) { 277cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Segment64LoadCommand> Segment64LC; 278cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC); 279cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Segment64LC) 280cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load segment load command"); 281cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 282cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) { 283cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Section64> Sect; 284cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSection64(*SegmentLCI, SectNum, Sect); 285cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Sect) 286cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load section: '" + Twine(SectNum) + "'"); 287cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 288cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: For the time being, we're only loading text segments. 289cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Sect->Flags != 0x80000400) 290cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 291cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 292cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Address and names of symbols in the section. 293cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev typedef std::pair<uint64_t, StringRef> SymbolEntry; 294cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SmallVector<SymbolEntry, 64> Symbols; 295cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Index of all the names, in this section or not. Used when we're 296cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // dealing with relocation entries. 297cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SmallVector<StringRef, 64> SymbolNames; 298cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) { 299cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::Symbol64TableEntry> STE; 300cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE); 301cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!STE) 302cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to read symbol: '" + Twine(i) + "'"); 303cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->SectionIndex > Segment64LC->NumSections) 304cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("invalid section index for symbol: '" + Twine(i) + "'"); 305cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the symbol name. 306cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Name = Obj->getStringAtIndex(STE->StringIndex); 307cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymbolNames.push_back(Name); 308cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 309cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Just skip symbols not defined in this section. 310cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if ((unsigned)STE->SectionIndex - 1 != SectNum) 311cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 312cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 313cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Check the symbol type and flags. 314cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->Type != 0xF) // external, defined in this section. 315cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 316cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (STE->Flags != 0x0) 317cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 318cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 319cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Remember the symbol. 320cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Symbols.push_back(SymbolEntry(STE->Value, Name)); 321cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 322cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Function sym: '" << Name << "' @ " << 323cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev (Sect->Address + STE->Value) << "\n"); 324cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 325cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Sort the symbols by address, just in case they didn't come in that way. 326cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev array_pod_sort(Symbols.begin(), Symbols.end()); 327cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 328cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If there weren't any functions (odd, but just in case...) 329cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Symbols.size()) 330cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev continue; 331cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 332cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Extract the function data. 333cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset, 334cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Segment64LC->FileSize).data(); 335cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0, e = Symbols.size() - 1; i != e; ++i) { 336cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t StartOffset = Sect->Address + Symbols[i].first; 337cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t EndOffset = Symbols[i + 1].first - 1; 338cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Extracting function: " << Symbols[i].second 339cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from [" << StartOffset << ", " << EndOffset << "]\n"); 340cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev extractFunction(Symbols[i].second, Base + StartOffset, Base + EndOffset); 341cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 342cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // The last symbol we do after since the end address is calculated 343cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // differently because there is no next symbol to reference. 344cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t StartOffset = Symbols[Symbols.size() - 1].first; 345cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint64_t EndOffset = Sect->Size - 1; 346cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Extracting function: " << Symbols[Symbols.size()-1].second 347cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from [" << StartOffset << ", " << EndOffset << "]\n"); 348cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev extractFunction(Symbols[Symbols.size()-1].second, 349cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Base + StartOffset, Base + EndOffset); 350cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 351cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Now extract the relocation information for each function and process it. 352cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned j = 0; j != Sect->NumRelocationTableEntries; ++j) { 353cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::RelocationEntry> RE; 354cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadRelocationEntry(Sect->RelocationTableOffset, j, RE); 355cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (RE->Word0 & macho::RF_Scattered) 356cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("NOT YET IMPLEMENTED: scattered relocations."); 357cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Word0 of the relocation is the offset into the section where the 358cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // relocation should be applied. We need to translate that into an 359cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // offset into a function since that's our atom. 360cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t Offset = RE->Word0; 361cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Look for the function containing the address. This is used for JIT 362cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // code, so the number of functions in section is almost always going 363cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // to be very small (usually just one), so until we have use cases 364cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // where that's not true, just use a trivial linear search. 365cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned SymbolNum; 366cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned NumSymbols = Symbols.size(); 367cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev assert(NumSymbols > 0 && Symbols[0].first <= Offset && 368cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev "No symbol containing relocation!"); 369cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (SymbolNum = 0; SymbolNum < NumSymbols - 1; ++SymbolNum) 370cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Symbols[SymbolNum + 1].first > Offset) 371cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 372cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Adjust the offset to be relative to the symbol. 373cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Offset -= Symbols[SymbolNum].first; 374cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the name of the symbol containing the relocation. 375cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef TargetName = SymbolNames[SymbolNum]; 376cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 377cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isExtern = (RE->Word1 >> 27) & 1; 378cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Figure out the source symbol of the relocation. If isExtern is true, 379cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // this relocation references the symbol table, otherwise it references 380cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // a section in the same object, numbered from 1 through NumSections 381cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // (SectionBases is [0, NumSections-1]). 382cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!isExtern) 383cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("Internal relocations not supported."); 384cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint32_t SourceNum = RE->Word1 & 0xffffff; // 24-bit value 385cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef SourceName = SymbolNames[SourceNum]; 386cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 387cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Get the relocation addend from the target address. 388cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 389cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Now store the relocation information. Associate it with the source 390cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // symbol. 391cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Relocations[SourceName].push_back(RelocationEntry(TargetName, 392cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Offset, 393cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RE->Word1, 394cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 0 /*Addend*/)); 395cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Relocation at '" << TargetName << "' + " << Offset 396cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from '" << SourceName << "(Word1: " 397cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << format("0x%x", RE->Word1) << ")\n"); 398cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 399cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 400cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 401cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 402cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 403cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::loadObject(MemoryBuffer *InputBuffer) { 404cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // If the linker is in an error state, don't do anything. 405cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (hasError()) 406cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 407cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the Mach-O wrapper object. 408cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev std::string ErrorStr; 409cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev OwningPtr<MachOObject> Obj( 410cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr)); 411cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!Obj) 412cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load object: '" + ErrorStr + "'"); 413cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 414cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Get the CPU type information from the header. 415cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const macho::Header &Header = Obj->getHeader(); 416cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 417cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: Error checking that the loaded object is compatible with 418cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // the system we're running on. 419cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUType = Header.CPUType; 420cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev CPUSubtype = Header.CPUSubtype; 421cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 422cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Validate that the load commands match what we expect. 423cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0, 424cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev *DysymtabLCI = 0; 425cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 426cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i); 427cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev switch (LCI.Command.Type) { 428cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment: 429cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Segment64: 430cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI) 431cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple segments)"); 432cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SegmentLCI = &LCI; 433cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 434cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Symtab: 435cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SymtabLCI) 436cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 437cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymtabLCI = &LCI; 438cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 439cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev case macho::LCT_Dysymtab: 440cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) 441cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (multiple symbol tables)"); 442cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DysymtabLCI = &LCI; 443cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev break; 444cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev default: 445cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unexpected input object (unexpected load command"); 446cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 447cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 448cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 449cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLCI) 450cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("no symbol table found in object"); 451cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SegmentLCI) 452cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("no symbol table found in object"); 453cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 454cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read and register the symbol table data. 455cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; 456cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); 457cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!SymtabLC) 458cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load symbol table load command"); 459cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->RegisterStringTable(*SymtabLC); 460cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 461cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Read the dynamic link-edit information, if present (not present in static 462cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // objects). 463cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (DysymtabLCI) { 464cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC; 465cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC); 466cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (!DysymtabLC) 467cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return Error("unable to load dynamic link-exit load command"); 468cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 469cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // FIXME: We don't support anything interesting yet. 470cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->LocalSymbolsIndex != 0) 471cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: local symbol entries"); 472cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->ExternalSymbolsIndex != 0) 473cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: non-external symbol entries"); 474cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries) 475cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// return Error("NOT YET IMPLEMENTED: undefined symbol entries"); 476cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 477cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 478cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Load the segment load command. 479cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (SegmentLCI->Command.Type == macho::LCT_Segment) { 480cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC)) 481cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 482cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } else { 483cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC)) 484cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return true; 485cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 486cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 487cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 488cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 489cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 490cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// Assign an address to a symbol name and resolve all the relocations 491cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev// associated with it. 492cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevvoid RuntimeDyldMachO::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 493cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev // Assign the address in our symbol table. 494cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev SymbolTable[Name] = Addr; 495cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 496cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RelocationList &Relocs = Relocations[Name]; 497cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 498cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RelocationEntry &RE = Relocs[i]; 499cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev uint8_t *Target = SymbolTable[RE.Target] + RE.Offset; 500cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev bool isPCRel = (RE.Data >> 24) & 1; 501cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Type = (RE.Data >> 28) & 0xf; 502cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev unsigned Size = 1 << ((RE.Data >> 25) & 3); 503cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 504cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev DEBUG(dbgs() << "Resolving relocation at '" << RE.Target 505cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << "' + " << RE.Offset << " (" << format("%p", Target) << ")" 506cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << " from '" << Name << " (" << format("%p", Addr) << ")" 507cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << "(" << (isPCRel ? "pcrel" : "absolute") 508cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev << ", type: " << Type << ", Size: " << Size << ").\n"); 509cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 510cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev resolveRelocation(Target, Addr, isPCRel, Type, Size); 511cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev RE.isResolved = true; 512cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev } 513cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 514cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 515cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshevbool RuntimeDyldMachO::isKnownFormat(const MemoryBuffer *InputBuffer) { 516cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev StringRef Magic = InputBuffer->getBuffer().slice(0, 4); 517cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCE") return true; 518cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCE\xFA\xED\xFE") return true; 519cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xFE\xED\xFA\xCF") return true; 520cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev if (Magic == "\xCF\xFA\xED\xFE") return true; 521cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev return false; 522cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} 523cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev 524cf852dc49bfadb79a27455f8773dbfda2b96f4f6Danil Malyshev} // end namespace llvm 525