1 //===- MachOObjectFile.cpp - Mach-O object file binding -------------------===// 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 // This file defines the MachOObjectFile class, which binds the MachOObject 11 // class to the generic ObjectFile wrapper. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/None.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/StringSwitch.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/ADT/Twine.h" 23 #include "llvm/BinaryFormat/MachO.h" 24 #include "llvm/Object/Error.h" 25 #include "llvm/Object/MachO.h" 26 #include "llvm/Object/ObjectFile.h" 27 #include "llvm/Object/SymbolicFile.h" 28 #include "llvm/Support/DataExtractor.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/Error.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/Format.h" 33 #include "llvm/Support/Host.h" 34 #include "llvm/Support/LEB128.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include "llvm/Support/SwapByteOrder.h" 37 #include "llvm/Support/raw_ostream.h" 38 #include <algorithm> 39 #include <cassert> 40 #include <cstddef> 41 #include <cstdint> 42 #include <cstring> 43 #include <limits> 44 #include <list> 45 #include <memory> 46 #include <string> 47 #include <system_error> 48 49 using namespace llvm; 50 using namespace object; 51 52 namespace { 53 54 struct section_base { 55 char sectname[16]; 56 char segname[16]; 57 }; 58 59 } // end anonymous namespace 60 61 static Error malformedError(const Twine &Msg) { 62 return make_error<GenericBinaryError>("truncated or malformed object (" + 63 Msg + ")", 64 object_error::parse_failed); 65 } 66 67 // FIXME: Replace all uses of this function with getStructOrErr. 68 template <typename T> 69 static T getStruct(const MachOObjectFile &O, const char *P) { 70 // Don't read before the beginning or past the end of the file 71 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end()) 72 report_fatal_error("Malformed MachO file."); 73 74 T Cmd; 75 memcpy(&Cmd, P, sizeof(T)); 76 if (O.isLittleEndian() != sys::IsLittleEndianHost) 77 MachO::swapStruct(Cmd); 78 return Cmd; 79 } 80 81 template <typename T> 82 static Expected<T> getStructOrErr(const MachOObjectFile &O, const char *P) { 83 // Don't read before the beginning or past the end of the file 84 if (P < O.getData().begin() || P + sizeof(T) > O.getData().end()) 85 return malformedError("Structure read out-of-range"); 86 87 T Cmd; 88 memcpy(&Cmd, P, sizeof(T)); 89 if (O.isLittleEndian() != sys::IsLittleEndianHost) 90 MachO::swapStruct(Cmd); 91 return Cmd; 92 } 93 94 static const char * 95 getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, 96 unsigned Sec) { 97 uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr); 98 99 bool Is64 = O.is64Bit(); 100 unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) : 101 sizeof(MachO::segment_command); 102 unsigned SectionSize = Is64 ? sizeof(MachO::section_64) : 103 sizeof(MachO::section); 104 105 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; 106 return reinterpret_cast<const char*>(SectionAddr); 107 } 108 109 static const char *getPtr(const MachOObjectFile &O, size_t Offset) { 110 return O.getData().substr(Offset, 1).data(); 111 } 112 113 static MachO::nlist_base 114 getSymbolTableEntryBase(const MachOObjectFile &O, DataRefImpl DRI) { 115 const char *P = reinterpret_cast<const char *>(DRI.p); 116 return getStruct<MachO::nlist_base>(O, P); 117 } 118 119 static StringRef parseSegmentOrSectionName(const char *P) { 120 if (P[15] == 0) 121 // Null terminated. 122 return P; 123 // Not null terminated, so this is a 16 char string. 124 return StringRef(P, 16); 125 } 126 127 static unsigned getCPUType(const MachOObjectFile &O) { 128 return O.getHeader().cputype; 129 } 130 131 static uint32_t 132 getPlainRelocationAddress(const MachO::any_relocation_info &RE) { 133 return RE.r_word0; 134 } 135 136 static unsigned 137 getScatteredRelocationAddress(const MachO::any_relocation_info &RE) { 138 return RE.r_word0 & 0xffffff; 139 } 140 141 static bool getPlainRelocationPCRel(const MachOObjectFile &O, 142 const MachO::any_relocation_info &RE) { 143 if (O.isLittleEndian()) 144 return (RE.r_word1 >> 24) & 1; 145 return (RE.r_word1 >> 7) & 1; 146 } 147 148 static bool 149 getScatteredRelocationPCRel(const MachO::any_relocation_info &RE) { 150 return (RE.r_word0 >> 30) & 1; 151 } 152 153 static unsigned getPlainRelocationLength(const MachOObjectFile &O, 154 const MachO::any_relocation_info &RE) { 155 if (O.isLittleEndian()) 156 return (RE.r_word1 >> 25) & 3; 157 return (RE.r_word1 >> 5) & 3; 158 } 159 160 static unsigned 161 getScatteredRelocationLength(const MachO::any_relocation_info &RE) { 162 return (RE.r_word0 >> 28) & 3; 163 } 164 165 static unsigned getPlainRelocationType(const MachOObjectFile &O, 166 const MachO::any_relocation_info &RE) { 167 if (O.isLittleEndian()) 168 return RE.r_word1 >> 28; 169 return RE.r_word1 & 0xf; 170 } 171 172 static uint32_t getSectionFlags(const MachOObjectFile &O, 173 DataRefImpl Sec) { 174 if (O.is64Bit()) { 175 MachO::section_64 Sect = O.getSection64(Sec); 176 return Sect.flags; 177 } 178 MachO::section Sect = O.getSection(Sec); 179 return Sect.flags; 180 } 181 182 static Expected<MachOObjectFile::LoadCommandInfo> 183 getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr, 184 uint32_t LoadCommandIndex) { 185 if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) { 186 if (CmdOrErr->cmdsize + Ptr > Obj.getData().end()) 187 return malformedError("load command " + Twine(LoadCommandIndex) + 188 " extends past end of file"); 189 if (CmdOrErr->cmdsize < 8) 190 return malformedError("load command " + Twine(LoadCommandIndex) + 191 " with size less than 8 bytes"); 192 return MachOObjectFile::LoadCommandInfo({Ptr, *CmdOrErr}); 193 } else 194 return CmdOrErr.takeError(); 195 } 196 197 static Expected<MachOObjectFile::LoadCommandInfo> 198 getFirstLoadCommandInfo(const MachOObjectFile &Obj) { 199 unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64) 200 : sizeof(MachO::mach_header); 201 if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds) 202 return malformedError("load command 0 extends past the end all load " 203 "commands in the file"); 204 return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0); 205 } 206 207 static Expected<MachOObjectFile::LoadCommandInfo> 208 getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, 209 const MachOObjectFile::LoadCommandInfo &L) { 210 unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64) 211 : sizeof(MachO::mach_header); 212 if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) > 213 Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds) 214 return malformedError("load command " + Twine(LoadCommandIndex + 1) + 215 " extends past the end all load commands in the file"); 216 return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1); 217 } 218 219 template <typename T> 220 static void parseHeader(const MachOObjectFile &Obj, T &Header, 221 Error &Err) { 222 if (sizeof(T) > Obj.getData().size()) { 223 Err = malformedError("the mach header extends past the end of the " 224 "file"); 225 return; 226 } 227 if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0))) 228 Header = *HeaderOrErr; 229 else 230 Err = HeaderOrErr.takeError(); 231 } 232 233 // This is used to check for overlapping of Mach-O elements. 234 struct MachOElement { 235 uint64_t Offset; 236 uint64_t Size; 237 const char *Name; 238 }; 239 240 static Error checkOverlappingElement(std::list<MachOElement> &Elements, 241 uint64_t Offset, uint64_t Size, 242 const char *Name) { 243 if (Size == 0) 244 return Error::success(); 245 246 for (auto it=Elements.begin() ; it != Elements.end(); ++it) { 247 auto E = *it; 248 if ((Offset >= E.Offset && Offset < E.Offset + E.Size) || 249 (Offset + Size > E.Offset && Offset + Size < E.Offset + E.Size) || 250 (Offset <= E.Offset && Offset + Size >= E.Offset + E.Size)) 251 return malformedError(Twine(Name) + " at offset " + Twine(Offset) + 252 " with a size of " + Twine(Size) + ", overlaps " + 253 E.Name + " at offset " + Twine(E.Offset) + " with " 254 "a size of " + Twine(E.Size)); 255 auto nt = it; 256 nt++; 257 if (nt != Elements.end()) { 258 auto N = *nt; 259 if (Offset + Size <= N.Offset) { 260 Elements.insert(nt, {Offset, Size, Name}); 261 return Error::success(); 262 } 263 } 264 } 265 Elements.push_back({Offset, Size, Name}); 266 return Error::success(); 267 } 268 269 // Parses LC_SEGMENT or LC_SEGMENT_64 load command, adds addresses of all 270 // sections to \param Sections, and optionally sets 271 // \param IsPageZeroSegment to true. 272 template <typename Segment, typename Section> 273 static Error parseSegmentLoadCommand( 274 const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &Load, 275 SmallVectorImpl<const char *> &Sections, bool &IsPageZeroSegment, 276 uint32_t LoadCommandIndex, const char *CmdName, uint64_t SizeOfHeaders, 277 std::list<MachOElement> &Elements) { 278 const unsigned SegmentLoadSize = sizeof(Segment); 279 if (Load.C.cmdsize < SegmentLoadSize) 280 return malformedError("load command " + Twine(LoadCommandIndex) + 281 " " + CmdName + " cmdsize too small"); 282 if (auto SegOrErr = getStructOrErr<Segment>(Obj, Load.Ptr)) { 283 Segment S = SegOrErr.get(); 284 const unsigned SectionSize = sizeof(Section); 285 uint64_t FileSize = Obj.getData().size(); 286 if (S.nsects > std::numeric_limits<uint32_t>::max() / SectionSize || 287 S.nsects * SectionSize > Load.C.cmdsize - SegmentLoadSize) 288 return malformedError("load command " + Twine(LoadCommandIndex) + 289 " inconsistent cmdsize in " + CmdName + 290 " for the number of sections"); 291 for (unsigned J = 0; J < S.nsects; ++J) { 292 const char *Sec = getSectionPtr(Obj, Load, J); 293 Sections.push_back(Sec); 294 Section s = getStruct<Section>(Obj, Sec); 295 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 296 Obj.getHeader().filetype != MachO::MH_DSYM && 297 s.flags != MachO::S_ZEROFILL && 298 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && 299 s.offset > FileSize) 300 return malformedError("offset field of section " + Twine(J) + " in " + 301 CmdName + " command " + Twine(LoadCommandIndex) + 302 " extends past the end of the file"); 303 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 304 Obj.getHeader().filetype != MachO::MH_DSYM && 305 s.flags != MachO::S_ZEROFILL && 306 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && S.fileoff == 0 && 307 s.offset < SizeOfHeaders && s.size != 0) 308 return malformedError("offset field of section " + Twine(J) + " in " + 309 CmdName + " command " + Twine(LoadCommandIndex) + 310 " not past the headers of the file"); 311 uint64_t BigSize = s.offset; 312 BigSize += s.size; 313 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 314 Obj.getHeader().filetype != MachO::MH_DSYM && 315 s.flags != MachO::S_ZEROFILL && 316 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && 317 BigSize > FileSize) 318 return malformedError("offset field plus size field of section " + 319 Twine(J) + " in " + CmdName + " command " + 320 Twine(LoadCommandIndex) + 321 " extends past the end of the file"); 322 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 323 Obj.getHeader().filetype != MachO::MH_DSYM && 324 s.flags != MachO::S_ZEROFILL && 325 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL && 326 s.size > S.filesize) 327 return malformedError("size field of section " + 328 Twine(J) + " in " + CmdName + " command " + 329 Twine(LoadCommandIndex) + 330 " greater than the segment"); 331 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 332 Obj.getHeader().filetype != MachO::MH_DSYM && s.size != 0 && 333 s.addr < S.vmaddr) 334 return malformedError("addr field of section " + Twine(J) + " in " + 335 CmdName + " command " + Twine(LoadCommandIndex) + 336 " less than the segment's vmaddr"); 337 BigSize = s.addr; 338 BigSize += s.size; 339 uint64_t BigEnd = S.vmaddr; 340 BigEnd += S.vmsize; 341 if (S.vmsize != 0 && s.size != 0 && BigSize > BigEnd) 342 return malformedError("addr field plus size of section " + Twine(J) + 343 " in " + CmdName + " command " + 344 Twine(LoadCommandIndex) + 345 " greater than than " 346 "the segment's vmaddr plus vmsize"); 347 if (Obj.getHeader().filetype != MachO::MH_DYLIB_STUB && 348 Obj.getHeader().filetype != MachO::MH_DSYM && 349 s.flags != MachO::S_ZEROFILL && 350 s.flags != MachO::S_THREAD_LOCAL_ZEROFILL) 351 if (Error Err = checkOverlappingElement(Elements, s.offset, s.size, 352 "section contents")) 353 return Err; 354 if (s.reloff > FileSize) 355 return malformedError("reloff field of section " + Twine(J) + " in " + 356 CmdName + " command " + Twine(LoadCommandIndex) + 357 " extends past the end of the file"); 358 BigSize = s.nreloc; 359 BigSize *= sizeof(struct MachO::relocation_info); 360 BigSize += s.reloff; 361 if (BigSize > FileSize) 362 return malformedError("reloff field plus nreloc field times sizeof(" 363 "struct relocation_info) of section " + 364 Twine(J) + " in " + CmdName + " command " + 365 Twine(LoadCommandIndex) + 366 " extends past the end of the file"); 367 if (Error Err = checkOverlappingElement(Elements, s.reloff, s.nreloc * 368 sizeof(struct 369 MachO::relocation_info), 370 "section relocation entries")) 371 return Err; 372 } 373 if (S.fileoff > FileSize) 374 return malformedError("load command " + Twine(LoadCommandIndex) + 375 " fileoff field in " + CmdName + 376 " extends past the end of the file"); 377 uint64_t BigSize = S.fileoff; 378 BigSize += S.filesize; 379 if (BigSize > FileSize) 380 return malformedError("load command " + Twine(LoadCommandIndex) + 381 " fileoff field plus filesize field in " + 382 CmdName + " extends past the end of the file"); 383 if (S.vmsize != 0 && S.filesize > S.vmsize) 384 return malformedError("load command " + Twine(LoadCommandIndex) + 385 " filesize field in " + CmdName + 386 " greater than vmsize field"); 387 IsPageZeroSegment |= StringRef("__PAGEZERO").equals(S.segname); 388 } else 389 return SegOrErr.takeError(); 390 391 return Error::success(); 392 } 393 394 static Error checkSymtabCommand(const MachOObjectFile &Obj, 395 const MachOObjectFile::LoadCommandInfo &Load, 396 uint32_t LoadCommandIndex, 397 const char **SymtabLoadCmd, 398 std::list<MachOElement> &Elements) { 399 if (Load.C.cmdsize < sizeof(MachO::symtab_command)) 400 return malformedError("load command " + Twine(LoadCommandIndex) + 401 " LC_SYMTAB cmdsize too small"); 402 if (*SymtabLoadCmd != nullptr) 403 return malformedError("more than one LC_SYMTAB command"); 404 MachO::symtab_command Symtab = 405 getStruct<MachO::symtab_command>(Obj, Load.Ptr); 406 if (Symtab.cmdsize != sizeof(MachO::symtab_command)) 407 return malformedError("LC_SYMTAB command " + Twine(LoadCommandIndex) + 408 " has incorrect cmdsize"); 409 uint64_t FileSize = Obj.getData().size(); 410 if (Symtab.symoff > FileSize) 411 return malformedError("symoff field of LC_SYMTAB command " + 412 Twine(LoadCommandIndex) + " extends past the end " 413 "of the file"); 414 uint64_t SymtabSize = Symtab.nsyms; 415 const char *struct_nlist_name; 416 if (Obj.is64Bit()) { 417 SymtabSize *= sizeof(MachO::nlist_64); 418 struct_nlist_name = "struct nlist_64"; 419 } else { 420 SymtabSize *= sizeof(MachO::nlist); 421 struct_nlist_name = "struct nlist"; 422 } 423 uint64_t BigSize = SymtabSize; 424 BigSize += Symtab.symoff; 425 if (BigSize > FileSize) 426 return malformedError("symoff field plus nsyms field times sizeof(" + 427 Twine(struct_nlist_name) + ") of LC_SYMTAB command " + 428 Twine(LoadCommandIndex) + " extends past the end " 429 "of the file"); 430 if (Error Err = checkOverlappingElement(Elements, Symtab.symoff, SymtabSize, 431 "symbol table")) 432 return Err; 433 if (Symtab.stroff > FileSize) 434 return malformedError("stroff field of LC_SYMTAB command " + 435 Twine(LoadCommandIndex) + " extends past the end " 436 "of the file"); 437 BigSize = Symtab.stroff; 438 BigSize += Symtab.strsize; 439 if (BigSize > FileSize) 440 return malformedError("stroff field plus strsize field of LC_SYMTAB " 441 "command " + Twine(LoadCommandIndex) + " extends " 442 "past the end of the file"); 443 if (Error Err = checkOverlappingElement(Elements, Symtab.stroff, 444 Symtab.strsize, "string table")) 445 return Err; 446 *SymtabLoadCmd = Load.Ptr; 447 return Error::success(); 448 } 449 450 static Error checkDysymtabCommand(const MachOObjectFile &Obj, 451 const MachOObjectFile::LoadCommandInfo &Load, 452 uint32_t LoadCommandIndex, 453 const char **DysymtabLoadCmd, 454 std::list<MachOElement> &Elements) { 455 if (Load.C.cmdsize < sizeof(MachO::dysymtab_command)) 456 return malformedError("load command " + Twine(LoadCommandIndex) + 457 " LC_DYSYMTAB cmdsize too small"); 458 if (*DysymtabLoadCmd != nullptr) 459 return malformedError("more than one LC_DYSYMTAB command"); 460 MachO::dysymtab_command Dysymtab = 461 getStruct<MachO::dysymtab_command>(Obj, Load.Ptr); 462 if (Dysymtab.cmdsize != sizeof(MachO::dysymtab_command)) 463 return malformedError("LC_DYSYMTAB command " + Twine(LoadCommandIndex) + 464 " has incorrect cmdsize"); 465 uint64_t FileSize = Obj.getData().size(); 466 if (Dysymtab.tocoff > FileSize) 467 return malformedError("tocoff field of LC_DYSYMTAB command " + 468 Twine(LoadCommandIndex) + " extends past the end of " 469 "the file"); 470 uint64_t BigSize = Dysymtab.ntoc; 471 BigSize *= sizeof(MachO::dylib_table_of_contents); 472 BigSize += Dysymtab.tocoff; 473 if (BigSize > FileSize) 474 return malformedError("tocoff field plus ntoc field times sizeof(struct " 475 "dylib_table_of_contents) of LC_DYSYMTAB command " + 476 Twine(LoadCommandIndex) + " extends past the end of " 477 "the file"); 478 if (Error Err = checkOverlappingElement(Elements, Dysymtab.tocoff, 479 Dysymtab.ntoc * sizeof(struct 480 MachO::dylib_table_of_contents), 481 "table of contents")) 482 return Err; 483 if (Dysymtab.modtaboff > FileSize) 484 return malformedError("modtaboff field of LC_DYSYMTAB command " + 485 Twine(LoadCommandIndex) + " extends past the end of " 486 "the file"); 487 BigSize = Dysymtab.nmodtab; 488 const char *struct_dylib_module_name; 489 uint64_t sizeof_modtab; 490 if (Obj.is64Bit()) { 491 sizeof_modtab = sizeof(MachO::dylib_module_64); 492 struct_dylib_module_name = "struct dylib_module_64"; 493 } else { 494 sizeof_modtab = sizeof(MachO::dylib_module); 495 struct_dylib_module_name = "struct dylib_module"; 496 } 497 BigSize *= sizeof_modtab; 498 BigSize += Dysymtab.modtaboff; 499 if (BigSize > FileSize) 500 return malformedError("modtaboff field plus nmodtab field times sizeof(" + 501 Twine(struct_dylib_module_name) + ") of LC_DYSYMTAB " 502 "command " + Twine(LoadCommandIndex) + " extends " 503 "past the end of the file"); 504 if (Error Err = checkOverlappingElement(Elements, Dysymtab.modtaboff, 505 Dysymtab.nmodtab * sizeof_modtab, 506 "module table")) 507 return Err; 508 if (Dysymtab.extrefsymoff > FileSize) 509 return malformedError("extrefsymoff field of LC_DYSYMTAB command " + 510 Twine(LoadCommandIndex) + " extends past the end of " 511 "the file"); 512 BigSize = Dysymtab.nextrefsyms; 513 BigSize *= sizeof(MachO::dylib_reference); 514 BigSize += Dysymtab.extrefsymoff; 515 if (BigSize > FileSize) 516 return malformedError("extrefsymoff field plus nextrefsyms field times " 517 "sizeof(struct dylib_reference) of LC_DYSYMTAB " 518 "command " + Twine(LoadCommandIndex) + " extends " 519 "past the end of the file"); 520 if (Error Err = checkOverlappingElement(Elements, Dysymtab.extrefsymoff, 521 Dysymtab.nextrefsyms * 522 sizeof(MachO::dylib_reference), 523 "reference table")) 524 return Err; 525 if (Dysymtab.indirectsymoff > FileSize) 526 return malformedError("indirectsymoff field of LC_DYSYMTAB command " + 527 Twine(LoadCommandIndex) + " extends past the end of " 528 "the file"); 529 BigSize = Dysymtab.nindirectsyms; 530 BigSize *= sizeof(uint32_t); 531 BigSize += Dysymtab.indirectsymoff; 532 if (BigSize > FileSize) 533 return malformedError("indirectsymoff field plus nindirectsyms field times " 534 "sizeof(uint32_t) of LC_DYSYMTAB command " + 535 Twine(LoadCommandIndex) + " extends past the end of " 536 "the file"); 537 if (Error Err = checkOverlappingElement(Elements, Dysymtab.indirectsymoff, 538 Dysymtab.nindirectsyms * 539 sizeof(uint32_t), 540 "indirect table")) 541 return Err; 542 if (Dysymtab.extreloff > FileSize) 543 return malformedError("extreloff field of LC_DYSYMTAB command " + 544 Twine(LoadCommandIndex) + " extends past the end of " 545 "the file"); 546 BigSize = Dysymtab.nextrel; 547 BigSize *= sizeof(MachO::relocation_info); 548 BigSize += Dysymtab.extreloff; 549 if (BigSize > FileSize) 550 return malformedError("extreloff field plus nextrel field times sizeof" 551 "(struct relocation_info) of LC_DYSYMTAB command " + 552 Twine(LoadCommandIndex) + " extends past the end of " 553 "the file"); 554 if (Error Err = checkOverlappingElement(Elements, Dysymtab.extreloff, 555 Dysymtab.nextrel * 556 sizeof(MachO::relocation_info), 557 "external relocation table")) 558 return Err; 559 if (Dysymtab.locreloff > FileSize) 560 return malformedError("locreloff field of LC_DYSYMTAB command " + 561 Twine(LoadCommandIndex) + " extends past the end of " 562 "the file"); 563 BigSize = Dysymtab.nlocrel; 564 BigSize *= sizeof(MachO::relocation_info); 565 BigSize += Dysymtab.locreloff; 566 if (BigSize > FileSize) 567 return malformedError("locreloff field plus nlocrel field times sizeof" 568 "(struct relocation_info) of LC_DYSYMTAB command " + 569 Twine(LoadCommandIndex) + " extends past the end of " 570 "the file"); 571 if (Error Err = checkOverlappingElement(Elements, Dysymtab.locreloff, 572 Dysymtab.nlocrel * 573 sizeof(MachO::relocation_info), 574 "local relocation table")) 575 return Err; 576 *DysymtabLoadCmd = Load.Ptr; 577 return Error::success(); 578 } 579 580 static Error checkLinkeditDataCommand(const MachOObjectFile &Obj, 581 const MachOObjectFile::LoadCommandInfo &Load, 582 uint32_t LoadCommandIndex, 583 const char **LoadCmd, const char *CmdName, 584 std::list<MachOElement> &Elements, 585 const char *ElementName) { 586 if (Load.C.cmdsize < sizeof(MachO::linkedit_data_command)) 587 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 588 CmdName + " cmdsize too small"); 589 if (*LoadCmd != nullptr) 590 return malformedError("more than one " + Twine(CmdName) + " command"); 591 MachO::linkedit_data_command LinkData = 592 getStruct<MachO::linkedit_data_command>(Obj, Load.Ptr); 593 if (LinkData.cmdsize != sizeof(MachO::linkedit_data_command)) 594 return malformedError(Twine(CmdName) + " command " + 595 Twine(LoadCommandIndex) + " has incorrect cmdsize"); 596 uint64_t FileSize = Obj.getData().size(); 597 if (LinkData.dataoff > FileSize) 598 return malformedError("dataoff field of " + Twine(CmdName) + " command " + 599 Twine(LoadCommandIndex) + " extends past the end of " 600 "the file"); 601 uint64_t BigSize = LinkData.dataoff; 602 BigSize += LinkData.datasize; 603 if (BigSize > FileSize) 604 return malformedError("dataoff field plus datasize field of " + 605 Twine(CmdName) + " command " + 606 Twine(LoadCommandIndex) + " extends past the end of " 607 "the file"); 608 if (Error Err = checkOverlappingElement(Elements, LinkData.dataoff, 609 LinkData.datasize, ElementName)) 610 return Err; 611 *LoadCmd = Load.Ptr; 612 return Error::success(); 613 } 614 615 static Error checkDyldInfoCommand(const MachOObjectFile &Obj, 616 const MachOObjectFile::LoadCommandInfo &Load, 617 uint32_t LoadCommandIndex, 618 const char **LoadCmd, const char *CmdName, 619 std::list<MachOElement> &Elements) { 620 if (Load.C.cmdsize < sizeof(MachO::dyld_info_command)) 621 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 622 CmdName + " cmdsize too small"); 623 if (*LoadCmd != nullptr) 624 return malformedError("more than one LC_DYLD_INFO and or LC_DYLD_INFO_ONLY " 625 "command"); 626 MachO::dyld_info_command DyldInfo = 627 getStruct<MachO::dyld_info_command>(Obj, Load.Ptr); 628 if (DyldInfo.cmdsize != sizeof(MachO::dyld_info_command)) 629 return malformedError(Twine(CmdName) + " command " + 630 Twine(LoadCommandIndex) + " has incorrect cmdsize"); 631 uint64_t FileSize = Obj.getData().size(); 632 if (DyldInfo.rebase_off > FileSize) 633 return malformedError("rebase_off field of " + Twine(CmdName) + 634 " command " + Twine(LoadCommandIndex) + " extends " 635 "past the end of the file"); 636 uint64_t BigSize = DyldInfo.rebase_off; 637 BigSize += DyldInfo.rebase_size; 638 if (BigSize > FileSize) 639 return malformedError("rebase_off field plus rebase_size field of " + 640 Twine(CmdName) + " command " + 641 Twine(LoadCommandIndex) + " extends past the end of " 642 "the file"); 643 if (Error Err = checkOverlappingElement(Elements, DyldInfo.rebase_off, 644 DyldInfo.rebase_size, 645 "dyld rebase info")) 646 return Err; 647 if (DyldInfo.bind_off > FileSize) 648 return malformedError("bind_off field of " + Twine(CmdName) + 649 " command " + Twine(LoadCommandIndex) + " extends " 650 "past the end of the file"); 651 BigSize = DyldInfo.bind_off; 652 BigSize += DyldInfo.bind_size; 653 if (BigSize > FileSize) 654 return malformedError("bind_off field plus bind_size field of " + 655 Twine(CmdName) + " command " + 656 Twine(LoadCommandIndex) + " extends past the end of " 657 "the file"); 658 if (Error Err = checkOverlappingElement(Elements, DyldInfo.bind_off, 659 DyldInfo.bind_size, 660 "dyld bind info")) 661 return Err; 662 if (DyldInfo.weak_bind_off > FileSize) 663 return malformedError("weak_bind_off field of " + Twine(CmdName) + 664 " command " + Twine(LoadCommandIndex) + " extends " 665 "past the end of the file"); 666 BigSize = DyldInfo.weak_bind_off; 667 BigSize += DyldInfo.weak_bind_size; 668 if (BigSize > FileSize) 669 return malformedError("weak_bind_off field plus weak_bind_size field of " + 670 Twine(CmdName) + " command " + 671 Twine(LoadCommandIndex) + " extends past the end of " 672 "the file"); 673 if (Error Err = checkOverlappingElement(Elements, DyldInfo.weak_bind_off, 674 DyldInfo.weak_bind_size, 675 "dyld weak bind info")) 676 return Err; 677 if (DyldInfo.lazy_bind_off > FileSize) 678 return malformedError("lazy_bind_off field of " + Twine(CmdName) + 679 " command " + Twine(LoadCommandIndex) + " extends " 680 "past the end of the file"); 681 BigSize = DyldInfo.lazy_bind_off; 682 BigSize += DyldInfo.lazy_bind_size; 683 if (BigSize > FileSize) 684 return malformedError("lazy_bind_off field plus lazy_bind_size field of " + 685 Twine(CmdName) + " command " + 686 Twine(LoadCommandIndex) + " extends past the end of " 687 "the file"); 688 if (Error Err = checkOverlappingElement(Elements, DyldInfo.lazy_bind_off, 689 DyldInfo.lazy_bind_size, 690 "dyld lazy bind info")) 691 return Err; 692 if (DyldInfo.export_off > FileSize) 693 return malformedError("export_off field of " + Twine(CmdName) + 694 " command " + Twine(LoadCommandIndex) + " extends " 695 "past the end of the file"); 696 BigSize = DyldInfo.export_off; 697 BigSize += DyldInfo.export_size; 698 if (BigSize > FileSize) 699 return malformedError("export_off field plus export_size field of " + 700 Twine(CmdName) + " command " + 701 Twine(LoadCommandIndex) + " extends past the end of " 702 "the file"); 703 if (Error Err = checkOverlappingElement(Elements, DyldInfo.export_off, 704 DyldInfo.export_size, 705 "dyld export info")) 706 return Err; 707 *LoadCmd = Load.Ptr; 708 return Error::success(); 709 } 710 711 static Error checkDylibCommand(const MachOObjectFile &Obj, 712 const MachOObjectFile::LoadCommandInfo &Load, 713 uint32_t LoadCommandIndex, const char *CmdName) { 714 if (Load.C.cmdsize < sizeof(MachO::dylib_command)) 715 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 716 CmdName + " cmdsize too small"); 717 MachO::dylib_command D = getStruct<MachO::dylib_command>(Obj, Load.Ptr); 718 if (D.dylib.name < sizeof(MachO::dylib_command)) 719 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 720 CmdName + " name.offset field too small, not past " 721 "the end of the dylib_command struct"); 722 if (D.dylib.name >= D.cmdsize) 723 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 724 CmdName + " name.offset field extends past the end " 725 "of the load command"); 726 // Make sure there is a null between the starting offset of the name and 727 // the end of the load command. 728 uint32_t i; 729 const char *P = (const char *)Load.Ptr; 730 for (i = D.dylib.name; i < D.cmdsize; i++) 731 if (P[i] == '\0') 732 break; 733 if (i >= D.cmdsize) 734 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 735 CmdName + " library name extends past the end of the " 736 "load command"); 737 return Error::success(); 738 } 739 740 static Error checkDylibIdCommand(const MachOObjectFile &Obj, 741 const MachOObjectFile::LoadCommandInfo &Load, 742 uint32_t LoadCommandIndex, 743 const char **LoadCmd) { 744 if (Error Err = checkDylibCommand(Obj, Load, LoadCommandIndex, 745 "LC_ID_DYLIB")) 746 return Err; 747 if (*LoadCmd != nullptr) 748 return malformedError("more than one LC_ID_DYLIB command"); 749 if (Obj.getHeader().filetype != MachO::MH_DYLIB && 750 Obj.getHeader().filetype != MachO::MH_DYLIB_STUB) 751 return malformedError("LC_ID_DYLIB load command in non-dynamic library " 752 "file type"); 753 *LoadCmd = Load.Ptr; 754 return Error::success(); 755 } 756 757 static Error checkDyldCommand(const MachOObjectFile &Obj, 758 const MachOObjectFile::LoadCommandInfo &Load, 759 uint32_t LoadCommandIndex, const char *CmdName) { 760 if (Load.C.cmdsize < sizeof(MachO::dylinker_command)) 761 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 762 CmdName + " cmdsize too small"); 763 MachO::dylinker_command D = getStruct<MachO::dylinker_command>(Obj, Load.Ptr); 764 if (D.name < sizeof(MachO::dylinker_command)) 765 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 766 CmdName + " name.offset field too small, not past " 767 "the end of the dylinker_command struct"); 768 if (D.name >= D.cmdsize) 769 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 770 CmdName + " name.offset field extends past the end " 771 "of the load command"); 772 // Make sure there is a null between the starting offset of the name and 773 // the end of the load command. 774 uint32_t i; 775 const char *P = (const char *)Load.Ptr; 776 for (i = D.name; i < D.cmdsize; i++) 777 if (P[i] == '\0') 778 break; 779 if (i >= D.cmdsize) 780 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 781 CmdName + " dyld name extends past the end of the " 782 "load command"); 783 return Error::success(); 784 } 785 786 static Error checkVersCommand(const MachOObjectFile &Obj, 787 const MachOObjectFile::LoadCommandInfo &Load, 788 uint32_t LoadCommandIndex, 789 const char **LoadCmd, const char *CmdName) { 790 if (Load.C.cmdsize != sizeof(MachO::version_min_command)) 791 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 792 CmdName + " has incorrect cmdsize"); 793 if (*LoadCmd != nullptr) 794 return malformedError("more than one LC_VERSION_MIN_MACOSX, " 795 "LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_TVOS or " 796 "LC_VERSION_MIN_WATCHOS command"); 797 *LoadCmd = Load.Ptr; 798 return Error::success(); 799 } 800 801 static Error checkNoteCommand(const MachOObjectFile &Obj, 802 const MachOObjectFile::LoadCommandInfo &Load, 803 uint32_t LoadCommandIndex, 804 std::list<MachOElement> &Elements) { 805 if (Load.C.cmdsize != sizeof(MachO::note_command)) 806 return malformedError("load command " + Twine(LoadCommandIndex) + 807 " LC_NOTE has incorrect cmdsize"); 808 MachO::note_command Nt = getStruct<MachO::note_command>(Obj, Load.Ptr); 809 uint64_t FileSize = Obj.getData().size(); 810 if (Nt.offset > FileSize) 811 return malformedError("offset field of LC_NOTE command " + 812 Twine(LoadCommandIndex) + " extends " 813 "past the end of the file"); 814 uint64_t BigSize = Nt.offset; 815 BigSize += Nt.size; 816 if (BigSize > FileSize) 817 return malformedError("size field plus offset field of LC_NOTE command " + 818 Twine(LoadCommandIndex) + " extends past the end of " 819 "the file"); 820 if (Error Err = checkOverlappingElement(Elements, Nt.offset, Nt.size, 821 "LC_NOTE data")) 822 return Err; 823 return Error::success(); 824 } 825 826 static Error 827 parseBuildVersionCommand(const MachOObjectFile &Obj, 828 const MachOObjectFile::LoadCommandInfo &Load, 829 SmallVectorImpl<const char*> &BuildTools, 830 uint32_t LoadCommandIndex) { 831 MachO::build_version_command BVC = 832 getStruct<MachO::build_version_command>(Obj, Load.Ptr); 833 if (Load.C.cmdsize != 834 sizeof(MachO::build_version_command) + 835 BVC.ntools * sizeof(MachO::build_tool_version)) 836 return malformedError("load command " + Twine(LoadCommandIndex) + 837 " LC_BUILD_VERSION_COMMAND has incorrect cmdsize"); 838 839 auto Start = Load.Ptr + sizeof(MachO::build_version_command); 840 BuildTools.resize(BVC.ntools); 841 for (unsigned i = 0; i < BVC.ntools; ++i) 842 BuildTools[i] = Start + i * sizeof(MachO::build_tool_version); 843 844 return Error::success(); 845 } 846 847 static Error checkRpathCommand(const MachOObjectFile &Obj, 848 const MachOObjectFile::LoadCommandInfo &Load, 849 uint32_t LoadCommandIndex) { 850 if (Load.C.cmdsize < sizeof(MachO::rpath_command)) 851 return malformedError("load command " + Twine(LoadCommandIndex) + 852 " LC_RPATH cmdsize too small"); 853 MachO::rpath_command R = getStruct<MachO::rpath_command>(Obj, Load.Ptr); 854 if (R.path < sizeof(MachO::rpath_command)) 855 return malformedError("load command " + Twine(LoadCommandIndex) + 856 " LC_RPATH path.offset field too small, not past " 857 "the end of the rpath_command struct"); 858 if (R.path >= R.cmdsize) 859 return malformedError("load command " + Twine(LoadCommandIndex) + 860 " LC_RPATH path.offset field extends past the end " 861 "of the load command"); 862 // Make sure there is a null between the starting offset of the path and 863 // the end of the load command. 864 uint32_t i; 865 const char *P = (const char *)Load.Ptr; 866 for (i = R.path; i < R.cmdsize; i++) 867 if (P[i] == '\0') 868 break; 869 if (i >= R.cmdsize) 870 return malformedError("load command " + Twine(LoadCommandIndex) + 871 " LC_RPATH library name extends past the end of the " 872 "load command"); 873 return Error::success(); 874 } 875 876 static Error checkEncryptCommand(const MachOObjectFile &Obj, 877 const MachOObjectFile::LoadCommandInfo &Load, 878 uint32_t LoadCommandIndex, 879 uint64_t cryptoff, uint64_t cryptsize, 880 const char **LoadCmd, const char *CmdName) { 881 if (*LoadCmd != nullptr) 882 return malformedError("more than one LC_ENCRYPTION_INFO and or " 883 "LC_ENCRYPTION_INFO_64 command"); 884 uint64_t FileSize = Obj.getData().size(); 885 if (cryptoff > FileSize) 886 return malformedError("cryptoff field of " + Twine(CmdName) + 887 " command " + Twine(LoadCommandIndex) + " extends " 888 "past the end of the file"); 889 uint64_t BigSize = cryptoff; 890 BigSize += cryptsize; 891 if (BigSize > FileSize) 892 return malformedError("cryptoff field plus cryptsize field of " + 893 Twine(CmdName) + " command " + 894 Twine(LoadCommandIndex) + " extends past the end of " 895 "the file"); 896 *LoadCmd = Load.Ptr; 897 return Error::success(); 898 } 899 900 static Error checkLinkerOptCommand(const MachOObjectFile &Obj, 901 const MachOObjectFile::LoadCommandInfo &Load, 902 uint32_t LoadCommandIndex) { 903 if (Load.C.cmdsize < sizeof(MachO::linker_option_command)) 904 return malformedError("load command " + Twine(LoadCommandIndex) + 905 " LC_LINKER_OPTION cmdsize too small"); 906 MachO::linker_option_command L = 907 getStruct<MachO::linker_option_command>(Obj, Load.Ptr); 908 // Make sure the count of strings is correct. 909 const char *string = (const char *)Load.Ptr + 910 sizeof(struct MachO::linker_option_command); 911 uint32_t left = L.cmdsize - sizeof(struct MachO::linker_option_command); 912 uint32_t i = 0; 913 while (left > 0) { 914 while (*string == '\0' && left > 0) { 915 string++; 916 left--; 917 } 918 if (left > 0) { 919 i++; 920 uint32_t NullPos = StringRef(string, left).find('\0'); 921 uint32_t len = std::min(NullPos, left) + 1; 922 string += len; 923 left -= len; 924 } 925 } 926 if (L.count != i) 927 return malformedError("load command " + Twine(LoadCommandIndex) + 928 " LC_LINKER_OPTION string count " + Twine(L.count) + 929 " does not match number of strings"); 930 return Error::success(); 931 } 932 933 static Error checkSubCommand(const MachOObjectFile &Obj, 934 const MachOObjectFile::LoadCommandInfo &Load, 935 uint32_t LoadCommandIndex, const char *CmdName, 936 size_t SizeOfCmd, const char *CmdStructName, 937 uint32_t PathOffset, const char *PathFieldName) { 938 if (PathOffset < SizeOfCmd) 939 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 940 CmdName + " " + PathFieldName + ".offset field too " 941 "small, not past the end of the " + CmdStructName); 942 if (PathOffset >= Load.C.cmdsize) 943 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 944 CmdName + " " + PathFieldName + ".offset field " 945 "extends past the end of the load command"); 946 // Make sure there is a null between the starting offset of the path and 947 // the end of the load command. 948 uint32_t i; 949 const char *P = (const char *)Load.Ptr; 950 for (i = PathOffset; i < Load.C.cmdsize; i++) 951 if (P[i] == '\0') 952 break; 953 if (i >= Load.C.cmdsize) 954 return malformedError("load command " + Twine(LoadCommandIndex) + " " + 955 CmdName + " " + PathFieldName + " name extends past " 956 "the end of the load command"); 957 return Error::success(); 958 } 959 960 static Error checkThreadCommand(const MachOObjectFile &Obj, 961 const MachOObjectFile::LoadCommandInfo &Load, 962 uint32_t LoadCommandIndex, 963 const char *CmdName) { 964 if (Load.C.cmdsize < sizeof(MachO::thread_command)) 965 return malformedError("load command " + Twine(LoadCommandIndex) + 966 CmdName + " cmdsize too small"); 967 MachO::thread_command T = 968 getStruct<MachO::thread_command>(Obj, Load.Ptr); 969 const char *state = Load.Ptr + sizeof(MachO::thread_command); 970 const char *end = Load.Ptr + T.cmdsize; 971 uint32_t nflavor = 0; 972 uint32_t cputype = getCPUType(Obj); 973 while (state < end) { 974 if(state + sizeof(uint32_t) > end) 975 return malformedError("load command " + Twine(LoadCommandIndex) + 976 "flavor in " + CmdName + " extends past end of " 977 "command"); 978 uint32_t flavor; 979 memcpy(&flavor, state, sizeof(uint32_t)); 980 if (Obj.isLittleEndian() != sys::IsLittleEndianHost) 981 sys::swapByteOrder(flavor); 982 state += sizeof(uint32_t); 983 984 if(state + sizeof(uint32_t) > end) 985 return malformedError("load command " + Twine(LoadCommandIndex) + 986 " count in " + CmdName + " extends past end of " 987 "command"); 988 uint32_t count; 989 memcpy(&count, state, sizeof(uint32_t)); 990 if (Obj.isLittleEndian() != sys::IsLittleEndianHost) 991 sys::swapByteOrder(count); 992 state += sizeof(uint32_t); 993 994 if (cputype == MachO::CPU_TYPE_I386) { 995 if (flavor == MachO::x86_THREAD_STATE32) { 996 if (count != MachO::x86_THREAD_STATE32_COUNT) 997 return malformedError("load command " + Twine(LoadCommandIndex) + 998 " count not x86_THREAD_STATE32_COUNT for " 999 "flavor number " + Twine(nflavor) + " which is " 1000 "a x86_THREAD_STATE32 flavor in " + CmdName + 1001 " command"); 1002 if (state + sizeof(MachO::x86_thread_state32_t) > end) 1003 return malformedError("load command " + Twine(LoadCommandIndex) + 1004 " x86_THREAD_STATE32 extends past end of " 1005 "command in " + CmdName + " command"); 1006 state += sizeof(MachO::x86_thread_state32_t); 1007 } else { 1008 return malformedError("load command " + Twine(LoadCommandIndex) + 1009 " unknown flavor (" + Twine(flavor) + ") for " 1010 "flavor number " + Twine(nflavor) + " in " + 1011 CmdName + " command"); 1012 } 1013 } else if (cputype == MachO::CPU_TYPE_X86_64) { 1014 if (flavor == MachO::x86_THREAD_STATE) { 1015 if (count != MachO::x86_THREAD_STATE_COUNT) 1016 return malformedError("load command " + Twine(LoadCommandIndex) + 1017 " count not x86_THREAD_STATE_COUNT for " 1018 "flavor number " + Twine(nflavor) + " which is " 1019 "a x86_THREAD_STATE flavor in " + CmdName + 1020 " command"); 1021 if (state + sizeof(MachO::x86_thread_state_t) > end) 1022 return malformedError("load command " + Twine(LoadCommandIndex) + 1023 " x86_THREAD_STATE extends past end of " 1024 "command in " + CmdName + " command"); 1025 state += sizeof(MachO::x86_thread_state_t); 1026 } else if (flavor == MachO::x86_FLOAT_STATE) { 1027 if (count != MachO::x86_FLOAT_STATE_COUNT) 1028 return malformedError("load command " + Twine(LoadCommandIndex) + 1029 " count not x86_FLOAT_STATE_COUNT for " 1030 "flavor number " + Twine(nflavor) + " which is " 1031 "a x86_FLOAT_STATE flavor in " + CmdName + 1032 " command"); 1033 if (state + sizeof(MachO::x86_float_state_t) > end) 1034 return malformedError("load command " + Twine(LoadCommandIndex) + 1035 " x86_FLOAT_STATE extends past end of " 1036 "command in " + CmdName + " command"); 1037 state += sizeof(MachO::x86_float_state_t); 1038 } else if (flavor == MachO::x86_EXCEPTION_STATE) { 1039 if (count != MachO::x86_EXCEPTION_STATE_COUNT) 1040 return malformedError("load command " + Twine(LoadCommandIndex) + 1041 " count not x86_EXCEPTION_STATE_COUNT for " 1042 "flavor number " + Twine(nflavor) + " which is " 1043 "a x86_EXCEPTION_STATE flavor in " + CmdName + 1044 " command"); 1045 if (state + sizeof(MachO::x86_exception_state_t) > end) 1046 return malformedError("load command " + Twine(LoadCommandIndex) + 1047 " x86_EXCEPTION_STATE extends past end of " 1048 "command in " + CmdName + " command"); 1049 state += sizeof(MachO::x86_exception_state_t); 1050 } else if (flavor == MachO::x86_THREAD_STATE64) { 1051 if (count != MachO::x86_THREAD_STATE64_COUNT) 1052 return malformedError("load command " + Twine(LoadCommandIndex) + 1053 " count not x86_THREAD_STATE64_COUNT for " 1054 "flavor number " + Twine(nflavor) + " which is " 1055 "a x86_THREAD_STATE64 flavor in " + CmdName + 1056 " command"); 1057 if (state + sizeof(MachO::x86_thread_state64_t) > end) 1058 return malformedError("load command " + Twine(LoadCommandIndex) + 1059 " x86_THREAD_STATE64 extends past end of " 1060 "command in " + CmdName + " command"); 1061 state += sizeof(MachO::x86_thread_state64_t); 1062 } else if (flavor == MachO::x86_EXCEPTION_STATE64) { 1063 if (count != MachO::x86_EXCEPTION_STATE64_COUNT) 1064 return malformedError("load command " + Twine(LoadCommandIndex) + 1065 " count not x86_EXCEPTION_STATE64_COUNT for " 1066 "flavor number " + Twine(nflavor) + " which is " 1067 "a x86_EXCEPTION_STATE64 flavor in " + CmdName + 1068 " command"); 1069 if (state + sizeof(MachO::x86_exception_state64_t) > end) 1070 return malformedError("load command " + Twine(LoadCommandIndex) + 1071 " x86_EXCEPTION_STATE64 extends past end of " 1072 "command in " + CmdName + " command"); 1073 state += sizeof(MachO::x86_exception_state64_t); 1074 } else { 1075 return malformedError("load command " + Twine(LoadCommandIndex) + 1076 " unknown flavor (" + Twine(flavor) + ") for " 1077 "flavor number " + Twine(nflavor) + " in " + 1078 CmdName + " command"); 1079 } 1080 } else if (cputype == MachO::CPU_TYPE_ARM) { 1081 if (flavor == MachO::ARM_THREAD_STATE) { 1082 if (count != MachO::ARM_THREAD_STATE_COUNT) 1083 return malformedError("load command " + Twine(LoadCommandIndex) + 1084 " count not ARM_THREAD_STATE_COUNT for " 1085 "flavor number " + Twine(nflavor) + " which is " 1086 "a ARM_THREAD_STATE flavor in " + CmdName + 1087 " command"); 1088 if (state + sizeof(MachO::arm_thread_state32_t) > end) 1089 return malformedError("load command " + Twine(LoadCommandIndex) + 1090 " ARM_THREAD_STATE extends past end of " 1091 "command in " + CmdName + " command"); 1092 state += sizeof(MachO::arm_thread_state32_t); 1093 } else { 1094 return malformedError("load command " + Twine(LoadCommandIndex) + 1095 " unknown flavor (" + Twine(flavor) + ") for " 1096 "flavor number " + Twine(nflavor) + " in " + 1097 CmdName + " command"); 1098 } 1099 } else if (cputype == MachO::CPU_TYPE_ARM64) { 1100 if (flavor == MachO::ARM_THREAD_STATE64) { 1101 if (count != MachO::ARM_THREAD_STATE64_COUNT) 1102 return malformedError("load command " + Twine(LoadCommandIndex) + 1103 " count not ARM_THREAD_STATE64_COUNT for " 1104 "flavor number " + Twine(nflavor) + " which is " 1105 "a ARM_THREAD_STATE64 flavor in " + CmdName + 1106 " command"); 1107 if (state + sizeof(MachO::arm_thread_state64_t) > end) 1108 return malformedError("load command " + Twine(LoadCommandIndex) + 1109 " ARM_THREAD_STATE64 extends past end of " 1110 "command in " + CmdName + " command"); 1111 state += sizeof(MachO::arm_thread_state64_t); 1112 } else { 1113 return malformedError("load command " + Twine(LoadCommandIndex) + 1114 " unknown flavor (" + Twine(flavor) + ") for " 1115 "flavor number " + Twine(nflavor) + " in " + 1116 CmdName + " command"); 1117 } 1118 } else if (cputype == MachO::CPU_TYPE_POWERPC) { 1119 if (flavor == MachO::PPC_THREAD_STATE) { 1120 if (count != MachO::PPC_THREAD_STATE_COUNT) 1121 return malformedError("load command " + Twine(LoadCommandIndex) + 1122 " count not PPC_THREAD_STATE_COUNT for " 1123 "flavor number " + Twine(nflavor) + " which is " 1124 "a PPC_THREAD_STATE flavor in " + CmdName + 1125 " command"); 1126 if (state + sizeof(MachO::ppc_thread_state32_t) > end) 1127 return malformedError("load command " + Twine(LoadCommandIndex) + 1128 " PPC_THREAD_STATE extends past end of " 1129 "command in " + CmdName + " command"); 1130 state += sizeof(MachO::ppc_thread_state32_t); 1131 } else { 1132 return malformedError("load command " + Twine(LoadCommandIndex) + 1133 " unknown flavor (" + Twine(flavor) + ") for " 1134 "flavor number " + Twine(nflavor) + " in " + 1135 CmdName + " command"); 1136 } 1137 } else { 1138 return malformedError("unknown cputype (" + Twine(cputype) + ") load " 1139 "command " + Twine(LoadCommandIndex) + " for " + 1140 CmdName + " command can't be checked"); 1141 } 1142 nflavor++; 1143 } 1144 return Error::success(); 1145 } 1146 1147 static Error checkTwoLevelHintsCommand(const MachOObjectFile &Obj, 1148 const MachOObjectFile::LoadCommandInfo 1149 &Load, 1150 uint32_t LoadCommandIndex, 1151 const char **LoadCmd, 1152 std::list<MachOElement> &Elements) { 1153 if (Load.C.cmdsize != sizeof(MachO::twolevel_hints_command)) 1154 return malformedError("load command " + Twine(LoadCommandIndex) + 1155 " LC_TWOLEVEL_HINTS has incorrect cmdsize"); 1156 if (*LoadCmd != nullptr) 1157 return malformedError("more than one LC_TWOLEVEL_HINTS command"); 1158 MachO::twolevel_hints_command Hints = 1159 getStruct<MachO::twolevel_hints_command>(Obj, Load.Ptr); 1160 uint64_t FileSize = Obj.getData().size(); 1161 if (Hints.offset > FileSize) 1162 return malformedError("offset field of LC_TWOLEVEL_HINTS command " + 1163 Twine(LoadCommandIndex) + " extends past the end of " 1164 "the file"); 1165 uint64_t BigSize = Hints.nhints; 1166 BigSize *= sizeof(MachO::twolevel_hint); 1167 BigSize += Hints.offset; 1168 if (BigSize > FileSize) 1169 return malformedError("offset field plus nhints times sizeof(struct " 1170 "twolevel_hint) field of LC_TWOLEVEL_HINTS command " + 1171 Twine(LoadCommandIndex) + " extends past the end of " 1172 "the file"); 1173 if (Error Err = checkOverlappingElement(Elements, Hints.offset, Hints.nhints * 1174 sizeof(MachO::twolevel_hint), 1175 "two level hints")) 1176 return Err; 1177 *LoadCmd = Load.Ptr; 1178 return Error::success(); 1179 } 1180 1181 // Returns true if the libObject code does not support the load command and its 1182 // contents. The cmd value it is treated as an unknown load command but with 1183 // an error message that says the cmd value is obsolete. 1184 static bool isLoadCommandObsolete(uint32_t cmd) { 1185 if (cmd == MachO::LC_SYMSEG || 1186 cmd == MachO::LC_LOADFVMLIB || 1187 cmd == MachO::LC_IDFVMLIB || 1188 cmd == MachO::LC_IDENT || 1189 cmd == MachO::LC_FVMFILE || 1190 cmd == MachO::LC_PREPAGE || 1191 cmd == MachO::LC_PREBOUND_DYLIB || 1192 cmd == MachO::LC_TWOLEVEL_HINTS || 1193 cmd == MachO::LC_PREBIND_CKSUM) 1194 return true; 1195 return false; 1196 } 1197 1198 Expected<std::unique_ptr<MachOObjectFile>> 1199 MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian, 1200 bool Is64Bits, uint32_t UniversalCputype, 1201 uint32_t UniversalIndex) { 1202 Error Err = Error::success(); 1203 std::unique_ptr<MachOObjectFile> Obj( 1204 new MachOObjectFile(std::move(Object), IsLittleEndian, 1205 Is64Bits, Err, UniversalCputype, 1206 UniversalIndex)); 1207 if (Err) 1208 return std::move(Err); 1209 return std::move(Obj); 1210 } 1211 1212 MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, 1213 bool Is64bits, Error &Err, 1214 uint32_t UniversalCputype, 1215 uint32_t UniversalIndex) 1216 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) { 1217 ErrorAsOutParameter ErrAsOutParam(&Err); 1218 uint64_t SizeOfHeaders; 1219 uint32_t cputype; 1220 if (is64Bit()) { 1221 parseHeader(*this, Header64, Err); 1222 SizeOfHeaders = sizeof(MachO::mach_header_64); 1223 cputype = Header64.cputype; 1224 } else { 1225 parseHeader(*this, Header, Err); 1226 SizeOfHeaders = sizeof(MachO::mach_header); 1227 cputype = Header.cputype; 1228 } 1229 if (Err) 1230 return; 1231 SizeOfHeaders += getHeader().sizeofcmds; 1232 if (getData().data() + SizeOfHeaders > getData().end()) { 1233 Err = malformedError("load commands extend past the end of the file"); 1234 return; 1235 } 1236 if (UniversalCputype != 0 && cputype != UniversalCputype) { 1237 Err = malformedError("universal header architecture: " + 1238 Twine(UniversalIndex) + "'s cputype does not match " 1239 "object file's mach header"); 1240 return; 1241 } 1242 std::list<MachOElement> Elements; 1243 Elements.push_back({0, SizeOfHeaders, "Mach-O headers"}); 1244 1245 uint32_t LoadCommandCount = getHeader().ncmds; 1246 LoadCommandInfo Load; 1247 if (LoadCommandCount != 0) { 1248 if (auto LoadOrErr = getFirstLoadCommandInfo(*this)) 1249 Load = *LoadOrErr; 1250 else { 1251 Err = LoadOrErr.takeError(); 1252 return; 1253 } 1254 } 1255 1256 const char *DyldIdLoadCmd = nullptr; 1257 const char *FuncStartsLoadCmd = nullptr; 1258 const char *SplitInfoLoadCmd = nullptr; 1259 const char *CodeSignDrsLoadCmd = nullptr; 1260 const char *CodeSignLoadCmd = nullptr; 1261 const char *VersLoadCmd = nullptr; 1262 const char *SourceLoadCmd = nullptr; 1263 const char *EntryPointLoadCmd = nullptr; 1264 const char *EncryptLoadCmd = nullptr; 1265 const char *RoutinesLoadCmd = nullptr; 1266 const char *UnixThreadLoadCmd = nullptr; 1267 const char *TwoLevelHintsLoadCmd = nullptr; 1268 for (unsigned I = 0; I < LoadCommandCount; ++I) { 1269 if (is64Bit()) { 1270 if (Load.C.cmdsize % 8 != 0) { 1271 // We have a hack here to allow 64-bit Mach-O core files to have 1272 // LC_THREAD commands that are only a multiple of 4 and not 8 to be 1273 // allowed since the macOS kernel produces them. 1274 if (getHeader().filetype != MachO::MH_CORE || 1275 Load.C.cmd != MachO::LC_THREAD || Load.C.cmdsize % 4) { 1276 Err = malformedError("load command " + Twine(I) + " cmdsize not a " 1277 "multiple of 8"); 1278 return; 1279 } 1280 } 1281 } else { 1282 if (Load.C.cmdsize % 4 != 0) { 1283 Err = malformedError("load command " + Twine(I) + " cmdsize not a " 1284 "multiple of 4"); 1285 return; 1286 } 1287 } 1288 LoadCommands.push_back(Load); 1289 if (Load.C.cmd == MachO::LC_SYMTAB) { 1290 if ((Err = checkSymtabCommand(*this, Load, I, &SymtabLoadCmd, Elements))) 1291 return; 1292 } else if (Load.C.cmd == MachO::LC_DYSYMTAB) { 1293 if ((Err = checkDysymtabCommand(*this, Load, I, &DysymtabLoadCmd, 1294 Elements))) 1295 return; 1296 } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) { 1297 if ((Err = checkLinkeditDataCommand(*this, Load, I, &DataInCodeLoadCmd, 1298 "LC_DATA_IN_CODE", Elements, 1299 "data in code info"))) 1300 return; 1301 } else if (Load.C.cmd == MachO::LC_LINKER_OPTIMIZATION_HINT) { 1302 if ((Err = checkLinkeditDataCommand(*this, Load, I, &LinkOptHintsLoadCmd, 1303 "LC_LINKER_OPTIMIZATION_HINT", 1304 Elements, "linker optimization " 1305 "hints"))) 1306 return; 1307 } else if (Load.C.cmd == MachO::LC_FUNCTION_STARTS) { 1308 if ((Err = checkLinkeditDataCommand(*this, Load, I, &FuncStartsLoadCmd, 1309 "LC_FUNCTION_STARTS", Elements, 1310 "function starts data"))) 1311 return; 1312 } else if (Load.C.cmd == MachO::LC_SEGMENT_SPLIT_INFO) { 1313 if ((Err = checkLinkeditDataCommand(*this, Load, I, &SplitInfoLoadCmd, 1314 "LC_SEGMENT_SPLIT_INFO", Elements, 1315 "split info data"))) 1316 return; 1317 } else if (Load.C.cmd == MachO::LC_DYLIB_CODE_SIGN_DRS) { 1318 if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignDrsLoadCmd, 1319 "LC_DYLIB_CODE_SIGN_DRS", Elements, 1320 "code signing RDs data"))) 1321 return; 1322 } else if (Load.C.cmd == MachO::LC_CODE_SIGNATURE) { 1323 if ((Err = checkLinkeditDataCommand(*this, Load, I, &CodeSignLoadCmd, 1324 "LC_CODE_SIGNATURE", Elements, 1325 "code signature data"))) 1326 return; 1327 } else if (Load.C.cmd == MachO::LC_DYLD_INFO) { 1328 if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd, 1329 "LC_DYLD_INFO", Elements))) 1330 return; 1331 } else if (Load.C.cmd == MachO::LC_DYLD_INFO_ONLY) { 1332 if ((Err = checkDyldInfoCommand(*this, Load, I, &DyldInfoLoadCmd, 1333 "LC_DYLD_INFO_ONLY", Elements))) 1334 return; 1335 } else if (Load.C.cmd == MachO::LC_UUID) { 1336 if (Load.C.cmdsize != sizeof(MachO::uuid_command)) { 1337 Err = malformedError("LC_UUID command " + Twine(I) + " has incorrect " 1338 "cmdsize"); 1339 return; 1340 } 1341 if (UuidLoadCmd) { 1342 Err = malformedError("more than one LC_UUID command"); 1343 return; 1344 } 1345 UuidLoadCmd = Load.Ptr; 1346 } else if (Load.C.cmd == MachO::LC_SEGMENT_64) { 1347 if ((Err = parseSegmentLoadCommand<MachO::segment_command_64, 1348 MachO::section_64>( 1349 *this, Load, Sections, HasPageZeroSegment, I, 1350 "LC_SEGMENT_64", SizeOfHeaders, Elements))) 1351 return; 1352 } else if (Load.C.cmd == MachO::LC_SEGMENT) { 1353 if ((Err = parseSegmentLoadCommand<MachO::segment_command, 1354 MachO::section>( 1355 *this, Load, Sections, HasPageZeroSegment, I, 1356 "LC_SEGMENT", SizeOfHeaders, Elements))) 1357 return; 1358 } else if (Load.C.cmd == MachO::LC_ID_DYLIB) { 1359 if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd))) 1360 return; 1361 } else if (Load.C.cmd == MachO::LC_LOAD_DYLIB) { 1362 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_DYLIB"))) 1363 return; 1364 Libraries.push_back(Load.Ptr); 1365 } else if (Load.C.cmd == MachO::LC_LOAD_WEAK_DYLIB) { 1366 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_WEAK_DYLIB"))) 1367 return; 1368 Libraries.push_back(Load.Ptr); 1369 } else if (Load.C.cmd == MachO::LC_LAZY_LOAD_DYLIB) { 1370 if ((Err = checkDylibCommand(*this, Load, I, "LC_LAZY_LOAD_DYLIB"))) 1371 return; 1372 Libraries.push_back(Load.Ptr); 1373 } else if (Load.C.cmd == MachO::LC_REEXPORT_DYLIB) { 1374 if ((Err = checkDylibCommand(*this, Load, I, "LC_REEXPORT_DYLIB"))) 1375 return; 1376 Libraries.push_back(Load.Ptr); 1377 } else if (Load.C.cmd == MachO::LC_LOAD_UPWARD_DYLIB) { 1378 if ((Err = checkDylibCommand(*this, Load, I, "LC_LOAD_UPWARD_DYLIB"))) 1379 return; 1380 Libraries.push_back(Load.Ptr); 1381 } else if (Load.C.cmd == MachO::LC_ID_DYLINKER) { 1382 if ((Err = checkDyldCommand(*this, Load, I, "LC_ID_DYLINKER"))) 1383 return; 1384 } else if (Load.C.cmd == MachO::LC_LOAD_DYLINKER) { 1385 if ((Err = checkDyldCommand(*this, Load, I, "LC_LOAD_DYLINKER"))) 1386 return; 1387 } else if (Load.C.cmd == MachO::LC_DYLD_ENVIRONMENT) { 1388 if ((Err = checkDyldCommand(*this, Load, I, "LC_DYLD_ENVIRONMENT"))) 1389 return; 1390 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX) { 1391 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd, 1392 "LC_VERSION_MIN_MACOSX"))) 1393 return; 1394 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) { 1395 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd, 1396 "LC_VERSION_MIN_IPHONEOS"))) 1397 return; 1398 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_TVOS) { 1399 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd, 1400 "LC_VERSION_MIN_TVOS"))) 1401 return; 1402 } else if (Load.C.cmd == MachO::LC_VERSION_MIN_WATCHOS) { 1403 if ((Err = checkVersCommand(*this, Load, I, &VersLoadCmd, 1404 "LC_VERSION_MIN_WATCHOS"))) 1405 return; 1406 } else if (Load.C.cmd == MachO::LC_NOTE) { 1407 if ((Err = checkNoteCommand(*this, Load, I, Elements))) 1408 return; 1409 } else if (Load.C.cmd == MachO::LC_BUILD_VERSION) { 1410 if ((Err = parseBuildVersionCommand(*this, Load, BuildTools, I))) 1411 return; 1412 } else if (Load.C.cmd == MachO::LC_RPATH) { 1413 if ((Err = checkRpathCommand(*this, Load, I))) 1414 return; 1415 } else if (Load.C.cmd == MachO::LC_SOURCE_VERSION) { 1416 if (Load.C.cmdsize != sizeof(MachO::source_version_command)) { 1417 Err = malformedError("LC_SOURCE_VERSION command " + Twine(I) + 1418 " has incorrect cmdsize"); 1419 return; 1420 } 1421 if (SourceLoadCmd) { 1422 Err = malformedError("more than one LC_SOURCE_VERSION command"); 1423 return; 1424 } 1425 SourceLoadCmd = Load.Ptr; 1426 } else if (Load.C.cmd == MachO::LC_MAIN) { 1427 if (Load.C.cmdsize != sizeof(MachO::entry_point_command)) { 1428 Err = malformedError("LC_MAIN command " + Twine(I) + 1429 " has incorrect cmdsize"); 1430 return; 1431 } 1432 if (EntryPointLoadCmd) { 1433 Err = malformedError("more than one LC_MAIN command"); 1434 return; 1435 } 1436 EntryPointLoadCmd = Load.Ptr; 1437 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO) { 1438 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command)) { 1439 Err = malformedError("LC_ENCRYPTION_INFO command " + Twine(I) + 1440 " has incorrect cmdsize"); 1441 return; 1442 } 1443 MachO::encryption_info_command E = 1444 getStruct<MachO::encryption_info_command>(*this, Load.Ptr); 1445 if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize, 1446 &EncryptLoadCmd, "LC_ENCRYPTION_INFO"))) 1447 return; 1448 } else if (Load.C.cmd == MachO::LC_ENCRYPTION_INFO_64) { 1449 if (Load.C.cmdsize != sizeof(MachO::encryption_info_command_64)) { 1450 Err = malformedError("LC_ENCRYPTION_INFO_64 command " + Twine(I) + 1451 " has incorrect cmdsize"); 1452 return; 1453 } 1454 MachO::encryption_info_command_64 E = 1455 getStruct<MachO::encryption_info_command_64>(*this, Load.Ptr); 1456 if ((Err = checkEncryptCommand(*this, Load, I, E.cryptoff, E.cryptsize, 1457 &EncryptLoadCmd, "LC_ENCRYPTION_INFO_64"))) 1458 return; 1459 } else if (Load.C.cmd == MachO::LC_LINKER_OPTION) { 1460 if ((Err = checkLinkerOptCommand(*this, Load, I))) 1461 return; 1462 } else if (Load.C.cmd == MachO::LC_SUB_FRAMEWORK) { 1463 if (Load.C.cmdsize < sizeof(MachO::sub_framework_command)) { 1464 Err = malformedError("load command " + Twine(I) + 1465 " LC_SUB_FRAMEWORK cmdsize too small"); 1466 return; 1467 } 1468 MachO::sub_framework_command S = 1469 getStruct<MachO::sub_framework_command>(*this, Load.Ptr); 1470 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_FRAMEWORK", 1471 sizeof(MachO::sub_framework_command), 1472 "sub_framework_command", S.umbrella, 1473 "umbrella"))) 1474 return; 1475 } else if (Load.C.cmd == MachO::LC_SUB_UMBRELLA) { 1476 if (Load.C.cmdsize < sizeof(MachO::sub_umbrella_command)) { 1477 Err = malformedError("load command " + Twine(I) + 1478 " LC_SUB_UMBRELLA cmdsize too small"); 1479 return; 1480 } 1481 MachO::sub_umbrella_command S = 1482 getStruct<MachO::sub_umbrella_command>(*this, Load.Ptr); 1483 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_UMBRELLA", 1484 sizeof(MachO::sub_umbrella_command), 1485 "sub_umbrella_command", S.sub_umbrella, 1486 "sub_umbrella"))) 1487 return; 1488 } else if (Load.C.cmd == MachO::LC_SUB_LIBRARY) { 1489 if (Load.C.cmdsize < sizeof(MachO::sub_library_command)) { 1490 Err = malformedError("load command " + Twine(I) + 1491 " LC_SUB_LIBRARY cmdsize too small"); 1492 return; 1493 } 1494 MachO::sub_library_command S = 1495 getStruct<MachO::sub_library_command>(*this, Load.Ptr); 1496 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_LIBRARY", 1497 sizeof(MachO::sub_library_command), 1498 "sub_library_command", S.sub_library, 1499 "sub_library"))) 1500 return; 1501 } else if (Load.C.cmd == MachO::LC_SUB_CLIENT) { 1502 if (Load.C.cmdsize < sizeof(MachO::sub_client_command)) { 1503 Err = malformedError("load command " + Twine(I) + 1504 " LC_SUB_CLIENT cmdsize too small"); 1505 return; 1506 } 1507 MachO::sub_client_command S = 1508 getStruct<MachO::sub_client_command>(*this, Load.Ptr); 1509 if ((Err = checkSubCommand(*this, Load, I, "LC_SUB_CLIENT", 1510 sizeof(MachO::sub_client_command), 1511 "sub_client_command", S.client, "client"))) 1512 return; 1513 } else if (Load.C.cmd == MachO::LC_ROUTINES) { 1514 if (Load.C.cmdsize != sizeof(MachO::routines_command)) { 1515 Err = malformedError("LC_ROUTINES command " + Twine(I) + 1516 " has incorrect cmdsize"); 1517 return; 1518 } 1519 if (RoutinesLoadCmd) { 1520 Err = malformedError("more than one LC_ROUTINES and or LC_ROUTINES_64 " 1521 "command"); 1522 return; 1523 } 1524 RoutinesLoadCmd = Load.Ptr; 1525 } else if (Load.C.cmd == MachO::LC_ROUTINES_64) { 1526 if (Load.C.cmdsize != sizeof(MachO::routines_command_64)) { 1527 Err = malformedError("LC_ROUTINES_64 command " + Twine(I) + 1528 " has incorrect cmdsize"); 1529 return; 1530 } 1531 if (RoutinesLoadCmd) { 1532 Err = malformedError("more than one LC_ROUTINES_64 and or LC_ROUTINES " 1533 "command"); 1534 return; 1535 } 1536 RoutinesLoadCmd = Load.Ptr; 1537 } else if (Load.C.cmd == MachO::LC_UNIXTHREAD) { 1538 if ((Err = checkThreadCommand(*this, Load, I, "LC_UNIXTHREAD"))) 1539 return; 1540 if (UnixThreadLoadCmd) { 1541 Err = malformedError("more than one LC_UNIXTHREAD command"); 1542 return; 1543 } 1544 UnixThreadLoadCmd = Load.Ptr; 1545 } else if (Load.C.cmd == MachO::LC_THREAD) { 1546 if ((Err = checkThreadCommand(*this, Load, I, "LC_THREAD"))) 1547 return; 1548 // Note: LC_TWOLEVEL_HINTS is really obsolete and is not supported. 1549 } else if (Load.C.cmd == MachO::LC_TWOLEVEL_HINTS) { 1550 if ((Err = checkTwoLevelHintsCommand(*this, Load, I, 1551 &TwoLevelHintsLoadCmd, Elements))) 1552 return; 1553 } else if (isLoadCommandObsolete(Load.C.cmd)) { 1554 Err = malformedError("load command " + Twine(I) + " for cmd value of: " + 1555 Twine(Load.C.cmd) + " is obsolete and not " 1556 "supported"); 1557 return; 1558 } 1559 // TODO: generate a error for unknown load commands by default. But still 1560 // need work out an approach to allow or not allow unknown values like this 1561 // as an option for some uses like lldb. 1562 if (I < LoadCommandCount - 1) { 1563 if (auto LoadOrErr = getNextLoadCommandInfo(*this, I, Load)) 1564 Load = *LoadOrErr; 1565 else { 1566 Err = LoadOrErr.takeError(); 1567 return; 1568 } 1569 } 1570 } 1571 if (!SymtabLoadCmd) { 1572 if (DysymtabLoadCmd) { 1573 Err = malformedError("contains LC_DYSYMTAB load command without a " 1574 "LC_SYMTAB load command"); 1575 return; 1576 } 1577 } else if (DysymtabLoadCmd) { 1578 MachO::symtab_command Symtab = 1579 getStruct<MachO::symtab_command>(*this, SymtabLoadCmd); 1580 MachO::dysymtab_command Dysymtab = 1581 getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd); 1582 if (Dysymtab.nlocalsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) { 1583 Err = malformedError("ilocalsym in LC_DYSYMTAB load command " 1584 "extends past the end of the symbol table"); 1585 return; 1586 } 1587 uint64_t BigSize = Dysymtab.ilocalsym; 1588 BigSize += Dysymtab.nlocalsym; 1589 if (Dysymtab.nlocalsym != 0 && BigSize > Symtab.nsyms) { 1590 Err = malformedError("ilocalsym plus nlocalsym in LC_DYSYMTAB load " 1591 "command extends past the end of the symbol table"); 1592 return; 1593 } 1594 if (Dysymtab.nextdefsym != 0 && Dysymtab.ilocalsym > Symtab.nsyms) { 1595 Err = malformedError("nextdefsym in LC_DYSYMTAB load command " 1596 "extends past the end of the symbol table"); 1597 return; 1598 } 1599 BigSize = Dysymtab.iextdefsym; 1600 BigSize += Dysymtab.nextdefsym; 1601 if (Dysymtab.nextdefsym != 0 && BigSize > Symtab.nsyms) { 1602 Err = malformedError("iextdefsym plus nextdefsym in LC_DYSYMTAB " 1603 "load command extends past the end of the symbol " 1604 "table"); 1605 return; 1606 } 1607 if (Dysymtab.nundefsym != 0 && Dysymtab.iundefsym > Symtab.nsyms) { 1608 Err = malformedError("nundefsym in LC_DYSYMTAB load command " 1609 "extends past the end of the symbol table"); 1610 return; 1611 } 1612 BigSize = Dysymtab.iundefsym; 1613 BigSize += Dysymtab.nundefsym; 1614 if (Dysymtab.nundefsym != 0 && BigSize > Symtab.nsyms) { 1615 Err = malformedError("iundefsym plus nundefsym in LC_DYSYMTAB load " 1616 " command extends past the end of the symbol table"); 1617 return; 1618 } 1619 } 1620 if ((getHeader().filetype == MachO::MH_DYLIB || 1621 getHeader().filetype == MachO::MH_DYLIB_STUB) && 1622 DyldIdLoadCmd == nullptr) { 1623 Err = malformedError("no LC_ID_DYLIB load command in dynamic library " 1624 "filetype"); 1625 return; 1626 } 1627 assert(LoadCommands.size() == LoadCommandCount); 1628 1629 Err = Error::success(); 1630 } 1631 1632 Error MachOObjectFile::checkSymbolTable() const { 1633 uint32_t Flags = 0; 1634 if (is64Bit()) { 1635 MachO::mach_header_64 H_64 = MachOObjectFile::getHeader64(); 1636 Flags = H_64.flags; 1637 } else { 1638 MachO::mach_header H = MachOObjectFile::getHeader(); 1639 Flags = H.flags; 1640 } 1641 uint8_t NType = 0; 1642 uint8_t NSect = 0; 1643 uint16_t NDesc = 0; 1644 uint32_t NStrx = 0; 1645 uint64_t NValue = 0; 1646 uint32_t SymbolIndex = 0; 1647 MachO::symtab_command S = getSymtabLoadCommand(); 1648 for (const SymbolRef &Symbol : symbols()) { 1649 DataRefImpl SymDRI = Symbol.getRawDataRefImpl(); 1650 if (is64Bit()) { 1651 MachO::nlist_64 STE_64 = getSymbol64TableEntry(SymDRI); 1652 NType = STE_64.n_type; 1653 NSect = STE_64.n_sect; 1654 NDesc = STE_64.n_desc; 1655 NStrx = STE_64.n_strx; 1656 NValue = STE_64.n_value; 1657 } else { 1658 MachO::nlist STE = getSymbolTableEntry(SymDRI); 1659 NType = STE.n_type; 1660 NType = STE.n_type; 1661 NSect = STE.n_sect; 1662 NDesc = STE.n_desc; 1663 NStrx = STE.n_strx; 1664 NValue = STE.n_value; 1665 } 1666 if ((NType & MachO::N_STAB) == 0 && 1667 (NType & MachO::N_TYPE) == MachO::N_SECT) { 1668 if (NSect == 0 || NSect > Sections.size()) 1669 return malformedError("bad section index: " + Twine((int)NSect) + 1670 " for symbol at index " + Twine(SymbolIndex)); 1671 } 1672 if ((NType & MachO::N_STAB) == 0 && 1673 (NType & MachO::N_TYPE) == MachO::N_INDR) { 1674 if (NValue >= S.strsize) 1675 return malformedError("bad n_value: " + Twine((int)NValue) + " past " 1676 "the end of string table, for N_INDR symbol at " 1677 "index " + Twine(SymbolIndex)); 1678 } 1679 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 1680 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 1681 (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 1682 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 1683 if (LibraryOrdinal != 0 && 1684 LibraryOrdinal != MachO::EXECUTABLE_ORDINAL && 1685 LibraryOrdinal != MachO::DYNAMIC_LOOKUP_ORDINAL && 1686 LibraryOrdinal - 1 >= Libraries.size() ) { 1687 return malformedError("bad library ordinal: " + Twine(LibraryOrdinal) + 1688 " for symbol at index " + Twine(SymbolIndex)); 1689 } 1690 } 1691 if (NStrx >= S.strsize) 1692 return malformedError("bad string table index: " + Twine((int)NStrx) + 1693 " past the end of string table, for symbol at " 1694 "index " + Twine(SymbolIndex)); 1695 SymbolIndex++; 1696 } 1697 return Error::success(); 1698 } 1699 1700 void MachOObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 1701 unsigned SymbolTableEntrySize = is64Bit() ? 1702 sizeof(MachO::nlist_64) : 1703 sizeof(MachO::nlist); 1704 Symb.p += SymbolTableEntrySize; 1705 } 1706 1707 Expected<StringRef> MachOObjectFile::getSymbolName(DataRefImpl Symb) const { 1708 StringRef StringTable = getStringTableData(); 1709 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb); 1710 if (Entry.n_strx == 0) 1711 // A n_strx value of 0 indicates that no name is associated with a 1712 // particular symbol table entry. 1713 return StringRef(); 1714 const char *Start = &StringTable.data()[Entry.n_strx]; 1715 if (Start < getData().begin() || Start >= getData().end()) { 1716 return malformedError("bad string index: " + Twine(Entry.n_strx) + 1717 " for symbol at index " + Twine(getSymbolIndex(Symb))); 1718 } 1719 return StringRef(Start); 1720 } 1721 1722 unsigned MachOObjectFile::getSectionType(SectionRef Sec) const { 1723 DataRefImpl DRI = Sec.getRawDataRefImpl(); 1724 uint32_t Flags = getSectionFlags(*this, DRI); 1725 return Flags & MachO::SECTION_TYPE; 1726 } 1727 1728 uint64_t MachOObjectFile::getNValue(DataRefImpl Sym) const { 1729 if (is64Bit()) { 1730 MachO::nlist_64 Entry = getSymbol64TableEntry(Sym); 1731 return Entry.n_value; 1732 } 1733 MachO::nlist Entry = getSymbolTableEntry(Sym); 1734 return Entry.n_value; 1735 } 1736 1737 // getIndirectName() returns the name of the alias'ed symbol who's string table 1738 // index is in the n_value field. 1739 std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb, 1740 StringRef &Res) const { 1741 StringRef StringTable = getStringTableData(); 1742 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb); 1743 if ((Entry.n_type & MachO::N_TYPE) != MachO::N_INDR) 1744 return object_error::parse_failed; 1745 uint64_t NValue = getNValue(Symb); 1746 if (NValue >= StringTable.size()) 1747 return object_error::parse_failed; 1748 const char *Start = &StringTable.data()[NValue]; 1749 Res = StringRef(Start); 1750 return std::error_code(); 1751 } 1752 1753 uint64_t MachOObjectFile::getSymbolValueImpl(DataRefImpl Sym) const { 1754 return getNValue(Sym); 1755 } 1756 1757 Expected<uint64_t> MachOObjectFile::getSymbolAddress(DataRefImpl Sym) const { 1758 return getSymbolValue(Sym); 1759 } 1760 1761 uint32_t MachOObjectFile::getSymbolAlignment(DataRefImpl DRI) const { 1762 uint32_t flags = getSymbolFlags(DRI); 1763 if (flags & SymbolRef::SF_Common) { 1764 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI); 1765 return 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); 1766 } 1767 return 0; 1768 } 1769 1770 uint64_t MachOObjectFile::getCommonSymbolSizeImpl(DataRefImpl DRI) const { 1771 return getNValue(DRI); 1772 } 1773 1774 Expected<SymbolRef::Type> 1775 MachOObjectFile::getSymbolType(DataRefImpl Symb) const { 1776 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb); 1777 uint8_t n_type = Entry.n_type; 1778 1779 // If this is a STAB debugging symbol, we can do nothing more. 1780 if (n_type & MachO::N_STAB) 1781 return SymbolRef::ST_Debug; 1782 1783 switch (n_type & MachO::N_TYPE) { 1784 case MachO::N_UNDF : 1785 return SymbolRef::ST_Unknown; 1786 case MachO::N_SECT : 1787 Expected<section_iterator> SecOrError = getSymbolSection(Symb); 1788 if (!SecOrError) 1789 return SecOrError.takeError(); 1790 section_iterator Sec = *SecOrError; 1791 if (Sec->isData() || Sec->isBSS()) 1792 return SymbolRef::ST_Data; 1793 return SymbolRef::ST_Function; 1794 } 1795 return SymbolRef::ST_Other; 1796 } 1797 1798 uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const { 1799 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, DRI); 1800 1801 uint8_t MachOType = Entry.n_type; 1802 uint16_t MachOFlags = Entry.n_desc; 1803 1804 uint32_t Result = SymbolRef::SF_None; 1805 1806 if ((MachOType & MachO::N_TYPE) == MachO::N_INDR) 1807 Result |= SymbolRef::SF_Indirect; 1808 1809 if (MachOType & MachO::N_STAB) 1810 Result |= SymbolRef::SF_FormatSpecific; 1811 1812 if (MachOType & MachO::N_EXT) { 1813 Result |= SymbolRef::SF_Global; 1814 if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { 1815 if (getNValue(DRI)) 1816 Result |= SymbolRef::SF_Common; 1817 else 1818 Result |= SymbolRef::SF_Undefined; 1819 } 1820 1821 if (!(MachOType & MachO::N_PEXT)) 1822 Result |= SymbolRef::SF_Exported; 1823 } 1824 1825 if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 1826 Result |= SymbolRef::SF_Weak; 1827 1828 if (MachOFlags & (MachO::N_ARM_THUMB_DEF)) 1829 Result |= SymbolRef::SF_Thumb; 1830 1831 if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) 1832 Result |= SymbolRef::SF_Absolute; 1833 1834 return Result; 1835 } 1836 1837 Expected<section_iterator> 1838 MachOObjectFile::getSymbolSection(DataRefImpl Symb) const { 1839 MachO::nlist_base Entry = getSymbolTableEntryBase(*this, Symb); 1840 uint8_t index = Entry.n_sect; 1841 1842 if (index == 0) 1843 return section_end(); 1844 DataRefImpl DRI; 1845 DRI.d.a = index - 1; 1846 if (DRI.d.a >= Sections.size()){ 1847 return malformedError("bad section index: " + Twine((int)index) + 1848 " for symbol at index " + Twine(getSymbolIndex(Symb))); 1849 } 1850 return section_iterator(SectionRef(DRI, this)); 1851 } 1852 1853 unsigned MachOObjectFile::getSymbolSectionID(SymbolRef Sym) const { 1854 MachO::nlist_base Entry = 1855 getSymbolTableEntryBase(*this, Sym.getRawDataRefImpl()); 1856 return Entry.n_sect - 1; 1857 } 1858 1859 void MachOObjectFile::moveSectionNext(DataRefImpl &Sec) const { 1860 Sec.d.a++; 1861 } 1862 1863 std::error_code MachOObjectFile::getSectionName(DataRefImpl Sec, 1864 StringRef &Result) const { 1865 ArrayRef<char> Raw = getSectionRawName(Sec); 1866 Result = parseSegmentOrSectionName(Raw.data()); 1867 return std::error_code(); 1868 } 1869 1870 uint64_t MachOObjectFile::getSectionAddress(DataRefImpl Sec) const { 1871 if (is64Bit()) 1872 return getSection64(Sec).addr; 1873 return getSection(Sec).addr; 1874 } 1875 1876 uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { 1877 return Sec.d.a; 1878 } 1879 1880 uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { 1881 // In the case if a malformed Mach-O file where the section offset is past 1882 // the end of the file or some part of the section size is past the end of 1883 // the file return a size of zero or a size that covers the rest of the file 1884 // but does not extend past the end of the file. 1885 uint32_t SectOffset, SectType; 1886 uint64_t SectSize; 1887 1888 if (is64Bit()) { 1889 MachO::section_64 Sect = getSection64(Sec); 1890 SectOffset = Sect.offset; 1891 SectSize = Sect.size; 1892 SectType = Sect.flags & MachO::SECTION_TYPE; 1893 } else { 1894 MachO::section Sect = getSection(Sec); 1895 SectOffset = Sect.offset; 1896 SectSize = Sect.size; 1897 SectType = Sect.flags & MachO::SECTION_TYPE; 1898 } 1899 if (SectType == MachO::S_ZEROFILL || SectType == MachO::S_GB_ZEROFILL) 1900 return SectSize; 1901 uint64_t FileSize = getData().size(); 1902 if (SectOffset > FileSize) 1903 return 0; 1904 if (FileSize - SectOffset < SectSize) 1905 return FileSize - SectOffset; 1906 return SectSize; 1907 } 1908 1909 std::error_code MachOObjectFile::getSectionContents(DataRefImpl Sec, 1910 StringRef &Res) const { 1911 uint32_t Offset; 1912 uint64_t Size; 1913 1914 if (is64Bit()) { 1915 MachO::section_64 Sect = getSection64(Sec); 1916 Offset = Sect.offset; 1917 Size = Sect.size; 1918 } else { 1919 MachO::section Sect = getSection(Sec); 1920 Offset = Sect.offset; 1921 Size = Sect.size; 1922 } 1923 1924 Res = this->getData().substr(Offset, Size); 1925 return std::error_code(); 1926 } 1927 1928 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const { 1929 uint32_t Align; 1930 if (is64Bit()) { 1931 MachO::section_64 Sect = getSection64(Sec); 1932 Align = Sect.align; 1933 } else { 1934 MachO::section Sect = getSection(Sec); 1935 Align = Sect.align; 1936 } 1937 1938 return uint64_t(1) << Align; 1939 } 1940 1941 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const { 1942 return false; 1943 } 1944 1945 bool MachOObjectFile::isSectionText(DataRefImpl Sec) const { 1946 uint32_t Flags = getSectionFlags(*this, Sec); 1947 return Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; 1948 } 1949 1950 bool MachOObjectFile::isSectionData(DataRefImpl Sec) const { 1951 uint32_t Flags = getSectionFlags(*this, Sec); 1952 unsigned SectionType = Flags & MachO::SECTION_TYPE; 1953 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 1954 !(SectionType == MachO::S_ZEROFILL || 1955 SectionType == MachO::S_GB_ZEROFILL); 1956 } 1957 1958 bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const { 1959 uint32_t Flags = getSectionFlags(*this, Sec); 1960 unsigned SectionType = Flags & MachO::SECTION_TYPE; 1961 return !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) && 1962 (SectionType == MachO::S_ZEROFILL || 1963 SectionType == MachO::S_GB_ZEROFILL); 1964 } 1965 1966 unsigned MachOObjectFile::getSectionID(SectionRef Sec) const { 1967 return Sec.getRawDataRefImpl().d.a; 1968 } 1969 1970 bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const { 1971 // FIXME: Unimplemented. 1972 return false; 1973 } 1974 1975 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const { 1976 StringRef SegmentName = getSectionFinalSegmentName(Sec); 1977 StringRef SectName; 1978 if (!getSectionName(Sec, SectName)) 1979 return (SegmentName == "__LLVM" && SectName == "__bitcode"); 1980 return false; 1981 } 1982 1983 bool MachOObjectFile::isSectionStripped(DataRefImpl Sec) const { 1984 if (is64Bit()) 1985 return getSection64(Sec).offset == 0; 1986 return getSection(Sec).offset == 0; 1987 } 1988 1989 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 1990 DataRefImpl Ret; 1991 Ret.d.a = Sec.d.a; 1992 Ret.d.b = 0; 1993 return relocation_iterator(RelocationRef(Ret, this)); 1994 } 1995 1996 relocation_iterator 1997 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 1998 uint32_t Num; 1999 if (is64Bit()) { 2000 MachO::section_64 Sect = getSection64(Sec); 2001 Num = Sect.nreloc; 2002 } else { 2003 MachO::section Sect = getSection(Sec); 2004 Num = Sect.nreloc; 2005 } 2006 2007 DataRefImpl Ret; 2008 Ret.d.a = Sec.d.a; 2009 Ret.d.b = Num; 2010 return relocation_iterator(RelocationRef(Ret, this)); 2011 } 2012 2013 relocation_iterator MachOObjectFile::extrel_begin() const { 2014 DataRefImpl Ret; 2015 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2016 Ret.d.a = 0; // Would normally be a section index. 2017 Ret.d.b = 0; // Index into the external relocations 2018 return relocation_iterator(RelocationRef(Ret, this)); 2019 } 2020 2021 relocation_iterator MachOObjectFile::extrel_end() const { 2022 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 2023 DataRefImpl Ret; 2024 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2025 Ret.d.a = 0; // Would normally be a section index. 2026 Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations 2027 return relocation_iterator(RelocationRef(Ret, this)); 2028 } 2029 2030 relocation_iterator MachOObjectFile::locrel_begin() const { 2031 DataRefImpl Ret; 2032 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2033 Ret.d.a = 1; // Would normally be a section index. 2034 Ret.d.b = 0; // Index into the local relocations 2035 return relocation_iterator(RelocationRef(Ret, this)); 2036 } 2037 2038 relocation_iterator MachOObjectFile::locrel_end() const { 2039 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 2040 DataRefImpl Ret; 2041 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2042 Ret.d.a = 1; // Would normally be a section index. 2043 Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations 2044 return relocation_iterator(RelocationRef(Ret, this)); 2045 } 2046 2047 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 2048 ++Rel.d.b; 2049 } 2050 2051 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const { 2052 assert((getHeader().filetype == MachO::MH_OBJECT || 2053 getHeader().filetype == MachO::MH_KEXT_BUNDLE) && 2054 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE"); 2055 MachO::any_relocation_info RE = getRelocation(Rel); 2056 return getAnyRelocationAddress(RE); 2057 } 2058 2059 symbol_iterator 2060 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 2061 MachO::any_relocation_info RE = getRelocation(Rel); 2062 if (isRelocationScattered(RE)) 2063 return symbol_end(); 2064 2065 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 2066 bool isExtern = getPlainRelocationExternal(RE); 2067 if (!isExtern) 2068 return symbol_end(); 2069 2070 MachO::symtab_command S = getSymtabLoadCommand(); 2071 unsigned SymbolTableEntrySize = is64Bit() ? 2072 sizeof(MachO::nlist_64) : 2073 sizeof(MachO::nlist); 2074 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 2075 DataRefImpl Sym; 2076 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2077 return symbol_iterator(SymbolRef(Sym, this)); 2078 } 2079 2080 section_iterator 2081 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { 2082 return section_iterator(getAnyRelocationSection(getRelocation(Rel))); 2083 } 2084 2085 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const { 2086 MachO::any_relocation_info RE = getRelocation(Rel); 2087 return getAnyRelocationType(RE); 2088 } 2089 2090 void MachOObjectFile::getRelocationTypeName( 2091 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 2092 StringRef res; 2093 uint64_t RType = getRelocationType(Rel); 2094 2095 unsigned Arch = this->getArch(); 2096 2097 switch (Arch) { 2098 case Triple::x86: { 2099 static const char *const Table[] = { 2100 "GENERIC_RELOC_VANILLA", 2101 "GENERIC_RELOC_PAIR", 2102 "GENERIC_RELOC_SECTDIFF", 2103 "GENERIC_RELOC_PB_LA_PTR", 2104 "GENERIC_RELOC_LOCAL_SECTDIFF", 2105 "GENERIC_RELOC_TLV" }; 2106 2107 if (RType > 5) 2108 res = "Unknown"; 2109 else 2110 res = Table[RType]; 2111 break; 2112 } 2113 case Triple::x86_64: { 2114 static const char *const Table[] = { 2115 "X86_64_RELOC_UNSIGNED", 2116 "X86_64_RELOC_SIGNED", 2117 "X86_64_RELOC_BRANCH", 2118 "X86_64_RELOC_GOT_LOAD", 2119 "X86_64_RELOC_GOT", 2120 "X86_64_RELOC_SUBTRACTOR", 2121 "X86_64_RELOC_SIGNED_1", 2122 "X86_64_RELOC_SIGNED_2", 2123 "X86_64_RELOC_SIGNED_4", 2124 "X86_64_RELOC_TLV" }; 2125 2126 if (RType > 9) 2127 res = "Unknown"; 2128 else 2129 res = Table[RType]; 2130 break; 2131 } 2132 case Triple::arm: { 2133 static const char *const Table[] = { 2134 "ARM_RELOC_VANILLA", 2135 "ARM_RELOC_PAIR", 2136 "ARM_RELOC_SECTDIFF", 2137 "ARM_RELOC_LOCAL_SECTDIFF", 2138 "ARM_RELOC_PB_LA_PTR", 2139 "ARM_RELOC_BR24", 2140 "ARM_THUMB_RELOC_BR22", 2141 "ARM_THUMB_32BIT_BRANCH", 2142 "ARM_RELOC_HALF", 2143 "ARM_RELOC_HALF_SECTDIFF" }; 2144 2145 if (RType > 9) 2146 res = "Unknown"; 2147 else 2148 res = Table[RType]; 2149 break; 2150 } 2151 case Triple::aarch64: { 2152 static const char *const Table[] = { 2153 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 2154 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 2155 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 2156 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 2157 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 2158 "ARM64_RELOC_ADDEND" 2159 }; 2160 2161 if (RType >= array_lengthof(Table)) 2162 res = "Unknown"; 2163 else 2164 res = Table[RType]; 2165 break; 2166 } 2167 case Triple::ppc: { 2168 static const char *const Table[] = { 2169 "PPC_RELOC_VANILLA", 2170 "PPC_RELOC_PAIR", 2171 "PPC_RELOC_BR14", 2172 "PPC_RELOC_BR24", 2173 "PPC_RELOC_HI16", 2174 "PPC_RELOC_LO16", 2175 "PPC_RELOC_HA16", 2176 "PPC_RELOC_LO14", 2177 "PPC_RELOC_SECTDIFF", 2178 "PPC_RELOC_PB_LA_PTR", 2179 "PPC_RELOC_HI16_SECTDIFF", 2180 "PPC_RELOC_LO16_SECTDIFF", 2181 "PPC_RELOC_HA16_SECTDIFF", 2182 "PPC_RELOC_JBSR", 2183 "PPC_RELOC_LO14_SECTDIFF", 2184 "PPC_RELOC_LOCAL_SECTDIFF" }; 2185 2186 if (RType > 15) 2187 res = "Unknown"; 2188 else 2189 res = Table[RType]; 2190 break; 2191 } 2192 case Triple::UnknownArch: 2193 res = "Unknown"; 2194 break; 2195 } 2196 Result.append(res.begin(), res.end()); 2197 } 2198 2199 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { 2200 MachO::any_relocation_info RE = getRelocation(Rel); 2201 return getAnyRelocationLength(RE); 2202 } 2203 2204 // 2205 // guessLibraryShortName() is passed a name of a dynamic library and returns a 2206 // guess on what the short name is. Then name is returned as a substring of the 2207 // StringRef Name passed in. The name of the dynamic library is recognized as 2208 // a framework if it has one of the two following forms: 2209 // Foo.framework/Versions/A/Foo 2210 // Foo.framework/Foo 2211 // Where A and Foo can be any string. And may contain a trailing suffix 2212 // starting with an underbar. If the Name is recognized as a framework then 2213 // isFramework is set to true else it is set to false. If the Name has a 2214 // suffix then Suffix is set to the substring in Name that contains the suffix 2215 // else it is set to a NULL StringRef. 2216 // 2217 // The Name of the dynamic library is recognized as a library name if it has 2218 // one of the two following forms: 2219 // libFoo.A.dylib 2220 // libFoo.dylib 2221 // The library may have a suffix trailing the name Foo of the form: 2222 // libFoo_profile.A.dylib 2223 // libFoo_profile.dylib 2224 // 2225 // The Name of the dynamic library is also recognized as a library name if it 2226 // has the following form: 2227 // Foo.qtx 2228 // 2229 // If the Name of the dynamic library is none of the forms above then a NULL 2230 // StringRef is returned. 2231 // 2232 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 2233 bool &isFramework, 2234 StringRef &Suffix) { 2235 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 2236 size_t a, b, c, d, Idx; 2237 2238 isFramework = false; 2239 Suffix = StringRef(); 2240 2241 // Pull off the last component and make Foo point to it 2242 a = Name.rfind('/'); 2243 if (a == Name.npos || a == 0) 2244 goto guess_library; 2245 Foo = Name.slice(a+1, Name.npos); 2246 2247 // Look for a suffix starting with a '_' 2248 Idx = Foo.rfind('_'); 2249 if (Idx != Foo.npos && Foo.size() >= 2) { 2250 Suffix = Foo.slice(Idx, Foo.npos); 2251 Foo = Foo.slice(0, Idx); 2252 } 2253 2254 // First look for the form Foo.framework/Foo 2255 b = Name.rfind('/', a); 2256 if (b == Name.npos) 2257 Idx = 0; 2258 else 2259 Idx = b+1; 2260 F = Name.slice(Idx, Idx + Foo.size()); 2261 DotFramework = Name.slice(Idx + Foo.size(), 2262 Idx + Foo.size() + sizeof(".framework/")-1); 2263 if (F == Foo && DotFramework == ".framework/") { 2264 isFramework = true; 2265 return Foo; 2266 } 2267 2268 // Next look for the form Foo.framework/Versions/A/Foo 2269 if (b == Name.npos) 2270 goto guess_library; 2271 c = Name.rfind('/', b); 2272 if (c == Name.npos || c == 0) 2273 goto guess_library; 2274 V = Name.slice(c+1, Name.npos); 2275 if (!V.startswith("Versions/")) 2276 goto guess_library; 2277 d = Name.rfind('/', c); 2278 if (d == Name.npos) 2279 Idx = 0; 2280 else 2281 Idx = d+1; 2282 F = Name.slice(Idx, Idx + Foo.size()); 2283 DotFramework = Name.slice(Idx + Foo.size(), 2284 Idx + Foo.size() + sizeof(".framework/")-1); 2285 if (F == Foo && DotFramework == ".framework/") { 2286 isFramework = true; 2287 return Foo; 2288 } 2289 2290 guess_library: 2291 // pull off the suffix after the "." and make a point to it 2292 a = Name.rfind('.'); 2293 if (a == Name.npos || a == 0) 2294 return StringRef(); 2295 Dylib = Name.slice(a, Name.npos); 2296 if (Dylib != ".dylib") 2297 goto guess_qtx; 2298 2299 // First pull off the version letter for the form Foo.A.dylib if any. 2300 if (a >= 3) { 2301 Dot = Name.slice(a-2, a-1); 2302 if (Dot == ".") 2303 a = a - 2; 2304 } 2305 2306 b = Name.rfind('/', a); 2307 if (b == Name.npos) 2308 b = 0; 2309 else 2310 b = b+1; 2311 // ignore any suffix after an underbar like Foo_profile.A.dylib 2312 Idx = Name.find('_', b); 2313 if (Idx != Name.npos && Idx != b) { 2314 Lib = Name.slice(b, Idx); 2315 Suffix = Name.slice(Idx, a); 2316 } 2317 else 2318 Lib = Name.slice(b, a); 2319 // There are incorrect library names of the form: 2320 // libATS.A_profile.dylib so check for these. 2321 if (Lib.size() >= 3) { 2322 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 2323 if (Dot == ".") 2324 Lib = Lib.slice(0, Lib.size()-2); 2325 } 2326 return Lib; 2327 2328 guess_qtx: 2329 Qtx = Name.slice(a, Name.npos); 2330 if (Qtx != ".qtx") 2331 return StringRef(); 2332 b = Name.rfind('/', a); 2333 if (b == Name.npos) 2334 Lib = Name.slice(0, a); 2335 else 2336 Lib = Name.slice(b+1, a); 2337 // There are library names of the form: QT.A.qtx so check for these. 2338 if (Lib.size() >= 3) { 2339 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 2340 if (Dot == ".") 2341 Lib = Lib.slice(0, Lib.size()-2); 2342 } 2343 return Lib; 2344 } 2345 2346 // getLibraryShortNameByIndex() is used to get the short name of the library 2347 // for an undefined symbol in a linked Mach-O binary that was linked with the 2348 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 2349 // It is passed the index (0 - based) of the library as translated from 2350 // GET_LIBRARY_ORDINAL (1 - based). 2351 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 2352 StringRef &Res) const { 2353 if (Index >= Libraries.size()) 2354 return object_error::parse_failed; 2355 2356 // If the cache of LibrariesShortNames is not built up do that first for 2357 // all the Libraries. 2358 if (LibrariesShortNames.size() == 0) { 2359 for (unsigned i = 0; i < Libraries.size(); i++) { 2360 MachO::dylib_command D = 2361 getStruct<MachO::dylib_command>(*this, Libraries[i]); 2362 if (D.dylib.name >= D.cmdsize) 2363 return object_error::parse_failed; 2364 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 2365 StringRef Name = StringRef(P); 2366 if (D.dylib.name+Name.size() >= D.cmdsize) 2367 return object_error::parse_failed; 2368 StringRef Suffix; 2369 bool isFramework; 2370 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 2371 if (shortName.empty()) 2372 LibrariesShortNames.push_back(Name); 2373 else 2374 LibrariesShortNames.push_back(shortName); 2375 } 2376 } 2377 2378 Res = LibrariesShortNames[Index]; 2379 return std::error_code(); 2380 } 2381 2382 uint32_t MachOObjectFile::getLibraryCount() const { 2383 return Libraries.size(); 2384 } 2385 2386 section_iterator 2387 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const { 2388 DataRefImpl Sec; 2389 Sec.d.a = Rel->getRawDataRefImpl().d.a; 2390 return section_iterator(SectionRef(Sec, this)); 2391 } 2392 2393 basic_symbol_iterator MachOObjectFile::symbol_begin() const { 2394 DataRefImpl DRI; 2395 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2396 if (!SymtabLoadCmd || Symtab.nsyms == 0) 2397 return basic_symbol_iterator(SymbolRef(DRI, this)); 2398 2399 return getSymbolByIndex(0); 2400 } 2401 2402 basic_symbol_iterator MachOObjectFile::symbol_end() const { 2403 DataRefImpl DRI; 2404 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2405 if (!SymtabLoadCmd || Symtab.nsyms == 0) 2406 return basic_symbol_iterator(SymbolRef(DRI, this)); 2407 2408 unsigned SymbolTableEntrySize = is64Bit() ? 2409 sizeof(MachO::nlist_64) : 2410 sizeof(MachO::nlist); 2411 unsigned Offset = Symtab.symoff + 2412 Symtab.nsyms * SymbolTableEntrySize; 2413 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2414 return basic_symbol_iterator(SymbolRef(DRI, this)); 2415 } 2416 2417 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 2418 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2419 if (!SymtabLoadCmd || Index >= Symtab.nsyms) 2420 report_fatal_error("Requested symbol index is out of range."); 2421 unsigned SymbolTableEntrySize = 2422 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 2423 DataRefImpl DRI; 2424 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff)); 2425 DRI.p += Index * SymbolTableEntrySize; 2426 return basic_symbol_iterator(SymbolRef(DRI, this)); 2427 } 2428 2429 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const { 2430 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2431 if (!SymtabLoadCmd) 2432 report_fatal_error("getSymbolIndex() called with no symbol table symbol"); 2433 unsigned SymbolTableEntrySize = 2434 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 2435 DataRefImpl DRIstart; 2436 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff)); 2437 uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize; 2438 return Index; 2439 } 2440 2441 section_iterator MachOObjectFile::section_begin() const { 2442 DataRefImpl DRI; 2443 return section_iterator(SectionRef(DRI, this)); 2444 } 2445 2446 section_iterator MachOObjectFile::section_end() const { 2447 DataRefImpl DRI; 2448 DRI.d.a = Sections.size(); 2449 return section_iterator(SectionRef(DRI, this)); 2450 } 2451 2452 uint8_t MachOObjectFile::getBytesInAddress() const { 2453 return is64Bit() ? 8 : 4; 2454 } 2455 2456 StringRef MachOObjectFile::getFileFormatName() const { 2457 unsigned CPUType = getCPUType(*this); 2458 if (!is64Bit()) { 2459 switch (CPUType) { 2460 case MachO::CPU_TYPE_I386: 2461 return "Mach-O 32-bit i386"; 2462 case MachO::CPU_TYPE_ARM: 2463 return "Mach-O arm"; 2464 case MachO::CPU_TYPE_POWERPC: 2465 return "Mach-O 32-bit ppc"; 2466 default: 2467 return "Mach-O 32-bit unknown"; 2468 } 2469 } 2470 2471 switch (CPUType) { 2472 case MachO::CPU_TYPE_X86_64: 2473 return "Mach-O 64-bit x86-64"; 2474 case MachO::CPU_TYPE_ARM64: 2475 return "Mach-O arm64"; 2476 case MachO::CPU_TYPE_POWERPC64: 2477 return "Mach-O 64-bit ppc64"; 2478 default: 2479 return "Mach-O 64-bit unknown"; 2480 } 2481 } 2482 2483 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 2484 switch (CPUType) { 2485 case MachO::CPU_TYPE_I386: 2486 return Triple::x86; 2487 case MachO::CPU_TYPE_X86_64: 2488 return Triple::x86_64; 2489 case MachO::CPU_TYPE_ARM: 2490 return Triple::arm; 2491 case MachO::CPU_TYPE_ARM64: 2492 return Triple::aarch64; 2493 case MachO::CPU_TYPE_POWERPC: 2494 return Triple::ppc; 2495 case MachO::CPU_TYPE_POWERPC64: 2496 return Triple::ppc64; 2497 default: 2498 return Triple::UnknownArch; 2499 } 2500 } 2501 2502 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType, 2503 const char **McpuDefault, 2504 const char **ArchFlag) { 2505 if (McpuDefault) 2506 *McpuDefault = nullptr; 2507 if (ArchFlag) 2508 *ArchFlag = nullptr; 2509 2510 switch (CPUType) { 2511 case MachO::CPU_TYPE_I386: 2512 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2513 case MachO::CPU_SUBTYPE_I386_ALL: 2514 if (ArchFlag) 2515 *ArchFlag = "i386"; 2516 return Triple("i386-apple-darwin"); 2517 default: 2518 return Triple(); 2519 } 2520 case MachO::CPU_TYPE_X86_64: 2521 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2522 case MachO::CPU_SUBTYPE_X86_64_ALL: 2523 if (ArchFlag) 2524 *ArchFlag = "x86_64"; 2525 return Triple("x86_64-apple-darwin"); 2526 case MachO::CPU_SUBTYPE_X86_64_H: 2527 if (ArchFlag) 2528 *ArchFlag = "x86_64h"; 2529 return Triple("x86_64h-apple-darwin"); 2530 default: 2531 return Triple(); 2532 } 2533 case MachO::CPU_TYPE_ARM: 2534 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2535 case MachO::CPU_SUBTYPE_ARM_V4T: 2536 if (ArchFlag) 2537 *ArchFlag = "armv4t"; 2538 return Triple("armv4t-apple-darwin"); 2539 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 2540 if (ArchFlag) 2541 *ArchFlag = "armv5e"; 2542 return Triple("armv5e-apple-darwin"); 2543 case MachO::CPU_SUBTYPE_ARM_XSCALE: 2544 if (ArchFlag) 2545 *ArchFlag = "xscale"; 2546 return Triple("xscale-apple-darwin"); 2547 case MachO::CPU_SUBTYPE_ARM_V6: 2548 if (ArchFlag) 2549 *ArchFlag = "armv6"; 2550 return Triple("armv6-apple-darwin"); 2551 case MachO::CPU_SUBTYPE_ARM_V6M: 2552 if (McpuDefault) 2553 *McpuDefault = "cortex-m0"; 2554 if (ArchFlag) 2555 *ArchFlag = "armv6m"; 2556 return Triple("armv6m-apple-darwin"); 2557 case MachO::CPU_SUBTYPE_ARM_V7: 2558 if (ArchFlag) 2559 *ArchFlag = "armv7"; 2560 return Triple("armv7-apple-darwin"); 2561 case MachO::CPU_SUBTYPE_ARM_V7EM: 2562 if (McpuDefault) 2563 *McpuDefault = "cortex-m4"; 2564 if (ArchFlag) 2565 *ArchFlag = "armv7em"; 2566 return Triple("thumbv7em-apple-darwin"); 2567 case MachO::CPU_SUBTYPE_ARM_V7K: 2568 if (McpuDefault) 2569 *McpuDefault = "cortex-a7"; 2570 if (ArchFlag) 2571 *ArchFlag = "armv7k"; 2572 return Triple("armv7k-apple-darwin"); 2573 case MachO::CPU_SUBTYPE_ARM_V7M: 2574 if (McpuDefault) 2575 *McpuDefault = "cortex-m3"; 2576 if (ArchFlag) 2577 *ArchFlag = "armv7m"; 2578 return Triple("thumbv7m-apple-darwin"); 2579 case MachO::CPU_SUBTYPE_ARM_V7S: 2580 if (McpuDefault) 2581 *McpuDefault = "cortex-a7"; 2582 if (ArchFlag) 2583 *ArchFlag = "armv7s"; 2584 return Triple("armv7s-apple-darwin"); 2585 default: 2586 return Triple(); 2587 } 2588 case MachO::CPU_TYPE_ARM64: 2589 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2590 case MachO::CPU_SUBTYPE_ARM64_ALL: 2591 if (McpuDefault) 2592 *McpuDefault = "cyclone"; 2593 if (ArchFlag) 2594 *ArchFlag = "arm64"; 2595 return Triple("arm64-apple-darwin"); 2596 default: 2597 return Triple(); 2598 } 2599 case MachO::CPU_TYPE_POWERPC: 2600 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2601 case MachO::CPU_SUBTYPE_POWERPC_ALL: 2602 if (ArchFlag) 2603 *ArchFlag = "ppc"; 2604 return Triple("ppc-apple-darwin"); 2605 default: 2606 return Triple(); 2607 } 2608 case MachO::CPU_TYPE_POWERPC64: 2609 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2610 case MachO::CPU_SUBTYPE_POWERPC_ALL: 2611 if (ArchFlag) 2612 *ArchFlag = "ppc64"; 2613 return Triple("ppc64-apple-darwin"); 2614 default: 2615 return Triple(); 2616 } 2617 default: 2618 return Triple(); 2619 } 2620 } 2621 2622 Triple MachOObjectFile::getHostArch() { 2623 return Triple(sys::getDefaultTargetTriple()); 2624 } 2625 2626 bool MachOObjectFile::isValidArch(StringRef ArchFlag) { 2627 return StringSwitch<bool>(ArchFlag) 2628 .Case("i386", true) 2629 .Case("x86_64", true) 2630 .Case("x86_64h", true) 2631 .Case("armv4t", true) 2632 .Case("arm", true) 2633 .Case("armv5e", true) 2634 .Case("armv6", true) 2635 .Case("armv6m", true) 2636 .Case("armv7", true) 2637 .Case("armv7em", true) 2638 .Case("armv7k", true) 2639 .Case("armv7m", true) 2640 .Case("armv7s", true) 2641 .Case("arm64", true) 2642 .Case("ppc", true) 2643 .Case("ppc64", true) 2644 .Default(false); 2645 } 2646 2647 Triple::ArchType MachOObjectFile::getArch() const { 2648 return getArch(getCPUType(*this)); 2649 } 2650 2651 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const { 2652 return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault); 2653 } 2654 2655 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 2656 DataRefImpl DRI; 2657 DRI.d.a = Index; 2658 return section_rel_begin(DRI); 2659 } 2660 2661 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 2662 DataRefImpl DRI; 2663 DRI.d.a = Index; 2664 return section_rel_end(DRI); 2665 } 2666 2667 dice_iterator MachOObjectFile::begin_dices() const { 2668 DataRefImpl DRI; 2669 if (!DataInCodeLoadCmd) 2670 return dice_iterator(DiceRef(DRI, this)); 2671 2672 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 2673 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff)); 2674 return dice_iterator(DiceRef(DRI, this)); 2675 } 2676 2677 dice_iterator MachOObjectFile::end_dices() const { 2678 DataRefImpl DRI; 2679 if (!DataInCodeLoadCmd) 2680 return dice_iterator(DiceRef(DRI, this)); 2681 2682 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 2683 unsigned Offset = DicLC.dataoff + DicLC.datasize; 2684 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2685 return dice_iterator(DiceRef(DRI, this)); 2686 } 2687 2688 ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O, 2689 ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {} 2690 2691 void ExportEntry::moveToFirst() { 2692 ErrorAsOutParameter ErrAsOutParam(E); 2693 pushNode(0); 2694 if (*E) 2695 return; 2696 pushDownUntilBottom(); 2697 } 2698 2699 void ExportEntry::moveToEnd() { 2700 Stack.clear(); 2701 Done = true; 2702 } 2703 2704 bool ExportEntry::operator==(const ExportEntry &Other) const { 2705 // Common case, one at end, other iterating from begin. 2706 if (Done || Other.Done) 2707 return (Done == Other.Done); 2708 // Not equal if different stack sizes. 2709 if (Stack.size() != Other.Stack.size()) 2710 return false; 2711 // Not equal if different cumulative strings. 2712 if (!CumulativeString.equals(Other.CumulativeString)) 2713 return false; 2714 // Equal if all nodes in both stacks match. 2715 for (unsigned i=0; i < Stack.size(); ++i) { 2716 if (Stack[i].Start != Other.Stack[i].Start) 2717 return false; 2718 } 2719 return true; 2720 } 2721 2722 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) { 2723 unsigned Count; 2724 uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error); 2725 Ptr += Count; 2726 if (Ptr > Trie.end()) 2727 Ptr = Trie.end(); 2728 return Result; 2729 } 2730 2731 StringRef ExportEntry::name() const { 2732 return CumulativeString; 2733 } 2734 2735 uint64_t ExportEntry::flags() const { 2736 return Stack.back().Flags; 2737 } 2738 2739 uint64_t ExportEntry::address() const { 2740 return Stack.back().Address; 2741 } 2742 2743 uint64_t ExportEntry::other() const { 2744 return Stack.back().Other; 2745 } 2746 2747 StringRef ExportEntry::otherName() const { 2748 const char* ImportName = Stack.back().ImportName; 2749 if (ImportName) 2750 return StringRef(ImportName); 2751 return StringRef(); 2752 } 2753 2754 uint32_t ExportEntry::nodeOffset() const { 2755 return Stack.back().Start - Trie.begin(); 2756 } 2757 2758 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 2759 : Start(Ptr), Current(Ptr) {} 2760 2761 void ExportEntry::pushNode(uint64_t offset) { 2762 ErrorAsOutParameter ErrAsOutParam(E); 2763 const uint8_t *Ptr = Trie.begin() + offset; 2764 NodeState State(Ptr); 2765 const char *error; 2766 uint64_t ExportInfoSize = readULEB128(State.Current, &error); 2767 if (error) { 2768 *E = malformedError("export info size " + Twine(error) + 2769 " in export trie data at node: 0x" + 2770 Twine::utohexstr(offset)); 2771 moveToEnd(); 2772 return; 2773 } 2774 State.IsExportNode = (ExportInfoSize != 0); 2775 const uint8_t* Children = State.Current + ExportInfoSize; 2776 if (Children > Trie.end()) { 2777 *E = malformedError( 2778 "export info size: 0x" + Twine::utohexstr(ExportInfoSize) + 2779 " in export trie data at node: 0x" + Twine::utohexstr(offset) + 2780 " too big and extends past end of trie data"); 2781 moveToEnd(); 2782 return; 2783 } 2784 if (State.IsExportNode) { 2785 const uint8_t *ExportStart = State.Current; 2786 State.Flags = readULEB128(State.Current, &error); 2787 if (error) { 2788 *E = malformedError("flags " + Twine(error) + 2789 " in export trie data at node: 0x" + 2790 Twine::utohexstr(offset)); 2791 moveToEnd(); 2792 return; 2793 } 2794 uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK; 2795 if (State.Flags != 0 && 2796 (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR && 2797 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE && 2798 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) { 2799 *E = malformedError( 2800 "unsupported exported symbol kind: " + Twine((int)Kind) + 2801 " in flags: 0x" + Twine::utohexstr(State.Flags) + 2802 " in export trie data at node: 0x" + Twine::utohexstr(offset)); 2803 moveToEnd(); 2804 return; 2805 } 2806 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 2807 State.Address = 0; 2808 State.Other = readULEB128(State.Current, &error); // dylib ordinal 2809 if (error) { 2810 *E = malformedError("dylib ordinal of re-export " + Twine(error) + 2811 " in export trie data at node: 0x" + 2812 Twine::utohexstr(offset)); 2813 moveToEnd(); 2814 return; 2815 } 2816 if (O != nullptr) { 2817 if (State.Other > O->getLibraryCount()) { 2818 *E = malformedError( 2819 "bad library ordinal: " + Twine((int)State.Other) + " (max " + 2820 Twine((int)O->getLibraryCount()) + 2821 ") in export trie data at node: 0x" + Twine::utohexstr(offset)); 2822 moveToEnd(); 2823 return; 2824 } 2825 } 2826 State.ImportName = reinterpret_cast<const char*>(State.Current); 2827 if (*State.ImportName == '\0') { 2828 State.Current++; 2829 } else { 2830 const uint8_t *End = State.Current + 1; 2831 if (End >= Trie.end()) { 2832 *E = malformedError("import name of re-export in export trie data at " 2833 "node: 0x" + 2834 Twine::utohexstr(offset) + 2835 " starts past end of trie data"); 2836 moveToEnd(); 2837 return; 2838 } 2839 while(*End != '\0' && End < Trie.end()) 2840 End++; 2841 if (*End != '\0') { 2842 *E = malformedError("import name of re-export in export trie data at " 2843 "node: 0x" + 2844 Twine::utohexstr(offset) + 2845 " extends past end of trie data"); 2846 moveToEnd(); 2847 return; 2848 } 2849 State.Current = End + 1; 2850 } 2851 } else { 2852 State.Address = readULEB128(State.Current, &error); 2853 if (error) { 2854 *E = malformedError("address " + Twine(error) + 2855 " in export trie data at node: 0x" + 2856 Twine::utohexstr(offset)); 2857 moveToEnd(); 2858 return; 2859 } 2860 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { 2861 State.Other = readULEB128(State.Current, &error); 2862 if (error) { 2863 *E = malformedError("resolver of stub and resolver " + Twine(error) + 2864 " in export trie data at node: 0x" + 2865 Twine::utohexstr(offset)); 2866 moveToEnd(); 2867 return; 2868 } 2869 } 2870 } 2871 if(ExportStart + ExportInfoSize != State.Current) { 2872 *E = malformedError( 2873 "inconsistant export info size: 0x" + 2874 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" + 2875 Twine::utohexstr(State.Current - ExportStart) + 2876 " in export trie data at node: 0x" + Twine::utohexstr(offset)); 2877 moveToEnd(); 2878 return; 2879 } 2880 } 2881 State.ChildCount = *Children; 2882 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) { 2883 *E = malformedError("byte for count of childern in export trie data at " 2884 "node: 0x" + 2885 Twine::utohexstr(offset) + 2886 " extends past end of trie data"); 2887 moveToEnd(); 2888 return; 2889 } 2890 State.Current = Children + 1; 2891 State.NextChildIndex = 0; 2892 State.ParentStringLength = CumulativeString.size(); 2893 Stack.push_back(State); 2894 } 2895 2896 void ExportEntry::pushDownUntilBottom() { 2897 ErrorAsOutParameter ErrAsOutParam(E); 2898 const char *error; 2899 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 2900 NodeState &Top = Stack.back(); 2901 CumulativeString.resize(Top.ParentStringLength); 2902 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) { 2903 char C = *Top.Current; 2904 CumulativeString.push_back(C); 2905 } 2906 if (Top.Current >= Trie.end()) { 2907 *E = malformedError("edge sub-string in export trie data at node: 0x" + 2908 Twine::utohexstr(Top.Start - Trie.begin()) + 2909 " for child #" + Twine((int)Top.NextChildIndex) + 2910 " extends past end of trie data"); 2911 moveToEnd(); 2912 return; 2913 } 2914 Top.Current += 1; 2915 uint64_t childNodeIndex = readULEB128(Top.Current, &error); 2916 if (error) { 2917 *E = malformedError("child node offset " + Twine(error) + 2918 " in export trie data at node: 0x" + 2919 Twine::utohexstr(Top.Start - Trie.begin())); 2920 moveToEnd(); 2921 return; 2922 } 2923 for (const NodeState &node : nodes()) { 2924 if (node.Start == Trie.begin() + childNodeIndex){ 2925 *E = malformedError("loop in childern in export trie data at node: 0x" + 2926 Twine::utohexstr(Top.Start - Trie.begin()) + 2927 " back to node: 0x" + 2928 Twine::utohexstr(childNodeIndex)); 2929 moveToEnd(); 2930 return; 2931 } 2932 } 2933 Top.NextChildIndex += 1; 2934 pushNode(childNodeIndex); 2935 if (*E) 2936 return; 2937 } 2938 if (!Stack.back().IsExportNode) { 2939 *E = malformedError("node is not an export node in export trie data at " 2940 "node: 0x" + 2941 Twine::utohexstr(Stack.back().Start - Trie.begin())); 2942 moveToEnd(); 2943 return; 2944 } 2945 } 2946 2947 // We have a trie data structure and need a way to walk it that is compatible 2948 // with the C++ iterator model. The solution is a non-recursive depth first 2949 // traversal where the iterator contains a stack of parent nodes along with a 2950 // string that is the accumulation of all edge strings along the parent chain 2951 // to this point. 2952 // 2953 // There is one "export" node for each exported symbol. But because some 2954 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 2955 // node may have child nodes too. 2956 // 2957 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 2958 // child until hitting a node with no children (which is an export node or 2959 // else the trie is malformed). On the way down, each node is pushed on the 2960 // stack ivar. If there is no more ways down, it pops up one and tries to go 2961 // down a sibling path until a childless node is reached. 2962 void ExportEntry::moveNext() { 2963 assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack"); 2964 if (!Stack.back().IsExportNode) { 2965 *E = malformedError("node is not an export node in export trie data at " 2966 "node: 0x" + 2967 Twine::utohexstr(Stack.back().Start - Trie.begin())); 2968 moveToEnd(); 2969 return; 2970 } 2971 2972 Stack.pop_back(); 2973 while (!Stack.empty()) { 2974 NodeState &Top = Stack.back(); 2975 if (Top.NextChildIndex < Top.ChildCount) { 2976 pushDownUntilBottom(); 2977 // Now at the next export node. 2978 return; 2979 } else { 2980 if (Top.IsExportNode) { 2981 // This node has no children but is itself an export node. 2982 CumulativeString.resize(Top.ParentStringLength); 2983 return; 2984 } 2985 Stack.pop_back(); 2986 } 2987 } 2988 Done = true; 2989 } 2990 2991 iterator_range<export_iterator> 2992 MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie, 2993 const MachOObjectFile *O) { 2994 ExportEntry Start(&E, O, Trie); 2995 if (Trie.empty()) 2996 Start.moveToEnd(); 2997 else 2998 Start.moveToFirst(); 2999 3000 ExportEntry Finish(&E, O, Trie); 3001 Finish.moveToEnd(); 3002 3003 return make_range(export_iterator(Start), export_iterator(Finish)); 3004 } 3005 3006 iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const { 3007 return exports(Err, getDyldInfoExportsTrie(), this); 3008 } 3009 3010 MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O, 3011 ArrayRef<uint8_t> Bytes, bool is64Bit) 3012 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), 3013 PointerSize(is64Bit ? 8 : 4) {} 3014 3015 void MachORebaseEntry::moveToFirst() { 3016 Ptr = Opcodes.begin(); 3017 moveNext(); 3018 } 3019 3020 void MachORebaseEntry::moveToEnd() { 3021 Ptr = Opcodes.end(); 3022 RemainingLoopCount = 0; 3023 Done = true; 3024 } 3025 3026 void MachORebaseEntry::moveNext() { 3027 ErrorAsOutParameter ErrAsOutParam(E); 3028 // If in the middle of some loop, move to next rebasing in loop. 3029 SegmentOffset += AdvanceAmount; 3030 if (RemainingLoopCount) { 3031 --RemainingLoopCount; 3032 return; 3033 } 3034 // REBASE_OPCODE_DONE is only used for padding if we are not aligned to 3035 // pointer size. Therefore it is possible to reach the end without ever having 3036 // seen REBASE_OPCODE_DONE. 3037 if (Ptr == Opcodes.end()) { 3038 Done = true; 3039 return; 3040 } 3041 bool More = true; 3042 while (More) { 3043 // Parse next opcode and set up next loop. 3044 const uint8_t *OpcodeStart = Ptr; 3045 uint8_t Byte = *Ptr++; 3046 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 3047 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 3048 uint32_t Count, Skip; 3049 const char *error = nullptr; 3050 switch (Opcode) { 3051 case MachO::REBASE_OPCODE_DONE: 3052 More = false; 3053 Done = true; 3054 moveToEnd(); 3055 DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n"); 3056 break; 3057 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 3058 RebaseType = ImmValue; 3059 if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) { 3060 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " + 3061 Twine((int)RebaseType) + " for opcode at: 0x" + 3062 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3063 moveToEnd(); 3064 return; 3065 } 3066 DEBUG_WITH_TYPE( 3067 "mach-o-rebase", 3068 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 3069 << "RebaseType=" << (int) RebaseType << "\n"); 3070 break; 3071 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 3072 SegmentIndex = ImmValue; 3073 SegmentOffset = readULEB128(&error); 3074 if (error) { 3075 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3076 Twine(error) + " for opcode at: 0x" + 3077 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3078 moveToEnd(); 3079 return; 3080 } 3081 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3082 true); 3083 if (error) { 3084 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3085 Twine(error) + " for opcode at: 0x" + 3086 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3087 moveToEnd(); 3088 return; 3089 } 3090 DEBUG_WITH_TYPE( 3091 "mach-o-rebase", 3092 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3093 << "SegmentIndex=" << SegmentIndex << ", " 3094 << format("SegmentOffset=0x%06X", SegmentOffset) 3095 << "\n"); 3096 break; 3097 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 3098 SegmentOffset += readULEB128(&error); 3099 if (error) { 3100 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3101 " for opcode at: 0x" + 3102 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3103 moveToEnd(); 3104 return; 3105 } 3106 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3107 true); 3108 if (error) { 3109 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3110 " for opcode at: 0x" + 3111 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3112 moveToEnd(); 3113 return; 3114 } 3115 DEBUG_WITH_TYPE("mach-o-rebase", 3116 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 3117 << format("SegmentOffset=0x%06X", 3118 SegmentOffset) << "\n"); 3119 break; 3120 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 3121 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3122 true); 3123 if (error) { 3124 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " + 3125 Twine(error) + " for opcode at: 0x" + 3126 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3127 moveToEnd(); 3128 return; 3129 } 3130 SegmentOffset += ImmValue * PointerSize; 3131 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3132 false); 3133 if (error) { 3134 *E = 3135 malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " 3136 " (after adding immediate times the pointer size) " + 3137 Twine(error) + " for opcode at: 0x" + 3138 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3139 moveToEnd(); 3140 return; 3141 } 3142 DEBUG_WITH_TYPE("mach-o-rebase", 3143 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 3144 << format("SegmentOffset=0x%06X", 3145 SegmentOffset) << "\n"); 3146 break; 3147 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 3148 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3149 true); 3150 if (error) { 3151 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " + 3152 Twine(error) + " for opcode at: 0x" + 3153 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3154 moveToEnd(); 3155 return; 3156 } 3157 AdvanceAmount = PointerSize; 3158 Skip = 0; 3159 Count = ImmValue; 3160 if (ImmValue != 0) 3161 RemainingLoopCount = ImmValue - 1; 3162 else 3163 RemainingLoopCount = 0; 3164 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3165 SegmentIndex, SegmentOffset); 3166 if (error) { 3167 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " + 3168 Twine(error) + " for opcode at: 0x" + 3169 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3170 moveToEnd(); 3171 return; 3172 } 3173 DEBUG_WITH_TYPE( 3174 "mach-o-rebase", 3175 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 3176 << format("SegmentOffset=0x%06X", SegmentOffset) 3177 << ", AdvanceAmount=" << AdvanceAmount 3178 << ", RemainingLoopCount=" << RemainingLoopCount 3179 << "\n"); 3180 return; 3181 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 3182 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3183 true); 3184 if (error) { 3185 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3186 Twine(error) + " for opcode at: 0x" + 3187 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3188 moveToEnd(); 3189 return; 3190 } 3191 AdvanceAmount = PointerSize; 3192 Skip = 0; 3193 Count = readULEB128(&error); 3194 if (error) { 3195 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3196 Twine(error) + " for opcode at: 0x" + 3197 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3198 moveToEnd(); 3199 return; 3200 } 3201 if (Count != 0) 3202 RemainingLoopCount = Count - 1; 3203 else 3204 RemainingLoopCount = 0; 3205 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3206 SegmentIndex, SegmentOffset); 3207 if (error) { 3208 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3209 Twine(error) + " for opcode at: 0x" + 3210 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3211 moveToEnd(); 3212 return; 3213 } 3214 DEBUG_WITH_TYPE( 3215 "mach-o-rebase", 3216 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 3217 << format("SegmentOffset=0x%06X", SegmentOffset) 3218 << ", AdvanceAmount=" << AdvanceAmount 3219 << ", RemainingLoopCount=" << RemainingLoopCount 3220 << "\n"); 3221 return; 3222 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 3223 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3224 true); 3225 if (error) { 3226 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3227 Twine(error) + " for opcode at: 0x" + 3228 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3229 moveToEnd(); 3230 return; 3231 } 3232 Skip = readULEB128(&error); 3233 if (error) { 3234 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3235 Twine(error) + " for opcode at: 0x" + 3236 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3237 moveToEnd(); 3238 return; 3239 } 3240 AdvanceAmount = Skip + PointerSize; 3241 Count = 1; 3242 RemainingLoopCount = 0; 3243 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3244 SegmentIndex, SegmentOffset); 3245 if (error) { 3246 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3247 Twine(error) + " for opcode at: 0x" + 3248 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3249 moveToEnd(); 3250 return; 3251 } 3252 DEBUG_WITH_TYPE( 3253 "mach-o-rebase", 3254 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 3255 << format("SegmentOffset=0x%06X", SegmentOffset) 3256 << ", AdvanceAmount=" << AdvanceAmount 3257 << ", RemainingLoopCount=" << RemainingLoopCount 3258 << "\n"); 3259 return; 3260 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 3261 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3262 true); 3263 if (error) { 3264 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3265 "ULEB " + 3266 Twine(error) + " for opcode at: 0x" + 3267 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3268 moveToEnd(); 3269 return; 3270 } 3271 Count = readULEB128(&error); 3272 if (error) { 3273 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3274 "ULEB " + 3275 Twine(error) + " for opcode at: 0x" + 3276 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3277 moveToEnd(); 3278 return; 3279 } 3280 if (Count != 0) 3281 RemainingLoopCount = Count - 1; 3282 else 3283 RemainingLoopCount = 0; 3284 Skip = readULEB128(&error); 3285 if (error) { 3286 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3287 "ULEB " + 3288 Twine(error) + " for opcode at: 0x" + 3289 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3290 moveToEnd(); 3291 return; 3292 } 3293 AdvanceAmount = Skip + PointerSize; 3294 3295 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3296 SegmentIndex, SegmentOffset); 3297 if (error) { 3298 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3299 "ULEB " + 3300 Twine(error) + " for opcode at: 0x" + 3301 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3302 moveToEnd(); 3303 return; 3304 } 3305 DEBUG_WITH_TYPE( 3306 "mach-o-rebase", 3307 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 3308 << format("SegmentOffset=0x%06X", SegmentOffset) 3309 << ", AdvanceAmount=" << AdvanceAmount 3310 << ", RemainingLoopCount=" << RemainingLoopCount 3311 << "\n"); 3312 return; 3313 default: 3314 *E = malformedError("bad rebase info (bad opcode value 0x" + 3315 Twine::utohexstr(Opcode) + " for opcode at: 0x" + 3316 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3317 moveToEnd(); 3318 return; 3319 } 3320 } 3321 } 3322 3323 uint64_t MachORebaseEntry::readULEB128(const char **error) { 3324 unsigned Count; 3325 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error); 3326 Ptr += Count; 3327 if (Ptr > Opcodes.end()) 3328 Ptr = Opcodes.end(); 3329 return Result; 3330 } 3331 3332 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 3333 3334 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 3335 3336 StringRef MachORebaseEntry::typeName() const { 3337 switch (RebaseType) { 3338 case MachO::REBASE_TYPE_POINTER: 3339 return "pointer"; 3340 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 3341 return "text abs32"; 3342 case MachO::REBASE_TYPE_TEXT_PCREL32: 3343 return "text rel32"; 3344 } 3345 return "unknown"; 3346 } 3347 3348 // For use with the SegIndex of a checked Mach-O Rebase entry 3349 // to get the segment name. 3350 StringRef MachORebaseEntry::segmentName() const { 3351 return O->BindRebaseSegmentName(SegmentIndex); 3352 } 3353 3354 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3355 // to get the section name. 3356 StringRef MachORebaseEntry::sectionName() const { 3357 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset); 3358 } 3359 3360 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3361 // to get the address. 3362 uint64_t MachORebaseEntry::address() const { 3363 return O->BindRebaseAddress(SegmentIndex, SegmentOffset); 3364 } 3365 3366 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 3367 #ifdef EXPENSIVE_CHECKS 3368 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 3369 #else 3370 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files"); 3371 #endif 3372 return (Ptr == Other.Ptr) && 3373 (RemainingLoopCount == Other.RemainingLoopCount) && 3374 (Done == Other.Done); 3375 } 3376 3377 iterator_range<rebase_iterator> 3378 MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O, 3379 ArrayRef<uint8_t> Opcodes, bool is64) { 3380 if (O->BindRebaseSectionTable == nullptr) 3381 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O); 3382 MachORebaseEntry Start(&Err, O, Opcodes, is64); 3383 Start.moveToFirst(); 3384 3385 MachORebaseEntry Finish(&Err, O, Opcodes, is64); 3386 Finish.moveToEnd(); 3387 3388 return make_range(rebase_iterator(Start), rebase_iterator(Finish)); 3389 } 3390 3391 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) { 3392 return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit()); 3393 } 3394 3395 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O, 3396 ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK) 3397 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), 3398 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {} 3399 3400 void MachOBindEntry::moveToFirst() { 3401 Ptr = Opcodes.begin(); 3402 moveNext(); 3403 } 3404 3405 void MachOBindEntry::moveToEnd() { 3406 Ptr = Opcodes.end(); 3407 RemainingLoopCount = 0; 3408 Done = true; 3409 } 3410 3411 void MachOBindEntry::moveNext() { 3412 ErrorAsOutParameter ErrAsOutParam(E); 3413 // If in the middle of some loop, move to next binding in loop. 3414 SegmentOffset += AdvanceAmount; 3415 if (RemainingLoopCount) { 3416 --RemainingLoopCount; 3417 return; 3418 } 3419 // BIND_OPCODE_DONE is only used for padding if we are not aligned to 3420 // pointer size. Therefore it is possible to reach the end without ever having 3421 // seen BIND_OPCODE_DONE. 3422 if (Ptr == Opcodes.end()) { 3423 Done = true; 3424 return; 3425 } 3426 bool More = true; 3427 while (More) { 3428 // Parse next opcode and set up next loop. 3429 const uint8_t *OpcodeStart = Ptr; 3430 uint8_t Byte = *Ptr++; 3431 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK; 3432 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK; 3433 int8_t SignExtended; 3434 const uint8_t *SymStart; 3435 uint32_t Count, Skip; 3436 const char *error = nullptr; 3437 switch (Opcode) { 3438 case MachO::BIND_OPCODE_DONE: 3439 if (TableKind == Kind::Lazy) { 3440 // Lazying bindings have a DONE opcode between entries. Need to ignore 3441 // it to advance to next entry. But need not if this is last entry. 3442 bool NotLastEntry = false; 3443 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) { 3444 if (*P) { 3445 NotLastEntry = true; 3446 } 3447 } 3448 if (NotLastEntry) 3449 break; 3450 } 3451 More = false; 3452 moveToEnd(); 3453 DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n"); 3454 break; 3455 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 3456 if (TableKind == Kind::Weak) { 3457 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in " 3458 "weak bind table for opcode at: 0x" + 3459 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3460 moveToEnd(); 3461 return; 3462 } 3463 Ordinal = ImmValue; 3464 LibraryOrdinalSet = true; 3465 if (ImmValue > O->getLibraryCount()) { 3466 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3467 "library ordinal: " + 3468 Twine((int)ImmValue) + " (max " + 3469 Twine((int)O->getLibraryCount()) + 3470 ") for opcode at: 0x" + 3471 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3472 moveToEnd(); 3473 return; 3474 } 3475 DEBUG_WITH_TYPE( 3476 "mach-o-bind", 3477 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 3478 << "Ordinal=" << Ordinal << "\n"); 3479 break; 3480 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 3481 if (TableKind == Kind::Weak) { 3482 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in " 3483 "weak bind table for opcode at: 0x" + 3484 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3485 moveToEnd(); 3486 return; 3487 } 3488 Ordinal = readULEB128(&error); 3489 LibraryOrdinalSet = true; 3490 if (error) { 3491 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " + 3492 Twine(error) + " for opcode at: 0x" + 3493 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3494 moveToEnd(); 3495 return; 3496 } 3497 if (Ordinal > (int)O->getLibraryCount()) { 3498 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3499 "library ordinal: " + 3500 Twine((int)Ordinal) + " (max " + 3501 Twine((int)O->getLibraryCount()) + 3502 ") for opcode at: 0x" + 3503 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3504 moveToEnd(); 3505 return; 3506 } 3507 DEBUG_WITH_TYPE( 3508 "mach-o-bind", 3509 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 3510 << "Ordinal=" << Ordinal << "\n"); 3511 break; 3512 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 3513 if (TableKind == Kind::Weak) { 3514 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in " 3515 "weak bind table for opcode at: 0x" + 3516 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3517 moveToEnd(); 3518 return; 3519 } 3520 if (ImmValue) { 3521 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue; 3522 Ordinal = SignExtended; 3523 if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) { 3524 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown " 3525 "special ordinal: " + 3526 Twine((int)Ordinal) + " for opcode at: 0x" + 3527 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3528 moveToEnd(); 3529 return; 3530 } 3531 } else 3532 Ordinal = 0; 3533 LibraryOrdinalSet = true; 3534 DEBUG_WITH_TYPE( 3535 "mach-o-bind", 3536 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 3537 << "Ordinal=" << Ordinal << "\n"); 3538 break; 3539 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 3540 Flags = ImmValue; 3541 SymStart = Ptr; 3542 while (*Ptr && (Ptr < Opcodes.end())) { 3543 ++Ptr; 3544 } 3545 if (Ptr == Opcodes.end()) { 3546 *E = malformedError( 3547 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM " 3548 "symbol name extends past opcodes for opcode at: 0x" + 3549 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3550 moveToEnd(); 3551 return; 3552 } 3553 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart), 3554 Ptr-SymStart); 3555 ++Ptr; 3556 DEBUG_WITH_TYPE( 3557 "mach-o-bind", 3558 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 3559 << "SymbolName=" << SymbolName << "\n"); 3560 if (TableKind == Kind::Weak) { 3561 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) 3562 return; 3563 } 3564 break; 3565 case MachO::BIND_OPCODE_SET_TYPE_IMM: 3566 BindType = ImmValue; 3567 if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) { 3568 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " + 3569 Twine((int)ImmValue) + " for opcode at: 0x" + 3570 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3571 moveToEnd(); 3572 return; 3573 } 3574 DEBUG_WITH_TYPE( 3575 "mach-o-bind", 3576 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: " 3577 << "BindType=" << (int)BindType << "\n"); 3578 break; 3579 case MachO::BIND_OPCODE_SET_ADDEND_SLEB: 3580 Addend = readSLEB128(&error); 3581 if (error) { 3582 *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) + 3583 " for opcode at: 0x" + 3584 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3585 moveToEnd(); 3586 return; 3587 } 3588 DEBUG_WITH_TYPE( 3589 "mach-o-bind", 3590 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: " 3591 << "Addend=" << Addend << "\n"); 3592 break; 3593 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 3594 SegmentIndex = ImmValue; 3595 SegmentOffset = readULEB128(&error); 3596 if (error) { 3597 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3598 Twine(error) + " for opcode at: 0x" + 3599 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3600 moveToEnd(); 3601 return; 3602 } 3603 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3604 if (error) { 3605 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3606 Twine(error) + " for opcode at: 0x" + 3607 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3608 moveToEnd(); 3609 return; 3610 } 3611 DEBUG_WITH_TYPE( 3612 "mach-o-bind", 3613 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3614 << "SegmentIndex=" << SegmentIndex << ", " 3615 << format("SegmentOffset=0x%06X", SegmentOffset) 3616 << "\n"); 3617 break; 3618 case MachO::BIND_OPCODE_ADD_ADDR_ULEB: 3619 SegmentOffset += readULEB128(&error); 3620 if (error) { 3621 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3622 " for opcode at: 0x" + 3623 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3624 moveToEnd(); 3625 return; 3626 } 3627 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3628 if (error) { 3629 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3630 " for opcode at: 0x" + 3631 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3632 moveToEnd(); 3633 return; 3634 } 3635 DEBUG_WITH_TYPE("mach-o-bind", 3636 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: " 3637 << format("SegmentOffset=0x%06X", 3638 SegmentOffset) << "\n"); 3639 break; 3640 case MachO::BIND_OPCODE_DO_BIND: 3641 AdvanceAmount = PointerSize; 3642 RemainingLoopCount = 0; 3643 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3644 if (error) { 3645 *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) + 3646 " for opcode at: 0x" + 3647 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3648 moveToEnd(); 3649 return; 3650 } 3651 if (SymbolName == StringRef()) { 3652 *E = malformedError( 3653 "for BIND_OPCODE_DO_BIND missing preceding " 3654 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" + 3655 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3656 moveToEnd(); 3657 return; 3658 } 3659 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3660 *E = 3661 malformedError("for BIND_OPCODE_DO_BIND missing preceding " 3662 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" + 3663 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3664 moveToEnd(); 3665 return; 3666 } 3667 DEBUG_WITH_TYPE("mach-o-bind", 3668 dbgs() << "BIND_OPCODE_DO_BIND: " 3669 << format("SegmentOffset=0x%06X", 3670 SegmentOffset) << "\n"); 3671 return; 3672 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 3673 if (TableKind == Kind::Lazy) { 3674 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in " 3675 "lazy bind table for opcode at: 0x" + 3676 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3677 moveToEnd(); 3678 return; 3679 } 3680 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3681 if (error) { 3682 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " + 3683 Twine(error) + " for opcode at: 0x" + 3684 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3685 moveToEnd(); 3686 return; 3687 } 3688 if (SymbolName == StringRef()) { 3689 *E = malformedError( 3690 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3691 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode " 3692 "at: 0x" + 3693 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3694 moveToEnd(); 3695 return; 3696 } 3697 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3698 *E = malformedError( 3699 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3700 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" + 3701 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3702 moveToEnd(); 3703 return; 3704 } 3705 AdvanceAmount = readULEB128(&error) + PointerSize; 3706 if (error) { 3707 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " + 3708 Twine(error) + " for opcode at: 0x" + 3709 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3710 moveToEnd(); 3711 return; 3712 } 3713 // Note, this is not really an error until the next bind but make no sense 3714 // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another 3715 // bind operation. 3716 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset + 3717 AdvanceAmount, false); 3718 if (error) { 3719 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding " 3720 "ULEB) " + 3721 Twine(error) + " for opcode at: 0x" + 3722 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3723 moveToEnd(); 3724 return; 3725 } 3726 RemainingLoopCount = 0; 3727 DEBUG_WITH_TYPE( 3728 "mach-o-bind", 3729 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 3730 << format("SegmentOffset=0x%06X", SegmentOffset) 3731 << ", AdvanceAmount=" << AdvanceAmount 3732 << ", RemainingLoopCount=" << RemainingLoopCount 3733 << "\n"); 3734 return; 3735 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 3736 if (TableKind == Kind::Lazy) { 3737 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not " 3738 "allowed in lazy bind table for opcode at: 0x" + 3739 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3740 moveToEnd(); 3741 return; 3742 } 3743 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3744 if (error) { 3745 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " + 3746 Twine(error) + " for opcode at: 0x" + 3747 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3748 moveToEnd(); 3749 return; 3750 } 3751 if (SymbolName == StringRef()) { 3752 *E = malformedError( 3753 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3754 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3755 "opcode at: 0x" + 3756 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3757 moveToEnd(); 3758 return; 3759 } 3760 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3761 *E = malformedError( 3762 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3763 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3764 "at: 0x" + 3765 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3766 moveToEnd(); 3767 return; 3768 } 3769 AdvanceAmount = ImmValue * PointerSize + PointerSize; 3770 RemainingLoopCount = 0; 3771 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset + 3772 AdvanceAmount, false); 3773 if (error) { 3774 *E = 3775 malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3776 " (after adding immediate times the pointer size) " + 3777 Twine(error) + " for opcode at: 0x" + 3778 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3779 moveToEnd(); 3780 return; 3781 } 3782 DEBUG_WITH_TYPE("mach-o-bind", 3783 dbgs() 3784 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 3785 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n"); 3786 return; 3787 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 3788 if (TableKind == Kind::Lazy) { 3789 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not " 3790 "allowed in lazy bind table for opcode at: 0x" + 3791 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3792 moveToEnd(); 3793 return; 3794 } 3795 Count = readULEB128(&error); 3796 if (Count != 0) 3797 RemainingLoopCount = Count - 1; 3798 else 3799 RemainingLoopCount = 0; 3800 if (error) { 3801 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3802 " (count value) " + 3803 Twine(error) + " for opcode at: 0x" + 3804 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3805 moveToEnd(); 3806 return; 3807 } 3808 Skip = readULEB128(&error); 3809 AdvanceAmount = Skip + PointerSize; 3810 if (error) { 3811 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3812 " (skip value) " + 3813 Twine(error) + " for opcode at: 0x" + 3814 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3815 moveToEnd(); 3816 return; 3817 } 3818 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3819 if (error) { 3820 *E = 3821 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " + 3822 Twine(error) + " for opcode at: 0x" + 3823 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3824 moveToEnd(); 3825 return; 3826 } 3827 if (SymbolName == StringRef()) { 3828 *E = malformedError( 3829 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3830 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3831 "opcode at: 0x" + 3832 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3833 moveToEnd(); 3834 return; 3835 } 3836 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3837 *E = malformedError( 3838 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3839 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3840 "at: 0x" + 3841 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3842 moveToEnd(); 3843 return; 3844 } 3845 error = O->BindEntryCheckCountAndSkip(Count, Skip, PointerSize, 3846 SegmentIndex, SegmentOffset); 3847 if (error) { 3848 *E = 3849 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " + 3850 Twine(error) + " for opcode at: 0x" + 3851 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3852 moveToEnd(); 3853 return; 3854 } 3855 DEBUG_WITH_TYPE( 3856 "mach-o-bind", 3857 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 3858 << format("SegmentOffset=0x%06X", SegmentOffset) 3859 << ", AdvanceAmount=" << AdvanceAmount 3860 << ", RemainingLoopCount=" << RemainingLoopCount 3861 << "\n"); 3862 return; 3863 default: 3864 *E = malformedError("bad bind info (bad opcode value 0x" + 3865 Twine::utohexstr(Opcode) + " for opcode at: 0x" + 3866 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3867 moveToEnd(); 3868 return; 3869 } 3870 } 3871 } 3872 3873 uint64_t MachOBindEntry::readULEB128(const char **error) { 3874 unsigned Count; 3875 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error); 3876 Ptr += Count; 3877 if (Ptr > Opcodes.end()) 3878 Ptr = Opcodes.end(); 3879 return Result; 3880 } 3881 3882 int64_t MachOBindEntry::readSLEB128(const char **error) { 3883 unsigned Count; 3884 int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error); 3885 Ptr += Count; 3886 if (Ptr > Opcodes.end()) 3887 Ptr = Opcodes.end(); 3888 return Result; 3889 } 3890 3891 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; } 3892 3893 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; } 3894 3895 StringRef MachOBindEntry::typeName() const { 3896 switch (BindType) { 3897 case MachO::BIND_TYPE_POINTER: 3898 return "pointer"; 3899 case MachO::BIND_TYPE_TEXT_ABSOLUTE32: 3900 return "text abs32"; 3901 case MachO::BIND_TYPE_TEXT_PCREL32: 3902 return "text rel32"; 3903 } 3904 return "unknown"; 3905 } 3906 3907 StringRef MachOBindEntry::symbolName() const { return SymbolName; } 3908 3909 int64_t MachOBindEntry::addend() const { return Addend; } 3910 3911 uint32_t MachOBindEntry::flags() const { return Flags; } 3912 3913 int MachOBindEntry::ordinal() const { return Ordinal; } 3914 3915 // For use with the SegIndex of a checked Mach-O Bind entry 3916 // to get the segment name. 3917 StringRef MachOBindEntry::segmentName() const { 3918 return O->BindRebaseSegmentName(SegmentIndex); 3919 } 3920 3921 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 3922 // to get the section name. 3923 StringRef MachOBindEntry::sectionName() const { 3924 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset); 3925 } 3926 3927 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 3928 // to get the address. 3929 uint64_t MachOBindEntry::address() const { 3930 return O->BindRebaseAddress(SegmentIndex, SegmentOffset); 3931 } 3932 3933 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const { 3934 #ifdef EXPENSIVE_CHECKS 3935 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 3936 #else 3937 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files"); 3938 #endif 3939 return (Ptr == Other.Ptr) && 3940 (RemainingLoopCount == Other.RemainingLoopCount) && 3941 (Done == Other.Done); 3942 } 3943 3944 // Build table of sections so SegIndex/SegOffset pairs can be translated. 3945 BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) { 3946 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0; 3947 StringRef CurSegName; 3948 uint64_t CurSegAddress; 3949 for (const SectionRef &Section : Obj->sections()) { 3950 SectionInfo Info; 3951 Section.getName(Info.SectionName); 3952 Info.Address = Section.getAddress(); 3953 Info.Size = Section.getSize(); 3954 Info.SegmentName = 3955 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl()); 3956 if (!Info.SegmentName.equals(CurSegName)) { 3957 ++CurSegIndex; 3958 CurSegName = Info.SegmentName; 3959 CurSegAddress = Info.Address; 3960 } 3961 Info.SegmentIndex = CurSegIndex - 1; 3962 Info.OffsetInSegment = Info.Address - CurSegAddress; 3963 Info.SegmentStartAddress = CurSegAddress; 3964 Sections.push_back(Info); 3965 } 3966 MaxSegIndex = CurSegIndex; 3967 } 3968 3969 // For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to 3970 // validate a MachOBindEntry or MachORebaseEntry. 3971 const char * BindRebaseSegInfo::checkSegAndOffset(int32_t SegIndex, 3972 uint64_t SegOffset, 3973 bool endInvalid) { 3974 if (SegIndex == -1) 3975 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB"; 3976 if (SegIndex >= MaxSegIndex) 3977 return "bad segIndex (too large)"; 3978 for (const SectionInfo &SI : Sections) { 3979 if (SI.SegmentIndex != SegIndex) 3980 continue; 3981 if (SI.OffsetInSegment > SegOffset) 3982 continue; 3983 if (SegOffset > (SI.OffsetInSegment + SI.Size)) 3984 continue; 3985 if (endInvalid && SegOffset >= (SI.OffsetInSegment + SI.Size)) 3986 continue; 3987 return nullptr; 3988 } 3989 return "bad segOffset, too large"; 3990 } 3991 3992 // For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for 3993 // the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode and for use in 3994 // MachORebaseEntry::moveNext() to validate a MachORebaseEntry for 3995 // REBASE_OPCODE_DO_*_TIMES* opcodes. The SegIndex and SegOffset must have 3996 // been already checked. 3997 const char * BindRebaseSegInfo::checkCountAndSkip(uint32_t Count, uint32_t Skip, 3998 uint8_t PointerSize, 3999 int32_t SegIndex, 4000 uint64_t SegOffset) { 4001 const SectionInfo &SI = findSection(SegIndex, SegOffset); 4002 uint64_t addr = SI.SegmentStartAddress + SegOffset; 4003 if (addr >= SI.Address + SI.Size) 4004 return "bad segOffset, too large"; 4005 uint64_t i = 0; 4006 if (Count > 1) 4007 i = (Skip + PointerSize) * (Count - 1); 4008 else if (Count == 1) 4009 i = Skip + PointerSize; 4010 if (addr + i >= SI.Address + SI.Size) { 4011 // For rebase opcodes they can step from one section to another. 4012 uint64_t TrailingSegOffset = (addr + i) - SI.SegmentStartAddress; 4013 const char *error = checkSegAndOffset(SegIndex, TrailingSegOffset, false); 4014 if (error) 4015 return "bad count and skip, too large"; 4016 } 4017 return nullptr; 4018 } 4019 4020 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry 4021 // to get the segment name. 4022 StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) { 4023 for (const SectionInfo &SI : Sections) { 4024 if (SI.SegmentIndex == SegIndex) 4025 return SI.SegmentName; 4026 } 4027 llvm_unreachable("invalid SegIndex"); 4028 } 4029 4030 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4031 // to get the SectionInfo. 4032 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection( 4033 int32_t SegIndex, uint64_t SegOffset) { 4034 for (const SectionInfo &SI : Sections) { 4035 if (SI.SegmentIndex != SegIndex) 4036 continue; 4037 if (SI.OffsetInSegment > SegOffset) 4038 continue; 4039 if (SegOffset >= (SI.OffsetInSegment + SI.Size)) 4040 continue; 4041 return SI; 4042 } 4043 llvm_unreachable("SegIndex and SegOffset not in any section"); 4044 } 4045 4046 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4047 // entry to get the section name. 4048 StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex, 4049 uint64_t SegOffset) { 4050 return findSection(SegIndex, SegOffset).SectionName; 4051 } 4052 4053 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4054 // entry to get the address. 4055 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) { 4056 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg); 4057 return SI.SegmentStartAddress + OffsetInSeg; 4058 } 4059 4060 iterator_range<bind_iterator> 4061 MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O, 4062 ArrayRef<uint8_t> Opcodes, bool is64, 4063 MachOBindEntry::Kind BKind) { 4064 if (O->BindRebaseSectionTable == nullptr) 4065 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O); 4066 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind); 4067 Start.moveToFirst(); 4068 4069 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind); 4070 Finish.moveToEnd(); 4071 4072 return make_range(bind_iterator(Start), bind_iterator(Finish)); 4073 } 4074 4075 iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) { 4076 return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(), 4077 MachOBindEntry::Kind::Regular); 4078 } 4079 4080 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) { 4081 return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(), 4082 MachOBindEntry::Kind::Lazy); 4083 } 4084 4085 iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) { 4086 return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(), 4087 MachOBindEntry::Kind::Weak); 4088 } 4089 4090 MachOObjectFile::load_command_iterator 4091 MachOObjectFile::begin_load_commands() const { 4092 return LoadCommands.begin(); 4093 } 4094 4095 MachOObjectFile::load_command_iterator 4096 MachOObjectFile::end_load_commands() const { 4097 return LoadCommands.end(); 4098 } 4099 4100 iterator_range<MachOObjectFile::load_command_iterator> 4101 MachOObjectFile::load_commands() const { 4102 return make_range(begin_load_commands(), end_load_commands()); 4103 } 4104 4105 StringRef 4106 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 4107 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 4108 return parseSegmentOrSectionName(Raw.data()); 4109 } 4110 4111 ArrayRef<char> 4112 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 4113 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 4114 const section_base *Base = 4115 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 4116 return makeArrayRef(Base->sectname); 4117 } 4118 4119 ArrayRef<char> 4120 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 4121 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 4122 const section_base *Base = 4123 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 4124 return makeArrayRef(Base->segname); 4125 } 4126 4127 bool 4128 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 4129 const { 4130 if (getCPUType(*this) == MachO::CPU_TYPE_X86_64) 4131 return false; 4132 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 4133 } 4134 4135 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 4136 const MachO::any_relocation_info &RE) const { 4137 if (isLittleEndian()) 4138 return RE.r_word1 & 0xffffff; 4139 return RE.r_word1 >> 8; 4140 } 4141 4142 bool MachOObjectFile::getPlainRelocationExternal( 4143 const MachO::any_relocation_info &RE) const { 4144 if (isLittleEndian()) 4145 return (RE.r_word1 >> 27) & 1; 4146 return (RE.r_word1 >> 4) & 1; 4147 } 4148 4149 bool MachOObjectFile::getScatteredRelocationScattered( 4150 const MachO::any_relocation_info &RE) const { 4151 return RE.r_word0 >> 31; 4152 } 4153 4154 uint32_t MachOObjectFile::getScatteredRelocationValue( 4155 const MachO::any_relocation_info &RE) const { 4156 return RE.r_word1; 4157 } 4158 4159 uint32_t MachOObjectFile::getScatteredRelocationType( 4160 const MachO::any_relocation_info &RE) const { 4161 return (RE.r_word0 >> 24) & 0xf; 4162 } 4163 4164 unsigned MachOObjectFile::getAnyRelocationAddress( 4165 const MachO::any_relocation_info &RE) const { 4166 if (isRelocationScattered(RE)) 4167 return getScatteredRelocationAddress(RE); 4168 return getPlainRelocationAddress(RE); 4169 } 4170 4171 unsigned MachOObjectFile::getAnyRelocationPCRel( 4172 const MachO::any_relocation_info &RE) const { 4173 if (isRelocationScattered(RE)) 4174 return getScatteredRelocationPCRel(RE); 4175 return getPlainRelocationPCRel(*this, RE); 4176 } 4177 4178 unsigned MachOObjectFile::getAnyRelocationLength( 4179 const MachO::any_relocation_info &RE) const { 4180 if (isRelocationScattered(RE)) 4181 return getScatteredRelocationLength(RE); 4182 return getPlainRelocationLength(*this, RE); 4183 } 4184 4185 unsigned 4186 MachOObjectFile::getAnyRelocationType( 4187 const MachO::any_relocation_info &RE) const { 4188 if (isRelocationScattered(RE)) 4189 return getScatteredRelocationType(RE); 4190 return getPlainRelocationType(*this, RE); 4191 } 4192 4193 SectionRef 4194 MachOObjectFile::getAnyRelocationSection( 4195 const MachO::any_relocation_info &RE) const { 4196 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 4197 return *section_end(); 4198 unsigned SecNum = getPlainRelocationSymbolNum(RE); 4199 if (SecNum == MachO::R_ABS || SecNum > Sections.size()) 4200 return *section_end(); 4201 DataRefImpl DRI; 4202 DRI.d.a = SecNum - 1; 4203 return SectionRef(DRI, this); 4204 } 4205 4206 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 4207 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 4208 return getStruct<MachO::section>(*this, Sections[DRI.d.a]); 4209 } 4210 4211 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 4212 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 4213 return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]); 4214 } 4215 4216 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 4217 unsigned Index) const { 4218 const char *Sec = getSectionPtr(*this, L, Index); 4219 return getStruct<MachO::section>(*this, Sec); 4220 } 4221 4222 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 4223 unsigned Index) const { 4224 const char *Sec = getSectionPtr(*this, L, Index); 4225 return getStruct<MachO::section_64>(*this, Sec); 4226 } 4227 4228 MachO::nlist 4229 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 4230 const char *P = reinterpret_cast<const char *>(DRI.p); 4231 return getStruct<MachO::nlist>(*this, P); 4232 } 4233 4234 MachO::nlist_64 4235 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 4236 const char *P = reinterpret_cast<const char *>(DRI.p); 4237 return getStruct<MachO::nlist_64>(*this, P); 4238 } 4239 4240 MachO::linkedit_data_command 4241 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 4242 return getStruct<MachO::linkedit_data_command>(*this, L.Ptr); 4243 } 4244 4245 MachO::segment_command 4246 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 4247 return getStruct<MachO::segment_command>(*this, L.Ptr); 4248 } 4249 4250 MachO::segment_command_64 4251 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 4252 return getStruct<MachO::segment_command_64>(*this, L.Ptr); 4253 } 4254 4255 MachO::linker_option_command 4256 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const { 4257 return getStruct<MachO::linker_option_command>(*this, L.Ptr); 4258 } 4259 4260 MachO::version_min_command 4261 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 4262 return getStruct<MachO::version_min_command>(*this, L.Ptr); 4263 } 4264 4265 MachO::note_command 4266 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const { 4267 return getStruct<MachO::note_command>(*this, L.Ptr); 4268 } 4269 4270 MachO::build_version_command 4271 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const { 4272 return getStruct<MachO::build_version_command>(*this, L.Ptr); 4273 } 4274 4275 MachO::build_tool_version 4276 MachOObjectFile::getBuildToolVersion(unsigned index) const { 4277 return getStruct<MachO::build_tool_version>(*this, BuildTools[index]); 4278 } 4279 4280 MachO::dylib_command 4281 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 4282 return getStruct<MachO::dylib_command>(*this, L.Ptr); 4283 } 4284 4285 MachO::dyld_info_command 4286 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const { 4287 return getStruct<MachO::dyld_info_command>(*this, L.Ptr); 4288 } 4289 4290 MachO::dylinker_command 4291 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const { 4292 return getStruct<MachO::dylinker_command>(*this, L.Ptr); 4293 } 4294 4295 MachO::uuid_command 4296 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const { 4297 return getStruct<MachO::uuid_command>(*this, L.Ptr); 4298 } 4299 4300 MachO::rpath_command 4301 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const { 4302 return getStruct<MachO::rpath_command>(*this, L.Ptr); 4303 } 4304 4305 MachO::source_version_command 4306 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const { 4307 return getStruct<MachO::source_version_command>(*this, L.Ptr); 4308 } 4309 4310 MachO::entry_point_command 4311 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const { 4312 return getStruct<MachO::entry_point_command>(*this, L.Ptr); 4313 } 4314 4315 MachO::encryption_info_command 4316 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const { 4317 return getStruct<MachO::encryption_info_command>(*this, L.Ptr); 4318 } 4319 4320 MachO::encryption_info_command_64 4321 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const { 4322 return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr); 4323 } 4324 4325 MachO::sub_framework_command 4326 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const { 4327 return getStruct<MachO::sub_framework_command>(*this, L.Ptr); 4328 } 4329 4330 MachO::sub_umbrella_command 4331 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const { 4332 return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr); 4333 } 4334 4335 MachO::sub_library_command 4336 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const { 4337 return getStruct<MachO::sub_library_command>(*this, L.Ptr); 4338 } 4339 4340 MachO::sub_client_command 4341 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const { 4342 return getStruct<MachO::sub_client_command>(*this, L.Ptr); 4343 } 4344 4345 MachO::routines_command 4346 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const { 4347 return getStruct<MachO::routines_command>(*this, L.Ptr); 4348 } 4349 4350 MachO::routines_command_64 4351 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const { 4352 return getStruct<MachO::routines_command_64>(*this, L.Ptr); 4353 } 4354 4355 MachO::thread_command 4356 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { 4357 return getStruct<MachO::thread_command>(*this, L.Ptr); 4358 } 4359 4360 MachO::any_relocation_info 4361 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 4362 uint32_t Offset; 4363 if (getHeader().filetype == MachO::MH_OBJECT) { 4364 DataRefImpl Sec; 4365 Sec.d.a = Rel.d.a; 4366 if (is64Bit()) { 4367 MachO::section_64 Sect = getSection64(Sec); 4368 Offset = Sect.reloff; 4369 } else { 4370 MachO::section Sect = getSection(Sec); 4371 Offset = Sect.reloff; 4372 } 4373 } else { 4374 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 4375 if (Rel.d.a == 0) 4376 Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations 4377 else 4378 Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations 4379 } 4380 4381 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 4382 getPtr(*this, Offset)) + Rel.d.b; 4383 return getStruct<MachO::any_relocation_info>( 4384 *this, reinterpret_cast<const char *>(P)); 4385 } 4386 4387 MachO::data_in_code_entry 4388 MachOObjectFile::getDice(DataRefImpl Rel) const { 4389 const char *P = reinterpret_cast<const char *>(Rel.p); 4390 return getStruct<MachO::data_in_code_entry>(*this, P); 4391 } 4392 4393 const MachO::mach_header &MachOObjectFile::getHeader() const { 4394 return Header; 4395 } 4396 4397 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const { 4398 assert(is64Bit()); 4399 return Header64; 4400 } 4401 4402 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 4403 const MachO::dysymtab_command &DLC, 4404 unsigned Index) const { 4405 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 4406 return getStruct<uint32_t>(*this, getPtr(*this, Offset)); 4407 } 4408 4409 MachO::data_in_code_entry 4410 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 4411 unsigned Index) const { 4412 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 4413 return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset)); 4414 } 4415 4416 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 4417 if (SymtabLoadCmd) 4418 return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd); 4419 4420 // If there is no SymtabLoadCmd return a load command with zero'ed fields. 4421 MachO::symtab_command Cmd; 4422 Cmd.cmd = MachO::LC_SYMTAB; 4423 Cmd.cmdsize = sizeof(MachO::symtab_command); 4424 Cmd.symoff = 0; 4425 Cmd.nsyms = 0; 4426 Cmd.stroff = 0; 4427 Cmd.strsize = 0; 4428 return Cmd; 4429 } 4430 4431 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 4432 if (DysymtabLoadCmd) 4433 return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd); 4434 4435 // If there is no DysymtabLoadCmd return a load command with zero'ed fields. 4436 MachO::dysymtab_command Cmd; 4437 Cmd.cmd = MachO::LC_DYSYMTAB; 4438 Cmd.cmdsize = sizeof(MachO::dysymtab_command); 4439 Cmd.ilocalsym = 0; 4440 Cmd.nlocalsym = 0; 4441 Cmd.iextdefsym = 0; 4442 Cmd.nextdefsym = 0; 4443 Cmd.iundefsym = 0; 4444 Cmd.nundefsym = 0; 4445 Cmd.tocoff = 0; 4446 Cmd.ntoc = 0; 4447 Cmd.modtaboff = 0; 4448 Cmd.nmodtab = 0; 4449 Cmd.extrefsymoff = 0; 4450 Cmd.nextrefsyms = 0; 4451 Cmd.indirectsymoff = 0; 4452 Cmd.nindirectsyms = 0; 4453 Cmd.extreloff = 0; 4454 Cmd.nextrel = 0; 4455 Cmd.locreloff = 0; 4456 Cmd.nlocrel = 0; 4457 return Cmd; 4458 } 4459 4460 MachO::linkedit_data_command 4461 MachOObjectFile::getDataInCodeLoadCommand() const { 4462 if (DataInCodeLoadCmd) 4463 return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd); 4464 4465 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 4466 MachO::linkedit_data_command Cmd; 4467 Cmd.cmd = MachO::LC_DATA_IN_CODE; 4468 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 4469 Cmd.dataoff = 0; 4470 Cmd.datasize = 0; 4471 return Cmd; 4472 } 4473 4474 MachO::linkedit_data_command 4475 MachOObjectFile::getLinkOptHintsLoadCommand() const { 4476 if (LinkOptHintsLoadCmd) 4477 return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd); 4478 4479 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed 4480 // fields. 4481 MachO::linkedit_data_command Cmd; 4482 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; 4483 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 4484 Cmd.dataoff = 0; 4485 Cmd.datasize = 0; 4486 return Cmd; 4487 } 4488 4489 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { 4490 if (!DyldInfoLoadCmd) 4491 return None; 4492 4493 MachO::dyld_info_command DyldInfo = 4494 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4495 const uint8_t *Ptr = 4496 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off)); 4497 return makeArrayRef(Ptr, DyldInfo.rebase_size); 4498 } 4499 4500 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 4501 if (!DyldInfoLoadCmd) 4502 return None; 4503 4504 MachO::dyld_info_command DyldInfo = 4505 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4506 const uint8_t *Ptr = 4507 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off)); 4508 return makeArrayRef(Ptr, DyldInfo.bind_size); 4509 } 4510 4511 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 4512 if (!DyldInfoLoadCmd) 4513 return None; 4514 4515 MachO::dyld_info_command DyldInfo = 4516 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4517 const uint8_t *Ptr = 4518 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off)); 4519 return makeArrayRef(Ptr, DyldInfo.weak_bind_size); 4520 } 4521 4522 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 4523 if (!DyldInfoLoadCmd) 4524 return None; 4525 4526 MachO::dyld_info_command DyldInfo = 4527 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4528 const uint8_t *Ptr = 4529 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off)); 4530 return makeArrayRef(Ptr, DyldInfo.lazy_bind_size); 4531 } 4532 4533 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 4534 if (!DyldInfoLoadCmd) 4535 return None; 4536 4537 MachO::dyld_info_command DyldInfo = 4538 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4539 const uint8_t *Ptr = 4540 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off)); 4541 return makeArrayRef(Ptr, DyldInfo.export_size); 4542 } 4543 4544 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 4545 if (!UuidLoadCmd) 4546 return None; 4547 // Returning a pointer is fine as uuid doesn't need endian swapping. 4548 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); 4549 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16); 4550 } 4551 4552 StringRef MachOObjectFile::getStringTableData() const { 4553 MachO::symtab_command S = getSymtabLoadCommand(); 4554 return getData().substr(S.stroff, S.strsize); 4555 } 4556 4557 bool MachOObjectFile::is64Bit() const { 4558 return getType() == getMachOType(false, true) || 4559 getType() == getMachOType(true, true); 4560 } 4561 4562 void MachOObjectFile::ReadULEB128s(uint64_t Index, 4563 SmallVectorImpl<uint64_t> &Out) const { 4564 DataExtractor extractor(ObjectFile::getData(), true, 0); 4565 4566 uint32_t offset = Index; 4567 uint64_t data = 0; 4568 while (uint64_t delta = extractor.getULEB128(&offset)) { 4569 data += delta; 4570 Out.push_back(data); 4571 } 4572 } 4573 4574 bool MachOObjectFile::isRelocatableObject() const { 4575 return getHeader().filetype == MachO::MH_OBJECT; 4576 } 4577 4578 Expected<std::unique_ptr<MachOObjectFile>> 4579 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer, 4580 uint32_t UniversalCputype, 4581 uint32_t UniversalIndex) { 4582 StringRef Magic = Buffer.getBuffer().slice(0, 4); 4583 if (Magic == "\xFE\xED\xFA\xCE") 4584 return MachOObjectFile::create(Buffer, false, false, 4585 UniversalCputype, UniversalIndex); 4586 if (Magic == "\xCE\xFA\xED\xFE") 4587 return MachOObjectFile::create(Buffer, true, false, 4588 UniversalCputype, UniversalIndex); 4589 if (Magic == "\xFE\xED\xFA\xCF") 4590 return MachOObjectFile::create(Buffer, false, true, 4591 UniversalCputype, UniversalIndex); 4592 if (Magic == "\xCF\xFA\xED\xFE") 4593 return MachOObjectFile::create(Buffer, true, true, 4594 UniversalCputype, UniversalIndex); 4595 return make_error<GenericBinaryError>("Unrecognized MachO magic number", 4596 object_error::invalid_file_type); 4597 } 4598 4599 StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const { 4600 return StringSwitch<StringRef>(Name) 4601 .Case("debug_str_offs", "debug_str_offsets") 4602 .Default(Name); 4603 } 4604