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