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().data() + Offset; 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 uint32_t Flags = getSectionFlags(*this, Sec); 1972 unsigned SectionType = Flags & MachO::SECTION_TYPE; 1973 return SectionType == MachO::S_ZEROFILL || 1974 SectionType == MachO::S_GB_ZEROFILL; 1975 } 1976 1977 bool MachOObjectFile::isSectionBitcode(DataRefImpl Sec) const { 1978 StringRef SegmentName = getSectionFinalSegmentName(Sec); 1979 StringRef SectName; 1980 if (!getSectionName(Sec, SectName)) 1981 return (SegmentName == "__LLVM" && SectName == "__bitcode"); 1982 return false; 1983 } 1984 1985 bool MachOObjectFile::isSectionStripped(DataRefImpl Sec) const { 1986 if (is64Bit()) 1987 return getSection64(Sec).offset == 0; 1988 return getSection(Sec).offset == 0; 1989 } 1990 1991 relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { 1992 DataRefImpl Ret; 1993 Ret.d.a = Sec.d.a; 1994 Ret.d.b = 0; 1995 return relocation_iterator(RelocationRef(Ret, this)); 1996 } 1997 1998 relocation_iterator 1999 MachOObjectFile::section_rel_end(DataRefImpl Sec) const { 2000 uint32_t Num; 2001 if (is64Bit()) { 2002 MachO::section_64 Sect = getSection64(Sec); 2003 Num = Sect.nreloc; 2004 } else { 2005 MachO::section Sect = getSection(Sec); 2006 Num = Sect.nreloc; 2007 } 2008 2009 DataRefImpl Ret; 2010 Ret.d.a = Sec.d.a; 2011 Ret.d.b = Num; 2012 return relocation_iterator(RelocationRef(Ret, this)); 2013 } 2014 2015 relocation_iterator MachOObjectFile::extrel_begin() const { 2016 DataRefImpl Ret; 2017 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2018 Ret.d.a = 0; // Would normally be a section index. 2019 Ret.d.b = 0; // Index into the external relocations 2020 return relocation_iterator(RelocationRef(Ret, this)); 2021 } 2022 2023 relocation_iterator MachOObjectFile::extrel_end() const { 2024 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 2025 DataRefImpl Ret; 2026 // for DYSYMTAB symbols, Ret.d.a == 0 for external relocations 2027 Ret.d.a = 0; // Would normally be a section index. 2028 Ret.d.b = DysymtabLoadCmd.nextrel; // Index into the external relocations 2029 return relocation_iterator(RelocationRef(Ret, this)); 2030 } 2031 2032 relocation_iterator MachOObjectFile::locrel_begin() const { 2033 DataRefImpl Ret; 2034 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2035 Ret.d.a = 1; // Would normally be a section index. 2036 Ret.d.b = 0; // Index into the local relocations 2037 return relocation_iterator(RelocationRef(Ret, this)); 2038 } 2039 2040 relocation_iterator MachOObjectFile::locrel_end() const { 2041 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 2042 DataRefImpl Ret; 2043 // for DYSYMTAB symbols, Ret.d.a == 1 for local relocations 2044 Ret.d.a = 1; // Would normally be a section index. 2045 Ret.d.b = DysymtabLoadCmd.nlocrel; // Index into the local relocations 2046 return relocation_iterator(RelocationRef(Ret, this)); 2047 } 2048 2049 void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 2050 ++Rel.d.b; 2051 } 2052 2053 uint64_t MachOObjectFile::getRelocationOffset(DataRefImpl Rel) const { 2054 assert((getHeader().filetype == MachO::MH_OBJECT || 2055 getHeader().filetype == MachO::MH_KEXT_BUNDLE) && 2056 "Only implemented for MH_OBJECT && MH_KEXT_BUNDLE"); 2057 MachO::any_relocation_info RE = getRelocation(Rel); 2058 return getAnyRelocationAddress(RE); 2059 } 2060 2061 symbol_iterator 2062 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 2063 MachO::any_relocation_info RE = getRelocation(Rel); 2064 if (isRelocationScattered(RE)) 2065 return symbol_end(); 2066 2067 uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); 2068 bool isExtern = getPlainRelocationExternal(RE); 2069 if (!isExtern) 2070 return symbol_end(); 2071 2072 MachO::symtab_command S = getSymtabLoadCommand(); 2073 unsigned SymbolTableEntrySize = is64Bit() ? 2074 sizeof(MachO::nlist_64) : 2075 sizeof(MachO::nlist); 2076 uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; 2077 DataRefImpl Sym; 2078 Sym.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2079 return symbol_iterator(SymbolRef(Sym, this)); 2080 } 2081 2082 section_iterator 2083 MachOObjectFile::getRelocationSection(DataRefImpl Rel) const { 2084 return section_iterator(getAnyRelocationSection(getRelocation(Rel))); 2085 } 2086 2087 uint64_t MachOObjectFile::getRelocationType(DataRefImpl Rel) const { 2088 MachO::any_relocation_info RE = getRelocation(Rel); 2089 return getAnyRelocationType(RE); 2090 } 2091 2092 void MachOObjectFile::getRelocationTypeName( 2093 DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 2094 StringRef res; 2095 uint64_t RType = getRelocationType(Rel); 2096 2097 unsigned Arch = this->getArch(); 2098 2099 switch (Arch) { 2100 case Triple::x86: { 2101 static const char *const Table[] = { 2102 "GENERIC_RELOC_VANILLA", 2103 "GENERIC_RELOC_PAIR", 2104 "GENERIC_RELOC_SECTDIFF", 2105 "GENERIC_RELOC_PB_LA_PTR", 2106 "GENERIC_RELOC_LOCAL_SECTDIFF", 2107 "GENERIC_RELOC_TLV" }; 2108 2109 if (RType > 5) 2110 res = "Unknown"; 2111 else 2112 res = Table[RType]; 2113 break; 2114 } 2115 case Triple::x86_64: { 2116 static const char *const Table[] = { 2117 "X86_64_RELOC_UNSIGNED", 2118 "X86_64_RELOC_SIGNED", 2119 "X86_64_RELOC_BRANCH", 2120 "X86_64_RELOC_GOT_LOAD", 2121 "X86_64_RELOC_GOT", 2122 "X86_64_RELOC_SUBTRACTOR", 2123 "X86_64_RELOC_SIGNED_1", 2124 "X86_64_RELOC_SIGNED_2", 2125 "X86_64_RELOC_SIGNED_4", 2126 "X86_64_RELOC_TLV" }; 2127 2128 if (RType > 9) 2129 res = "Unknown"; 2130 else 2131 res = Table[RType]; 2132 break; 2133 } 2134 case Triple::arm: { 2135 static const char *const Table[] = { 2136 "ARM_RELOC_VANILLA", 2137 "ARM_RELOC_PAIR", 2138 "ARM_RELOC_SECTDIFF", 2139 "ARM_RELOC_LOCAL_SECTDIFF", 2140 "ARM_RELOC_PB_LA_PTR", 2141 "ARM_RELOC_BR24", 2142 "ARM_THUMB_RELOC_BR22", 2143 "ARM_THUMB_32BIT_BRANCH", 2144 "ARM_RELOC_HALF", 2145 "ARM_RELOC_HALF_SECTDIFF" }; 2146 2147 if (RType > 9) 2148 res = "Unknown"; 2149 else 2150 res = Table[RType]; 2151 break; 2152 } 2153 case Triple::aarch64: { 2154 static const char *const Table[] = { 2155 "ARM64_RELOC_UNSIGNED", "ARM64_RELOC_SUBTRACTOR", 2156 "ARM64_RELOC_BRANCH26", "ARM64_RELOC_PAGE21", 2157 "ARM64_RELOC_PAGEOFF12", "ARM64_RELOC_GOT_LOAD_PAGE21", 2158 "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT", 2159 "ARM64_RELOC_TLVP_LOAD_PAGE21", "ARM64_RELOC_TLVP_LOAD_PAGEOFF12", 2160 "ARM64_RELOC_ADDEND" 2161 }; 2162 2163 if (RType >= array_lengthof(Table)) 2164 res = "Unknown"; 2165 else 2166 res = Table[RType]; 2167 break; 2168 } 2169 case Triple::ppc: { 2170 static const char *const Table[] = { 2171 "PPC_RELOC_VANILLA", 2172 "PPC_RELOC_PAIR", 2173 "PPC_RELOC_BR14", 2174 "PPC_RELOC_BR24", 2175 "PPC_RELOC_HI16", 2176 "PPC_RELOC_LO16", 2177 "PPC_RELOC_HA16", 2178 "PPC_RELOC_LO14", 2179 "PPC_RELOC_SECTDIFF", 2180 "PPC_RELOC_PB_LA_PTR", 2181 "PPC_RELOC_HI16_SECTDIFF", 2182 "PPC_RELOC_LO16_SECTDIFF", 2183 "PPC_RELOC_HA16_SECTDIFF", 2184 "PPC_RELOC_JBSR", 2185 "PPC_RELOC_LO14_SECTDIFF", 2186 "PPC_RELOC_LOCAL_SECTDIFF" }; 2187 2188 if (RType > 15) 2189 res = "Unknown"; 2190 else 2191 res = Table[RType]; 2192 break; 2193 } 2194 case Triple::UnknownArch: 2195 res = "Unknown"; 2196 break; 2197 } 2198 Result.append(res.begin(), res.end()); 2199 } 2200 2201 uint8_t MachOObjectFile::getRelocationLength(DataRefImpl Rel) const { 2202 MachO::any_relocation_info RE = getRelocation(Rel); 2203 return getAnyRelocationLength(RE); 2204 } 2205 2206 // 2207 // guessLibraryShortName() is passed a name of a dynamic library and returns a 2208 // guess on what the short name is. Then name is returned as a substring of the 2209 // StringRef Name passed in. The name of the dynamic library is recognized as 2210 // a framework if it has one of the two following forms: 2211 // Foo.framework/Versions/A/Foo 2212 // Foo.framework/Foo 2213 // Where A and Foo can be any string. And may contain a trailing suffix 2214 // starting with an underbar. If the Name is recognized as a framework then 2215 // isFramework is set to true else it is set to false. If the Name has a 2216 // suffix then Suffix is set to the substring in Name that contains the suffix 2217 // else it is set to a NULL StringRef. 2218 // 2219 // The Name of the dynamic library is recognized as a library name if it has 2220 // one of the two following forms: 2221 // libFoo.A.dylib 2222 // libFoo.dylib 2223 // The library may have a suffix trailing the name Foo of the form: 2224 // libFoo_profile.A.dylib 2225 // libFoo_profile.dylib 2226 // 2227 // The Name of the dynamic library is also recognized as a library name if it 2228 // has the following form: 2229 // Foo.qtx 2230 // 2231 // If the Name of the dynamic library is none of the forms above then a NULL 2232 // StringRef is returned. 2233 // 2234 StringRef MachOObjectFile::guessLibraryShortName(StringRef Name, 2235 bool &isFramework, 2236 StringRef &Suffix) { 2237 StringRef Foo, F, DotFramework, V, Dylib, Lib, Dot, Qtx; 2238 size_t a, b, c, d, Idx; 2239 2240 isFramework = false; 2241 Suffix = StringRef(); 2242 2243 // Pull off the last component and make Foo point to it 2244 a = Name.rfind('/'); 2245 if (a == Name.npos || a == 0) 2246 goto guess_library; 2247 Foo = Name.slice(a+1, Name.npos); 2248 2249 // Look for a suffix starting with a '_' 2250 Idx = Foo.rfind('_'); 2251 if (Idx != Foo.npos && Foo.size() >= 2) { 2252 Suffix = Foo.slice(Idx, Foo.npos); 2253 Foo = Foo.slice(0, Idx); 2254 } 2255 2256 // First look for the form Foo.framework/Foo 2257 b = Name.rfind('/', a); 2258 if (b == Name.npos) 2259 Idx = 0; 2260 else 2261 Idx = b+1; 2262 F = Name.slice(Idx, Idx + Foo.size()); 2263 DotFramework = Name.slice(Idx + Foo.size(), 2264 Idx + Foo.size() + sizeof(".framework/")-1); 2265 if (F == Foo && DotFramework == ".framework/") { 2266 isFramework = true; 2267 return Foo; 2268 } 2269 2270 // Next look for the form Foo.framework/Versions/A/Foo 2271 if (b == Name.npos) 2272 goto guess_library; 2273 c = Name.rfind('/', b); 2274 if (c == Name.npos || c == 0) 2275 goto guess_library; 2276 V = Name.slice(c+1, Name.npos); 2277 if (!V.startswith("Versions/")) 2278 goto guess_library; 2279 d = Name.rfind('/', c); 2280 if (d == Name.npos) 2281 Idx = 0; 2282 else 2283 Idx = d+1; 2284 F = Name.slice(Idx, Idx + Foo.size()); 2285 DotFramework = Name.slice(Idx + Foo.size(), 2286 Idx + Foo.size() + sizeof(".framework/")-1); 2287 if (F == Foo && DotFramework == ".framework/") { 2288 isFramework = true; 2289 return Foo; 2290 } 2291 2292 guess_library: 2293 // pull off the suffix after the "." and make a point to it 2294 a = Name.rfind('.'); 2295 if (a == Name.npos || a == 0) 2296 return StringRef(); 2297 Dylib = Name.slice(a, Name.npos); 2298 if (Dylib != ".dylib") 2299 goto guess_qtx; 2300 2301 // First pull off the version letter for the form Foo.A.dylib if any. 2302 if (a >= 3) { 2303 Dot = Name.slice(a-2, a-1); 2304 if (Dot == ".") 2305 a = a - 2; 2306 } 2307 2308 b = Name.rfind('/', a); 2309 if (b == Name.npos) 2310 b = 0; 2311 else 2312 b = b+1; 2313 // ignore any suffix after an underbar like Foo_profile.A.dylib 2314 Idx = Name.find('_', b); 2315 if (Idx != Name.npos && Idx != b) { 2316 Lib = Name.slice(b, Idx); 2317 Suffix = Name.slice(Idx, a); 2318 } 2319 else 2320 Lib = Name.slice(b, a); 2321 // There are incorrect library names of the form: 2322 // libATS.A_profile.dylib so check for these. 2323 if (Lib.size() >= 3) { 2324 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 2325 if (Dot == ".") 2326 Lib = Lib.slice(0, Lib.size()-2); 2327 } 2328 return Lib; 2329 2330 guess_qtx: 2331 Qtx = Name.slice(a, Name.npos); 2332 if (Qtx != ".qtx") 2333 return StringRef(); 2334 b = Name.rfind('/', a); 2335 if (b == Name.npos) 2336 Lib = Name.slice(0, a); 2337 else 2338 Lib = Name.slice(b+1, a); 2339 // There are library names of the form: QT.A.qtx so check for these. 2340 if (Lib.size() >= 3) { 2341 Dot = Lib.slice(Lib.size()-2, Lib.size()-1); 2342 if (Dot == ".") 2343 Lib = Lib.slice(0, Lib.size()-2); 2344 } 2345 return Lib; 2346 } 2347 2348 // getLibraryShortNameByIndex() is used to get the short name of the library 2349 // for an undefined symbol in a linked Mach-O binary that was linked with the 2350 // normal two-level namespace default (that is MH_TWOLEVEL in the header). 2351 // It is passed the index (0 - based) of the library as translated from 2352 // GET_LIBRARY_ORDINAL (1 - based). 2353 std::error_code MachOObjectFile::getLibraryShortNameByIndex(unsigned Index, 2354 StringRef &Res) const { 2355 if (Index >= Libraries.size()) 2356 return object_error::parse_failed; 2357 2358 // If the cache of LibrariesShortNames is not built up do that first for 2359 // all the Libraries. 2360 if (LibrariesShortNames.size() == 0) { 2361 for (unsigned i = 0; i < Libraries.size(); i++) { 2362 MachO::dylib_command D = 2363 getStruct<MachO::dylib_command>(*this, Libraries[i]); 2364 if (D.dylib.name >= D.cmdsize) 2365 return object_error::parse_failed; 2366 const char *P = (const char *)(Libraries[i]) + D.dylib.name; 2367 StringRef Name = StringRef(P); 2368 if (D.dylib.name+Name.size() >= D.cmdsize) 2369 return object_error::parse_failed; 2370 StringRef Suffix; 2371 bool isFramework; 2372 StringRef shortName = guessLibraryShortName(Name, isFramework, Suffix); 2373 if (shortName.empty()) 2374 LibrariesShortNames.push_back(Name); 2375 else 2376 LibrariesShortNames.push_back(shortName); 2377 } 2378 } 2379 2380 Res = LibrariesShortNames[Index]; 2381 return std::error_code(); 2382 } 2383 2384 uint32_t MachOObjectFile::getLibraryCount() const { 2385 return Libraries.size(); 2386 } 2387 2388 section_iterator 2389 MachOObjectFile::getRelocationRelocatedSection(relocation_iterator Rel) const { 2390 DataRefImpl Sec; 2391 Sec.d.a = Rel->getRawDataRefImpl().d.a; 2392 return section_iterator(SectionRef(Sec, this)); 2393 } 2394 2395 basic_symbol_iterator MachOObjectFile::symbol_begin() const { 2396 DataRefImpl DRI; 2397 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2398 if (!SymtabLoadCmd || Symtab.nsyms == 0) 2399 return basic_symbol_iterator(SymbolRef(DRI, this)); 2400 2401 return getSymbolByIndex(0); 2402 } 2403 2404 basic_symbol_iterator MachOObjectFile::symbol_end() const { 2405 DataRefImpl DRI; 2406 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2407 if (!SymtabLoadCmd || Symtab.nsyms == 0) 2408 return basic_symbol_iterator(SymbolRef(DRI, this)); 2409 2410 unsigned SymbolTableEntrySize = is64Bit() ? 2411 sizeof(MachO::nlist_64) : 2412 sizeof(MachO::nlist); 2413 unsigned Offset = Symtab.symoff + 2414 Symtab.nsyms * SymbolTableEntrySize; 2415 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2416 return basic_symbol_iterator(SymbolRef(DRI, this)); 2417 } 2418 2419 basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const { 2420 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2421 if (!SymtabLoadCmd || Index >= Symtab.nsyms) 2422 report_fatal_error("Requested symbol index is out of range."); 2423 unsigned SymbolTableEntrySize = 2424 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 2425 DataRefImpl DRI; 2426 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff)); 2427 DRI.p += Index * SymbolTableEntrySize; 2428 return basic_symbol_iterator(SymbolRef(DRI, this)); 2429 } 2430 2431 uint64_t MachOObjectFile::getSymbolIndex(DataRefImpl Symb) const { 2432 MachO::symtab_command Symtab = getSymtabLoadCommand(); 2433 if (!SymtabLoadCmd) 2434 report_fatal_error("getSymbolIndex() called with no symbol table symbol"); 2435 unsigned SymbolTableEntrySize = 2436 is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist); 2437 DataRefImpl DRIstart; 2438 DRIstart.p = reinterpret_cast<uintptr_t>(getPtr(*this, Symtab.symoff)); 2439 uint64_t Index = (Symb.p - DRIstart.p) / SymbolTableEntrySize; 2440 return Index; 2441 } 2442 2443 section_iterator MachOObjectFile::section_begin() const { 2444 DataRefImpl DRI; 2445 return section_iterator(SectionRef(DRI, this)); 2446 } 2447 2448 section_iterator MachOObjectFile::section_end() const { 2449 DataRefImpl DRI; 2450 DRI.d.a = Sections.size(); 2451 return section_iterator(SectionRef(DRI, this)); 2452 } 2453 2454 uint8_t MachOObjectFile::getBytesInAddress() const { 2455 return is64Bit() ? 8 : 4; 2456 } 2457 2458 StringRef MachOObjectFile::getFileFormatName() const { 2459 unsigned CPUType = getCPUType(*this); 2460 if (!is64Bit()) { 2461 switch (CPUType) { 2462 case MachO::CPU_TYPE_I386: 2463 return "Mach-O 32-bit i386"; 2464 case MachO::CPU_TYPE_ARM: 2465 return "Mach-O arm"; 2466 case MachO::CPU_TYPE_POWERPC: 2467 return "Mach-O 32-bit ppc"; 2468 default: 2469 return "Mach-O 32-bit unknown"; 2470 } 2471 } 2472 2473 switch (CPUType) { 2474 case MachO::CPU_TYPE_X86_64: 2475 return "Mach-O 64-bit x86-64"; 2476 case MachO::CPU_TYPE_ARM64: 2477 return "Mach-O arm64"; 2478 case MachO::CPU_TYPE_POWERPC64: 2479 return "Mach-O 64-bit ppc64"; 2480 default: 2481 return "Mach-O 64-bit unknown"; 2482 } 2483 } 2484 2485 Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { 2486 switch (CPUType) { 2487 case MachO::CPU_TYPE_I386: 2488 return Triple::x86; 2489 case MachO::CPU_TYPE_X86_64: 2490 return Triple::x86_64; 2491 case MachO::CPU_TYPE_ARM: 2492 return Triple::arm; 2493 case MachO::CPU_TYPE_ARM64: 2494 return Triple::aarch64; 2495 case MachO::CPU_TYPE_POWERPC: 2496 return Triple::ppc; 2497 case MachO::CPU_TYPE_POWERPC64: 2498 return Triple::ppc64; 2499 default: 2500 return Triple::UnknownArch; 2501 } 2502 } 2503 2504 Triple MachOObjectFile::getArchTriple(uint32_t CPUType, uint32_t CPUSubType, 2505 const char **McpuDefault, 2506 const char **ArchFlag) { 2507 if (McpuDefault) 2508 *McpuDefault = nullptr; 2509 if (ArchFlag) 2510 *ArchFlag = nullptr; 2511 2512 switch (CPUType) { 2513 case MachO::CPU_TYPE_I386: 2514 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2515 case MachO::CPU_SUBTYPE_I386_ALL: 2516 if (ArchFlag) 2517 *ArchFlag = "i386"; 2518 return Triple("i386-apple-darwin"); 2519 default: 2520 return Triple(); 2521 } 2522 case MachO::CPU_TYPE_X86_64: 2523 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2524 case MachO::CPU_SUBTYPE_X86_64_ALL: 2525 if (ArchFlag) 2526 *ArchFlag = "x86_64"; 2527 return Triple("x86_64-apple-darwin"); 2528 case MachO::CPU_SUBTYPE_X86_64_H: 2529 if (ArchFlag) 2530 *ArchFlag = "x86_64h"; 2531 return Triple("x86_64h-apple-darwin"); 2532 default: 2533 return Triple(); 2534 } 2535 case MachO::CPU_TYPE_ARM: 2536 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2537 case MachO::CPU_SUBTYPE_ARM_V4T: 2538 if (ArchFlag) 2539 *ArchFlag = "armv4t"; 2540 return Triple("armv4t-apple-darwin"); 2541 case MachO::CPU_SUBTYPE_ARM_V5TEJ: 2542 if (ArchFlag) 2543 *ArchFlag = "armv5e"; 2544 return Triple("armv5e-apple-darwin"); 2545 case MachO::CPU_SUBTYPE_ARM_XSCALE: 2546 if (ArchFlag) 2547 *ArchFlag = "xscale"; 2548 return Triple("xscale-apple-darwin"); 2549 case MachO::CPU_SUBTYPE_ARM_V6: 2550 if (ArchFlag) 2551 *ArchFlag = "armv6"; 2552 return Triple("armv6-apple-darwin"); 2553 case MachO::CPU_SUBTYPE_ARM_V6M: 2554 if (McpuDefault) 2555 *McpuDefault = "cortex-m0"; 2556 if (ArchFlag) 2557 *ArchFlag = "armv6m"; 2558 return Triple("armv6m-apple-darwin"); 2559 case MachO::CPU_SUBTYPE_ARM_V7: 2560 if (ArchFlag) 2561 *ArchFlag = "armv7"; 2562 return Triple("armv7-apple-darwin"); 2563 case MachO::CPU_SUBTYPE_ARM_V7EM: 2564 if (McpuDefault) 2565 *McpuDefault = "cortex-m4"; 2566 if (ArchFlag) 2567 *ArchFlag = "armv7em"; 2568 return Triple("thumbv7em-apple-darwin"); 2569 case MachO::CPU_SUBTYPE_ARM_V7K: 2570 if (McpuDefault) 2571 *McpuDefault = "cortex-a7"; 2572 if (ArchFlag) 2573 *ArchFlag = "armv7k"; 2574 return Triple("armv7k-apple-darwin"); 2575 case MachO::CPU_SUBTYPE_ARM_V7M: 2576 if (McpuDefault) 2577 *McpuDefault = "cortex-m3"; 2578 if (ArchFlag) 2579 *ArchFlag = "armv7m"; 2580 return Triple("thumbv7m-apple-darwin"); 2581 case MachO::CPU_SUBTYPE_ARM_V7S: 2582 if (McpuDefault) 2583 *McpuDefault = "cortex-a7"; 2584 if (ArchFlag) 2585 *ArchFlag = "armv7s"; 2586 return Triple("armv7s-apple-darwin"); 2587 default: 2588 return Triple(); 2589 } 2590 case MachO::CPU_TYPE_ARM64: 2591 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2592 case MachO::CPU_SUBTYPE_ARM64_ALL: 2593 if (McpuDefault) 2594 *McpuDefault = "cyclone"; 2595 if (ArchFlag) 2596 *ArchFlag = "arm64"; 2597 return Triple("arm64-apple-darwin"); 2598 default: 2599 return Triple(); 2600 } 2601 case MachO::CPU_TYPE_POWERPC: 2602 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2603 case MachO::CPU_SUBTYPE_POWERPC_ALL: 2604 if (ArchFlag) 2605 *ArchFlag = "ppc"; 2606 return Triple("ppc-apple-darwin"); 2607 default: 2608 return Triple(); 2609 } 2610 case MachO::CPU_TYPE_POWERPC64: 2611 switch (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) { 2612 case MachO::CPU_SUBTYPE_POWERPC_ALL: 2613 if (ArchFlag) 2614 *ArchFlag = "ppc64"; 2615 return Triple("ppc64-apple-darwin"); 2616 default: 2617 return Triple(); 2618 } 2619 default: 2620 return Triple(); 2621 } 2622 } 2623 2624 Triple MachOObjectFile::getHostArch() { 2625 return Triple(sys::getDefaultTargetTriple()); 2626 } 2627 2628 bool MachOObjectFile::isValidArch(StringRef ArchFlag) { 2629 return StringSwitch<bool>(ArchFlag) 2630 .Case("i386", true) 2631 .Case("x86_64", true) 2632 .Case("x86_64h", true) 2633 .Case("armv4t", true) 2634 .Case("arm", true) 2635 .Case("armv5e", true) 2636 .Case("armv6", true) 2637 .Case("armv6m", true) 2638 .Case("armv7", true) 2639 .Case("armv7em", true) 2640 .Case("armv7k", true) 2641 .Case("armv7m", true) 2642 .Case("armv7s", true) 2643 .Case("arm64", true) 2644 .Case("ppc", true) 2645 .Case("ppc64", true) 2646 .Default(false); 2647 } 2648 2649 Triple::ArchType MachOObjectFile::getArch() const { 2650 return getArch(getCPUType(*this)); 2651 } 2652 2653 Triple MachOObjectFile::getArchTriple(const char **McpuDefault) const { 2654 return getArchTriple(Header.cputype, Header.cpusubtype, McpuDefault); 2655 } 2656 2657 relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { 2658 DataRefImpl DRI; 2659 DRI.d.a = Index; 2660 return section_rel_begin(DRI); 2661 } 2662 2663 relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { 2664 DataRefImpl DRI; 2665 DRI.d.a = Index; 2666 return section_rel_end(DRI); 2667 } 2668 2669 dice_iterator MachOObjectFile::begin_dices() const { 2670 DataRefImpl DRI; 2671 if (!DataInCodeLoadCmd) 2672 return dice_iterator(DiceRef(DRI, this)); 2673 2674 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 2675 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, DicLC.dataoff)); 2676 return dice_iterator(DiceRef(DRI, this)); 2677 } 2678 2679 dice_iterator MachOObjectFile::end_dices() const { 2680 DataRefImpl DRI; 2681 if (!DataInCodeLoadCmd) 2682 return dice_iterator(DiceRef(DRI, this)); 2683 2684 MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); 2685 unsigned Offset = DicLC.dataoff + DicLC.datasize; 2686 DRI.p = reinterpret_cast<uintptr_t>(getPtr(*this, Offset)); 2687 return dice_iterator(DiceRef(DRI, this)); 2688 } 2689 2690 ExportEntry::ExportEntry(Error *E, const MachOObjectFile *O, 2691 ArrayRef<uint8_t> T) : E(E), O(O), Trie(T) {} 2692 2693 void ExportEntry::moveToFirst() { 2694 ErrorAsOutParameter ErrAsOutParam(E); 2695 pushNode(0); 2696 if (*E) 2697 return; 2698 pushDownUntilBottom(); 2699 } 2700 2701 void ExportEntry::moveToEnd() { 2702 Stack.clear(); 2703 Done = true; 2704 } 2705 2706 bool ExportEntry::operator==(const ExportEntry &Other) const { 2707 // Common case, one at end, other iterating from begin. 2708 if (Done || Other.Done) 2709 return (Done == Other.Done); 2710 // Not equal if different stack sizes. 2711 if (Stack.size() != Other.Stack.size()) 2712 return false; 2713 // Not equal if different cumulative strings. 2714 if (!CumulativeString.equals(Other.CumulativeString)) 2715 return false; 2716 // Equal if all nodes in both stacks match. 2717 for (unsigned i=0; i < Stack.size(); ++i) { 2718 if (Stack[i].Start != Other.Stack[i].Start) 2719 return false; 2720 } 2721 return true; 2722 } 2723 2724 uint64_t ExportEntry::readULEB128(const uint8_t *&Ptr, const char **error) { 2725 unsigned Count; 2726 uint64_t Result = decodeULEB128(Ptr, &Count, Trie.end(), error); 2727 Ptr += Count; 2728 if (Ptr > Trie.end()) 2729 Ptr = Trie.end(); 2730 return Result; 2731 } 2732 2733 StringRef ExportEntry::name() const { 2734 return CumulativeString; 2735 } 2736 2737 uint64_t ExportEntry::flags() const { 2738 return Stack.back().Flags; 2739 } 2740 2741 uint64_t ExportEntry::address() const { 2742 return Stack.back().Address; 2743 } 2744 2745 uint64_t ExportEntry::other() const { 2746 return Stack.back().Other; 2747 } 2748 2749 StringRef ExportEntry::otherName() const { 2750 const char* ImportName = Stack.back().ImportName; 2751 if (ImportName) 2752 return StringRef(ImportName); 2753 return StringRef(); 2754 } 2755 2756 uint32_t ExportEntry::nodeOffset() const { 2757 return Stack.back().Start - Trie.begin(); 2758 } 2759 2760 ExportEntry::NodeState::NodeState(const uint8_t *Ptr) 2761 : Start(Ptr), Current(Ptr) {} 2762 2763 void ExportEntry::pushNode(uint64_t offset) { 2764 ErrorAsOutParameter ErrAsOutParam(E); 2765 const uint8_t *Ptr = Trie.begin() + offset; 2766 NodeState State(Ptr); 2767 const char *error; 2768 uint64_t ExportInfoSize = readULEB128(State.Current, &error); 2769 if (error) { 2770 *E = malformedError("export info size " + Twine(error) + 2771 " in export trie data at node: 0x" + 2772 Twine::utohexstr(offset)); 2773 moveToEnd(); 2774 return; 2775 } 2776 State.IsExportNode = (ExportInfoSize != 0); 2777 const uint8_t* Children = State.Current + ExportInfoSize; 2778 if (Children > Trie.end()) { 2779 *E = malformedError( 2780 "export info size: 0x" + Twine::utohexstr(ExportInfoSize) + 2781 " in export trie data at node: 0x" + Twine::utohexstr(offset) + 2782 " too big and extends past end of trie data"); 2783 moveToEnd(); 2784 return; 2785 } 2786 if (State.IsExportNode) { 2787 const uint8_t *ExportStart = State.Current; 2788 State.Flags = readULEB128(State.Current, &error); 2789 if (error) { 2790 *E = malformedError("flags " + Twine(error) + 2791 " in export trie data at node: 0x" + 2792 Twine::utohexstr(offset)); 2793 moveToEnd(); 2794 return; 2795 } 2796 uint64_t Kind = State.Flags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK; 2797 if (State.Flags != 0 && 2798 (Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR && 2799 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE && 2800 Kind != MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL)) { 2801 *E = malformedError( 2802 "unsupported exported symbol kind: " + Twine((int)Kind) + 2803 " in flags: 0x" + Twine::utohexstr(State.Flags) + 2804 " in export trie data at node: 0x" + Twine::utohexstr(offset)); 2805 moveToEnd(); 2806 return; 2807 } 2808 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) { 2809 State.Address = 0; 2810 State.Other = readULEB128(State.Current, &error); // dylib ordinal 2811 if (error) { 2812 *E = malformedError("dylib ordinal of re-export " + Twine(error) + 2813 " in export trie data at node: 0x" + 2814 Twine::utohexstr(offset)); 2815 moveToEnd(); 2816 return; 2817 } 2818 if (O != nullptr) { 2819 if (State.Other > O->getLibraryCount()) { 2820 *E = malformedError( 2821 "bad library ordinal: " + Twine((int)State.Other) + " (max " + 2822 Twine((int)O->getLibraryCount()) + 2823 ") in export trie data at node: 0x" + Twine::utohexstr(offset)); 2824 moveToEnd(); 2825 return; 2826 } 2827 } 2828 State.ImportName = reinterpret_cast<const char*>(State.Current); 2829 if (*State.ImportName == '\0') { 2830 State.Current++; 2831 } else { 2832 const uint8_t *End = State.Current + 1; 2833 if (End >= Trie.end()) { 2834 *E = malformedError("import name of re-export in export trie data at " 2835 "node: 0x" + 2836 Twine::utohexstr(offset) + 2837 " starts past end of trie data"); 2838 moveToEnd(); 2839 return; 2840 } 2841 while(*End != '\0' && End < Trie.end()) 2842 End++; 2843 if (*End != '\0') { 2844 *E = malformedError("import name of re-export in export trie data at " 2845 "node: 0x" + 2846 Twine::utohexstr(offset) + 2847 " extends past end of trie data"); 2848 moveToEnd(); 2849 return; 2850 } 2851 State.Current = End + 1; 2852 } 2853 } else { 2854 State.Address = readULEB128(State.Current, &error); 2855 if (error) { 2856 *E = malformedError("address " + Twine(error) + 2857 " in export trie data at node: 0x" + 2858 Twine::utohexstr(offset)); 2859 moveToEnd(); 2860 return; 2861 } 2862 if (State.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) { 2863 State.Other = readULEB128(State.Current, &error); 2864 if (error) { 2865 *E = malformedError("resolver of stub and resolver " + Twine(error) + 2866 " in export trie data at node: 0x" + 2867 Twine::utohexstr(offset)); 2868 moveToEnd(); 2869 return; 2870 } 2871 } 2872 } 2873 if(ExportStart + ExportInfoSize != State.Current) { 2874 *E = malformedError( 2875 "inconsistant export info size: 0x" + 2876 Twine::utohexstr(ExportInfoSize) + " where actual size was: 0x" + 2877 Twine::utohexstr(State.Current - ExportStart) + 2878 " in export trie data at node: 0x" + Twine::utohexstr(offset)); 2879 moveToEnd(); 2880 return; 2881 } 2882 } 2883 State.ChildCount = *Children; 2884 if (State.ChildCount != 0 && Children + 1 >= Trie.end()) { 2885 *E = malformedError("byte for count of childern in export trie data at " 2886 "node: 0x" + 2887 Twine::utohexstr(offset) + 2888 " extends past end of trie data"); 2889 moveToEnd(); 2890 return; 2891 } 2892 State.Current = Children + 1; 2893 State.NextChildIndex = 0; 2894 State.ParentStringLength = CumulativeString.size(); 2895 Stack.push_back(State); 2896 } 2897 2898 void ExportEntry::pushDownUntilBottom() { 2899 ErrorAsOutParameter ErrAsOutParam(E); 2900 const char *error; 2901 while (Stack.back().NextChildIndex < Stack.back().ChildCount) { 2902 NodeState &Top = Stack.back(); 2903 CumulativeString.resize(Top.ParentStringLength); 2904 for (;*Top.Current != 0 && Top.Current < Trie.end(); Top.Current++) { 2905 char C = *Top.Current; 2906 CumulativeString.push_back(C); 2907 } 2908 if (Top.Current >= Trie.end()) { 2909 *E = malformedError("edge sub-string in export trie data at node: 0x" + 2910 Twine::utohexstr(Top.Start - Trie.begin()) + 2911 " for child #" + Twine((int)Top.NextChildIndex) + 2912 " extends past end of trie data"); 2913 moveToEnd(); 2914 return; 2915 } 2916 Top.Current += 1; 2917 uint64_t childNodeIndex = readULEB128(Top.Current, &error); 2918 if (error) { 2919 *E = malformedError("child node offset " + Twine(error) + 2920 " in export trie data at node: 0x" + 2921 Twine::utohexstr(Top.Start - Trie.begin())); 2922 moveToEnd(); 2923 return; 2924 } 2925 for (const NodeState &node : nodes()) { 2926 if (node.Start == Trie.begin() + childNodeIndex){ 2927 *E = malformedError("loop in childern in export trie data at node: 0x" + 2928 Twine::utohexstr(Top.Start - Trie.begin()) + 2929 " back to node: 0x" + 2930 Twine::utohexstr(childNodeIndex)); 2931 moveToEnd(); 2932 return; 2933 } 2934 } 2935 Top.NextChildIndex += 1; 2936 pushNode(childNodeIndex); 2937 if (*E) 2938 return; 2939 } 2940 if (!Stack.back().IsExportNode) { 2941 *E = malformedError("node is not an export node in export trie data at " 2942 "node: 0x" + 2943 Twine::utohexstr(Stack.back().Start - Trie.begin())); 2944 moveToEnd(); 2945 return; 2946 } 2947 } 2948 2949 // We have a trie data structure and need a way to walk it that is compatible 2950 // with the C++ iterator model. The solution is a non-recursive depth first 2951 // traversal where the iterator contains a stack of parent nodes along with a 2952 // string that is the accumulation of all edge strings along the parent chain 2953 // to this point. 2954 // 2955 // There is one "export" node for each exported symbol. But because some 2956 // symbols may be a prefix of another symbol (e.g. _dup and _dup2), an export 2957 // node may have child nodes too. 2958 // 2959 // The algorithm for moveNext() is to keep moving down the leftmost unvisited 2960 // child until hitting a node with no children (which is an export node or 2961 // else the trie is malformed). On the way down, each node is pushed on the 2962 // stack ivar. If there is no more ways down, it pops up one and tries to go 2963 // down a sibling path until a childless node is reached. 2964 void ExportEntry::moveNext() { 2965 assert(!Stack.empty() && "ExportEntry::moveNext() with empty node stack"); 2966 if (!Stack.back().IsExportNode) { 2967 *E = malformedError("node is not an export node in export trie data at " 2968 "node: 0x" + 2969 Twine::utohexstr(Stack.back().Start - Trie.begin())); 2970 moveToEnd(); 2971 return; 2972 } 2973 2974 Stack.pop_back(); 2975 while (!Stack.empty()) { 2976 NodeState &Top = Stack.back(); 2977 if (Top.NextChildIndex < Top.ChildCount) { 2978 pushDownUntilBottom(); 2979 // Now at the next export node. 2980 return; 2981 } else { 2982 if (Top.IsExportNode) { 2983 // This node has no children but is itself an export node. 2984 CumulativeString.resize(Top.ParentStringLength); 2985 return; 2986 } 2987 Stack.pop_back(); 2988 } 2989 } 2990 Done = true; 2991 } 2992 2993 iterator_range<export_iterator> 2994 MachOObjectFile::exports(Error &E, ArrayRef<uint8_t> Trie, 2995 const MachOObjectFile *O) { 2996 ExportEntry Start(&E, O, Trie); 2997 if (Trie.empty()) 2998 Start.moveToEnd(); 2999 else 3000 Start.moveToFirst(); 3001 3002 ExportEntry Finish(&E, O, Trie); 3003 Finish.moveToEnd(); 3004 3005 return make_range(export_iterator(Start), export_iterator(Finish)); 3006 } 3007 3008 iterator_range<export_iterator> MachOObjectFile::exports(Error &Err) const { 3009 return exports(Err, getDyldInfoExportsTrie(), this); 3010 } 3011 3012 MachORebaseEntry::MachORebaseEntry(Error *E, const MachOObjectFile *O, 3013 ArrayRef<uint8_t> Bytes, bool is64Bit) 3014 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), 3015 PointerSize(is64Bit ? 8 : 4) {} 3016 3017 void MachORebaseEntry::moveToFirst() { 3018 Ptr = Opcodes.begin(); 3019 moveNext(); 3020 } 3021 3022 void MachORebaseEntry::moveToEnd() { 3023 Ptr = Opcodes.end(); 3024 RemainingLoopCount = 0; 3025 Done = true; 3026 } 3027 3028 void MachORebaseEntry::moveNext() { 3029 ErrorAsOutParameter ErrAsOutParam(E); 3030 // If in the middle of some loop, move to next rebasing in loop. 3031 SegmentOffset += AdvanceAmount; 3032 if (RemainingLoopCount) { 3033 --RemainingLoopCount; 3034 return; 3035 } 3036 // REBASE_OPCODE_DONE is only used for padding if we are not aligned to 3037 // pointer size. Therefore it is possible to reach the end without ever having 3038 // seen REBASE_OPCODE_DONE. 3039 if (Ptr == Opcodes.end()) { 3040 Done = true; 3041 return; 3042 } 3043 bool More = true; 3044 while (More) { 3045 // Parse next opcode and set up next loop. 3046 const uint8_t *OpcodeStart = Ptr; 3047 uint8_t Byte = *Ptr++; 3048 uint8_t ImmValue = Byte & MachO::REBASE_IMMEDIATE_MASK; 3049 uint8_t Opcode = Byte & MachO::REBASE_OPCODE_MASK; 3050 uint32_t Count, Skip; 3051 const char *error = nullptr; 3052 switch (Opcode) { 3053 case MachO::REBASE_OPCODE_DONE: 3054 More = false; 3055 Done = true; 3056 moveToEnd(); 3057 DEBUG_WITH_TYPE("mach-o-rebase", dbgs() << "REBASE_OPCODE_DONE\n"); 3058 break; 3059 case MachO::REBASE_OPCODE_SET_TYPE_IMM: 3060 RebaseType = ImmValue; 3061 if (RebaseType > MachO::REBASE_TYPE_TEXT_PCREL32) { 3062 *E = malformedError("for REBASE_OPCODE_SET_TYPE_IMM bad bind type: " + 3063 Twine((int)RebaseType) + " for opcode at: 0x" + 3064 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3065 moveToEnd(); 3066 return; 3067 } 3068 DEBUG_WITH_TYPE( 3069 "mach-o-rebase", 3070 dbgs() << "REBASE_OPCODE_SET_TYPE_IMM: " 3071 << "RebaseType=" << (int) RebaseType << "\n"); 3072 break; 3073 case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 3074 SegmentIndex = ImmValue; 3075 SegmentOffset = readULEB128(&error); 3076 if (error) { 3077 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3078 Twine(error) + " for opcode at: 0x" + 3079 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3080 moveToEnd(); 3081 return; 3082 } 3083 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3084 true); 3085 if (error) { 3086 *E = malformedError("for REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3087 Twine(error) + " for opcode at: 0x" + 3088 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3089 moveToEnd(); 3090 return; 3091 } 3092 DEBUG_WITH_TYPE( 3093 "mach-o-rebase", 3094 dbgs() << "REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3095 << "SegmentIndex=" << SegmentIndex << ", " 3096 << format("SegmentOffset=0x%06X", SegmentOffset) 3097 << "\n"); 3098 break; 3099 case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: 3100 SegmentOffset += readULEB128(&error); 3101 if (error) { 3102 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3103 " for opcode at: 0x" + 3104 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3105 moveToEnd(); 3106 return; 3107 } 3108 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3109 true); 3110 if (error) { 3111 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3112 " for opcode at: 0x" + 3113 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3114 moveToEnd(); 3115 return; 3116 } 3117 DEBUG_WITH_TYPE("mach-o-rebase", 3118 dbgs() << "REBASE_OPCODE_ADD_ADDR_ULEB: " 3119 << format("SegmentOffset=0x%06X", 3120 SegmentOffset) << "\n"); 3121 break; 3122 case MachO::REBASE_OPCODE_ADD_ADDR_IMM_SCALED: 3123 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3124 true); 3125 if (error) { 3126 *E = malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " + 3127 Twine(error) + " for opcode at: 0x" + 3128 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3129 moveToEnd(); 3130 return; 3131 } 3132 SegmentOffset += ImmValue * PointerSize; 3133 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3134 false); 3135 if (error) { 3136 *E = 3137 malformedError("for REBASE_OPCODE_ADD_ADDR_IMM_SCALED " 3138 " (after adding immediate times the pointer size) " + 3139 Twine(error) + " for opcode at: 0x" + 3140 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3141 moveToEnd(); 3142 return; 3143 } 3144 DEBUG_WITH_TYPE("mach-o-rebase", 3145 dbgs() << "REBASE_OPCODE_ADD_ADDR_IMM_SCALED: " 3146 << format("SegmentOffset=0x%06X", 3147 SegmentOffset) << "\n"); 3148 break; 3149 case MachO::REBASE_OPCODE_DO_REBASE_IMM_TIMES: 3150 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3151 true); 3152 if (error) { 3153 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " + 3154 Twine(error) + " for opcode at: 0x" + 3155 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3156 moveToEnd(); 3157 return; 3158 } 3159 AdvanceAmount = PointerSize; 3160 Skip = 0; 3161 Count = ImmValue; 3162 if (ImmValue != 0) 3163 RemainingLoopCount = ImmValue - 1; 3164 else 3165 RemainingLoopCount = 0; 3166 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3167 SegmentIndex, SegmentOffset); 3168 if (error) { 3169 *E = malformedError("for REBASE_OPCODE_DO_REBASE_IMM_TIMES " + 3170 Twine(error) + " for opcode at: 0x" + 3171 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3172 moveToEnd(); 3173 return; 3174 } 3175 DEBUG_WITH_TYPE( 3176 "mach-o-rebase", 3177 dbgs() << "REBASE_OPCODE_DO_REBASE_IMM_TIMES: " 3178 << format("SegmentOffset=0x%06X", SegmentOffset) 3179 << ", AdvanceAmount=" << AdvanceAmount 3180 << ", RemainingLoopCount=" << RemainingLoopCount 3181 << "\n"); 3182 return; 3183 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: 3184 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3185 true); 3186 if (error) { 3187 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3188 Twine(error) + " for opcode at: 0x" + 3189 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3190 moveToEnd(); 3191 return; 3192 } 3193 AdvanceAmount = PointerSize; 3194 Skip = 0; 3195 Count = readULEB128(&error); 3196 if (error) { 3197 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3198 Twine(error) + " for opcode at: 0x" + 3199 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3200 moveToEnd(); 3201 return; 3202 } 3203 if (Count != 0) 3204 RemainingLoopCount = Count - 1; 3205 else 3206 RemainingLoopCount = 0; 3207 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3208 SegmentIndex, SegmentOffset); 3209 if (error) { 3210 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES " + 3211 Twine(error) + " for opcode at: 0x" + 3212 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3213 moveToEnd(); 3214 return; 3215 } 3216 DEBUG_WITH_TYPE( 3217 "mach-o-rebase", 3218 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES: " 3219 << format("SegmentOffset=0x%06X", SegmentOffset) 3220 << ", AdvanceAmount=" << AdvanceAmount 3221 << ", RemainingLoopCount=" << RemainingLoopCount 3222 << "\n"); 3223 return; 3224 case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: 3225 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3226 true); 3227 if (error) { 3228 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3229 Twine(error) + " for opcode at: 0x" + 3230 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3231 moveToEnd(); 3232 return; 3233 } 3234 Skip = readULEB128(&error); 3235 if (error) { 3236 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3237 Twine(error) + " for opcode at: 0x" + 3238 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3239 moveToEnd(); 3240 return; 3241 } 3242 AdvanceAmount = Skip + PointerSize; 3243 Count = 1; 3244 RemainingLoopCount = 0; 3245 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3246 SegmentIndex, SegmentOffset); 3247 if (error) { 3248 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB " + 3249 Twine(error) + " for opcode at: 0x" + 3250 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3251 moveToEnd(); 3252 return; 3253 } 3254 DEBUG_WITH_TYPE( 3255 "mach-o-rebase", 3256 dbgs() << "REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: " 3257 << format("SegmentOffset=0x%06X", SegmentOffset) 3258 << ", AdvanceAmount=" << AdvanceAmount 3259 << ", RemainingLoopCount=" << RemainingLoopCount 3260 << "\n"); 3261 return; 3262 case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: 3263 error = O->RebaseEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, 3264 true); 3265 if (error) { 3266 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3267 "ULEB " + 3268 Twine(error) + " for opcode at: 0x" + 3269 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3270 moveToEnd(); 3271 return; 3272 } 3273 Count = readULEB128(&error); 3274 if (error) { 3275 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3276 "ULEB " + 3277 Twine(error) + " for opcode at: 0x" + 3278 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3279 moveToEnd(); 3280 return; 3281 } 3282 if (Count != 0) 3283 RemainingLoopCount = Count - 1; 3284 else 3285 RemainingLoopCount = 0; 3286 Skip = readULEB128(&error); 3287 if (error) { 3288 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3289 "ULEB " + 3290 Twine(error) + " for opcode at: 0x" + 3291 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3292 moveToEnd(); 3293 return; 3294 } 3295 AdvanceAmount = Skip + PointerSize; 3296 3297 error = O->RebaseEntryCheckCountAndSkip(Count, Skip, PointerSize, 3298 SegmentIndex, SegmentOffset); 3299 if (error) { 3300 *E = malformedError("for REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_" 3301 "ULEB " + 3302 Twine(error) + " for opcode at: 0x" + 3303 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3304 moveToEnd(); 3305 return; 3306 } 3307 DEBUG_WITH_TYPE( 3308 "mach-o-rebase", 3309 dbgs() << "REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: " 3310 << format("SegmentOffset=0x%06X", SegmentOffset) 3311 << ", AdvanceAmount=" << AdvanceAmount 3312 << ", RemainingLoopCount=" << RemainingLoopCount 3313 << "\n"); 3314 return; 3315 default: 3316 *E = malformedError("bad rebase info (bad opcode value 0x" + 3317 Twine::utohexstr(Opcode) + " for opcode at: 0x" + 3318 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3319 moveToEnd(); 3320 return; 3321 } 3322 } 3323 } 3324 3325 uint64_t MachORebaseEntry::readULEB128(const char **error) { 3326 unsigned Count; 3327 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error); 3328 Ptr += Count; 3329 if (Ptr > Opcodes.end()) 3330 Ptr = Opcodes.end(); 3331 return Result; 3332 } 3333 3334 int32_t MachORebaseEntry::segmentIndex() const { return SegmentIndex; } 3335 3336 uint64_t MachORebaseEntry::segmentOffset() const { return SegmentOffset; } 3337 3338 StringRef MachORebaseEntry::typeName() const { 3339 switch (RebaseType) { 3340 case MachO::REBASE_TYPE_POINTER: 3341 return "pointer"; 3342 case MachO::REBASE_TYPE_TEXT_ABSOLUTE32: 3343 return "text abs32"; 3344 case MachO::REBASE_TYPE_TEXT_PCREL32: 3345 return "text rel32"; 3346 } 3347 return "unknown"; 3348 } 3349 3350 // For use with the SegIndex of a checked Mach-O Rebase entry 3351 // to get the segment name. 3352 StringRef MachORebaseEntry::segmentName() const { 3353 return O->BindRebaseSegmentName(SegmentIndex); 3354 } 3355 3356 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3357 // to get the section name. 3358 StringRef MachORebaseEntry::sectionName() const { 3359 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset); 3360 } 3361 3362 // For use with a SegIndex,SegOffset pair from a checked Mach-O Rebase entry 3363 // to get the address. 3364 uint64_t MachORebaseEntry::address() const { 3365 return O->BindRebaseAddress(SegmentIndex, SegmentOffset); 3366 } 3367 3368 bool MachORebaseEntry::operator==(const MachORebaseEntry &Other) const { 3369 #ifdef EXPENSIVE_CHECKS 3370 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 3371 #else 3372 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files"); 3373 #endif 3374 return (Ptr == Other.Ptr) && 3375 (RemainingLoopCount == Other.RemainingLoopCount) && 3376 (Done == Other.Done); 3377 } 3378 3379 iterator_range<rebase_iterator> 3380 MachOObjectFile::rebaseTable(Error &Err, MachOObjectFile *O, 3381 ArrayRef<uint8_t> Opcodes, bool is64) { 3382 if (O->BindRebaseSectionTable == nullptr) 3383 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O); 3384 MachORebaseEntry Start(&Err, O, Opcodes, is64); 3385 Start.moveToFirst(); 3386 3387 MachORebaseEntry Finish(&Err, O, Opcodes, is64); 3388 Finish.moveToEnd(); 3389 3390 return make_range(rebase_iterator(Start), rebase_iterator(Finish)); 3391 } 3392 3393 iterator_range<rebase_iterator> MachOObjectFile::rebaseTable(Error &Err) { 3394 return rebaseTable(Err, this, getDyldInfoRebaseOpcodes(), is64Bit()); 3395 } 3396 3397 MachOBindEntry::MachOBindEntry(Error *E, const MachOObjectFile *O, 3398 ArrayRef<uint8_t> Bytes, bool is64Bit, Kind BK) 3399 : E(E), O(O), Opcodes(Bytes), Ptr(Bytes.begin()), 3400 PointerSize(is64Bit ? 8 : 4), TableKind(BK) {} 3401 3402 void MachOBindEntry::moveToFirst() { 3403 Ptr = Opcodes.begin(); 3404 moveNext(); 3405 } 3406 3407 void MachOBindEntry::moveToEnd() { 3408 Ptr = Opcodes.end(); 3409 RemainingLoopCount = 0; 3410 Done = true; 3411 } 3412 3413 void MachOBindEntry::moveNext() { 3414 ErrorAsOutParameter ErrAsOutParam(E); 3415 // If in the middle of some loop, move to next binding in loop. 3416 SegmentOffset += AdvanceAmount; 3417 if (RemainingLoopCount) { 3418 --RemainingLoopCount; 3419 return; 3420 } 3421 // BIND_OPCODE_DONE is only used for padding if we are not aligned to 3422 // pointer size. Therefore it is possible to reach the end without ever having 3423 // seen BIND_OPCODE_DONE. 3424 if (Ptr == Opcodes.end()) { 3425 Done = true; 3426 return; 3427 } 3428 bool More = true; 3429 while (More) { 3430 // Parse next opcode and set up next loop. 3431 const uint8_t *OpcodeStart = Ptr; 3432 uint8_t Byte = *Ptr++; 3433 uint8_t ImmValue = Byte & MachO::BIND_IMMEDIATE_MASK; 3434 uint8_t Opcode = Byte & MachO::BIND_OPCODE_MASK; 3435 int8_t SignExtended; 3436 const uint8_t *SymStart; 3437 uint32_t Count, Skip; 3438 const char *error = nullptr; 3439 switch (Opcode) { 3440 case MachO::BIND_OPCODE_DONE: 3441 if (TableKind == Kind::Lazy) { 3442 // Lazying bindings have a DONE opcode between entries. Need to ignore 3443 // it to advance to next entry. But need not if this is last entry. 3444 bool NotLastEntry = false; 3445 for (const uint8_t *P = Ptr; P < Opcodes.end(); ++P) { 3446 if (*P) { 3447 NotLastEntry = true; 3448 } 3449 } 3450 if (NotLastEntry) 3451 break; 3452 } 3453 More = false; 3454 moveToEnd(); 3455 DEBUG_WITH_TYPE("mach-o-bind", dbgs() << "BIND_OPCODE_DONE\n"); 3456 break; 3457 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: 3458 if (TableKind == Kind::Weak) { 3459 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM not allowed in " 3460 "weak bind table for opcode at: 0x" + 3461 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3462 moveToEnd(); 3463 return; 3464 } 3465 Ordinal = ImmValue; 3466 LibraryOrdinalSet = true; 3467 if (ImmValue > O->getLibraryCount()) { 3468 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3469 "library ordinal: " + 3470 Twine((int)ImmValue) + " (max " + 3471 Twine((int)O->getLibraryCount()) + 3472 ") for opcode at: 0x" + 3473 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3474 moveToEnd(); 3475 return; 3476 } 3477 DEBUG_WITH_TYPE( 3478 "mach-o-bind", 3479 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: " 3480 << "Ordinal=" << Ordinal << "\n"); 3481 break; 3482 case MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: 3483 if (TableKind == Kind::Weak) { 3484 *E = malformedError("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB not allowed in " 3485 "weak bind table for opcode at: 0x" + 3486 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3487 moveToEnd(); 3488 return; 3489 } 3490 Ordinal = readULEB128(&error); 3491 LibraryOrdinalSet = true; 3492 if (error) { 3493 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB " + 3494 Twine(error) + " for opcode at: 0x" + 3495 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3496 moveToEnd(); 3497 return; 3498 } 3499 if (Ordinal > (int)O->getLibraryCount()) { 3500 *E = malformedError("for BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB bad " 3501 "library ordinal: " + 3502 Twine((int)Ordinal) + " (max " + 3503 Twine((int)O->getLibraryCount()) + 3504 ") for opcode at: 0x" + 3505 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3506 moveToEnd(); 3507 return; 3508 } 3509 DEBUG_WITH_TYPE( 3510 "mach-o-bind", 3511 dbgs() << "BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: " 3512 << "Ordinal=" << Ordinal << "\n"); 3513 break; 3514 case MachO::BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: 3515 if (TableKind == Kind::Weak) { 3516 *E = malformedError("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM not allowed in " 3517 "weak bind table for opcode at: 0x" + 3518 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3519 moveToEnd(); 3520 return; 3521 } 3522 if (ImmValue) { 3523 SignExtended = MachO::BIND_OPCODE_MASK | ImmValue; 3524 Ordinal = SignExtended; 3525 if (Ordinal < MachO::BIND_SPECIAL_DYLIB_FLAT_LOOKUP) { 3526 *E = malformedError("for BIND_OPCODE_SET_DYLIB_SPECIAL_IMM unknown " 3527 "special ordinal: " + 3528 Twine((int)Ordinal) + " for opcode at: 0x" + 3529 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3530 moveToEnd(); 3531 return; 3532 } 3533 } else 3534 Ordinal = 0; 3535 LibraryOrdinalSet = true; 3536 DEBUG_WITH_TYPE( 3537 "mach-o-bind", 3538 dbgs() << "BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: " 3539 << "Ordinal=" << Ordinal << "\n"); 3540 break; 3541 case MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: 3542 Flags = ImmValue; 3543 SymStart = Ptr; 3544 while (*Ptr && (Ptr < Opcodes.end())) { 3545 ++Ptr; 3546 } 3547 if (Ptr == Opcodes.end()) { 3548 *E = malformedError( 3549 "for BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM " 3550 "symbol name extends past opcodes for opcode at: 0x" + 3551 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3552 moveToEnd(); 3553 return; 3554 } 3555 SymbolName = StringRef(reinterpret_cast<const char*>(SymStart), 3556 Ptr-SymStart); 3557 ++Ptr; 3558 DEBUG_WITH_TYPE( 3559 "mach-o-bind", 3560 dbgs() << "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: " 3561 << "SymbolName=" << SymbolName << "\n"); 3562 if (TableKind == Kind::Weak) { 3563 if (ImmValue & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) 3564 return; 3565 } 3566 break; 3567 case MachO::BIND_OPCODE_SET_TYPE_IMM: 3568 BindType = ImmValue; 3569 if (ImmValue > MachO::BIND_TYPE_TEXT_PCREL32) { 3570 *E = malformedError("for BIND_OPCODE_SET_TYPE_IMM bad bind type: " + 3571 Twine((int)ImmValue) + " for opcode at: 0x" + 3572 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3573 moveToEnd(); 3574 return; 3575 } 3576 DEBUG_WITH_TYPE( 3577 "mach-o-bind", 3578 dbgs() << "BIND_OPCODE_SET_TYPE_IMM: " 3579 << "BindType=" << (int)BindType << "\n"); 3580 break; 3581 case MachO::BIND_OPCODE_SET_ADDEND_SLEB: 3582 Addend = readSLEB128(&error); 3583 if (error) { 3584 *E = malformedError("for BIND_OPCODE_SET_ADDEND_SLEB " + Twine(error) + 3585 " for opcode at: 0x" + 3586 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3587 moveToEnd(); 3588 return; 3589 } 3590 DEBUG_WITH_TYPE( 3591 "mach-o-bind", 3592 dbgs() << "BIND_OPCODE_SET_ADDEND_SLEB: " 3593 << "Addend=" << Addend << "\n"); 3594 break; 3595 case MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 3596 SegmentIndex = ImmValue; 3597 SegmentOffset = readULEB128(&error); 3598 if (error) { 3599 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3600 Twine(error) + " for opcode at: 0x" + 3601 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3602 moveToEnd(); 3603 return; 3604 } 3605 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3606 if (error) { 3607 *E = malformedError("for BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB " + 3608 Twine(error) + " for opcode at: 0x" + 3609 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3610 moveToEnd(); 3611 return; 3612 } 3613 DEBUG_WITH_TYPE( 3614 "mach-o-bind", 3615 dbgs() << "BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: " 3616 << "SegmentIndex=" << SegmentIndex << ", " 3617 << format("SegmentOffset=0x%06X", SegmentOffset) 3618 << "\n"); 3619 break; 3620 case MachO::BIND_OPCODE_ADD_ADDR_ULEB: 3621 SegmentOffset += readULEB128(&error); 3622 if (error) { 3623 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3624 " for opcode at: 0x" + 3625 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3626 moveToEnd(); 3627 return; 3628 } 3629 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3630 if (error) { 3631 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB " + Twine(error) + 3632 " for opcode at: 0x" + 3633 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3634 moveToEnd(); 3635 return; 3636 } 3637 DEBUG_WITH_TYPE("mach-o-bind", 3638 dbgs() << "BIND_OPCODE_ADD_ADDR_ULEB: " 3639 << format("SegmentOffset=0x%06X", 3640 SegmentOffset) << "\n"); 3641 break; 3642 case MachO::BIND_OPCODE_DO_BIND: 3643 AdvanceAmount = PointerSize; 3644 RemainingLoopCount = 0; 3645 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3646 if (error) { 3647 *E = malformedError("for BIND_OPCODE_DO_BIND " + Twine(error) + 3648 " for opcode at: 0x" + 3649 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3650 moveToEnd(); 3651 return; 3652 } 3653 if (SymbolName == StringRef()) { 3654 *E = malformedError( 3655 "for BIND_OPCODE_DO_BIND missing preceding " 3656 "BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode at: 0x" + 3657 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3658 moveToEnd(); 3659 return; 3660 } 3661 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3662 *E = 3663 malformedError("for BIND_OPCODE_DO_BIND missing preceding " 3664 "BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" + 3665 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3666 moveToEnd(); 3667 return; 3668 } 3669 DEBUG_WITH_TYPE("mach-o-bind", 3670 dbgs() << "BIND_OPCODE_DO_BIND: " 3671 << format("SegmentOffset=0x%06X", 3672 SegmentOffset) << "\n"); 3673 return; 3674 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: 3675 if (TableKind == Kind::Lazy) { 3676 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB not allowed in " 3677 "lazy bind table for opcode at: 0x" + 3678 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3679 moveToEnd(); 3680 return; 3681 } 3682 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3683 if (error) { 3684 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " + 3685 Twine(error) + " for opcode at: 0x" + 3686 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3687 moveToEnd(); 3688 return; 3689 } 3690 if (SymbolName == StringRef()) { 3691 *E = malformedError( 3692 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3693 "preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for opcode " 3694 "at: 0x" + 3695 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3696 moveToEnd(); 3697 return; 3698 } 3699 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3700 *E = malformedError( 3701 "for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB missing " 3702 "preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode at: 0x" + 3703 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3704 moveToEnd(); 3705 return; 3706 } 3707 AdvanceAmount = readULEB128(&error) + PointerSize; 3708 if (error) { 3709 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB " + 3710 Twine(error) + " for opcode at: 0x" + 3711 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3712 moveToEnd(); 3713 return; 3714 } 3715 // Note, this is not really an error until the next bind but make no sense 3716 // for a BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB to not be followed by another 3717 // bind operation. 3718 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset + 3719 AdvanceAmount, false); 3720 if (error) { 3721 *E = malformedError("for BIND_OPCODE_ADD_ADDR_ULEB (after adding " 3722 "ULEB) " + 3723 Twine(error) + " for opcode at: 0x" + 3724 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3725 moveToEnd(); 3726 return; 3727 } 3728 RemainingLoopCount = 0; 3729 DEBUG_WITH_TYPE( 3730 "mach-o-bind", 3731 dbgs() << "BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: " 3732 << format("SegmentOffset=0x%06X", SegmentOffset) 3733 << ", AdvanceAmount=" << AdvanceAmount 3734 << ", RemainingLoopCount=" << RemainingLoopCount 3735 << "\n"); 3736 return; 3737 case MachO::BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: 3738 if (TableKind == Kind::Lazy) { 3739 *E = malformedError("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED not " 3740 "allowed in lazy bind table for opcode at: 0x" + 3741 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3742 moveToEnd(); 3743 return; 3744 } 3745 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3746 if (error) { 3747 *E = malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " + 3748 Twine(error) + " for opcode at: 0x" + 3749 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3750 moveToEnd(); 3751 return; 3752 } 3753 if (SymbolName == StringRef()) { 3754 *E = malformedError( 3755 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3756 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3757 "opcode at: 0x" + 3758 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3759 moveToEnd(); 3760 return; 3761 } 3762 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3763 *E = malformedError( 3764 "for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3765 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3766 "at: 0x" + 3767 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3768 moveToEnd(); 3769 return; 3770 } 3771 AdvanceAmount = ImmValue * PointerSize + PointerSize; 3772 RemainingLoopCount = 0; 3773 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset + 3774 AdvanceAmount, false); 3775 if (error) { 3776 *E = 3777 malformedError("for BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED " 3778 " (after adding immediate times the pointer size) " + 3779 Twine(error) + " for opcode at: 0x" + 3780 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3781 moveToEnd(); 3782 return; 3783 } 3784 DEBUG_WITH_TYPE("mach-o-bind", 3785 dbgs() 3786 << "BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: " 3787 << format("SegmentOffset=0x%06X", SegmentOffset) << "\n"); 3788 return; 3789 case MachO::BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: 3790 if (TableKind == Kind::Lazy) { 3791 *E = malformedError("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB not " 3792 "allowed in lazy bind table for opcode at: 0x" + 3793 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3794 moveToEnd(); 3795 return; 3796 } 3797 Count = readULEB128(&error); 3798 if (Count != 0) 3799 RemainingLoopCount = Count - 1; 3800 else 3801 RemainingLoopCount = 0; 3802 if (error) { 3803 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3804 " (count value) " + 3805 Twine(error) + " for opcode at: 0x" + 3806 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3807 moveToEnd(); 3808 return; 3809 } 3810 Skip = readULEB128(&error); 3811 AdvanceAmount = Skip + PointerSize; 3812 if (error) { 3813 *E = malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3814 " (skip value) " + 3815 Twine(error) + " for opcode at: 0x" + 3816 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3817 moveToEnd(); 3818 return; 3819 } 3820 error = O->BindEntryCheckSegAndOffset(SegmentIndex, SegmentOffset, true); 3821 if (error) { 3822 *E = 3823 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " + 3824 Twine(error) + " for opcode at: 0x" + 3825 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3826 moveToEnd(); 3827 return; 3828 } 3829 if (SymbolName == StringRef()) { 3830 *E = malformedError( 3831 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3832 "missing preceding BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM for " 3833 "opcode at: 0x" + 3834 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3835 moveToEnd(); 3836 return; 3837 } 3838 if (!LibraryOrdinalSet && TableKind != Kind::Weak) { 3839 *E = malformedError( 3840 "for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " 3841 "missing preceding BIND_OPCODE_SET_DYLIB_ORDINAL_* for opcode " 3842 "at: 0x" + 3843 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3844 moveToEnd(); 3845 return; 3846 } 3847 error = O->BindEntryCheckCountAndSkip(Count, Skip, PointerSize, 3848 SegmentIndex, SegmentOffset); 3849 if (error) { 3850 *E = 3851 malformedError("for BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB " + 3852 Twine(error) + " for opcode at: 0x" + 3853 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3854 moveToEnd(); 3855 return; 3856 } 3857 DEBUG_WITH_TYPE( 3858 "mach-o-bind", 3859 dbgs() << "BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: " 3860 << format("SegmentOffset=0x%06X", SegmentOffset) 3861 << ", AdvanceAmount=" << AdvanceAmount 3862 << ", RemainingLoopCount=" << RemainingLoopCount 3863 << "\n"); 3864 return; 3865 default: 3866 *E = malformedError("bad bind info (bad opcode value 0x" + 3867 Twine::utohexstr(Opcode) + " for opcode at: 0x" + 3868 Twine::utohexstr(OpcodeStart - Opcodes.begin())); 3869 moveToEnd(); 3870 return; 3871 } 3872 } 3873 } 3874 3875 uint64_t MachOBindEntry::readULEB128(const char **error) { 3876 unsigned Count; 3877 uint64_t Result = decodeULEB128(Ptr, &Count, Opcodes.end(), error); 3878 Ptr += Count; 3879 if (Ptr > Opcodes.end()) 3880 Ptr = Opcodes.end(); 3881 return Result; 3882 } 3883 3884 int64_t MachOBindEntry::readSLEB128(const char **error) { 3885 unsigned Count; 3886 int64_t Result = decodeSLEB128(Ptr, &Count, Opcodes.end(), error); 3887 Ptr += Count; 3888 if (Ptr > Opcodes.end()) 3889 Ptr = Opcodes.end(); 3890 return Result; 3891 } 3892 3893 int32_t MachOBindEntry::segmentIndex() const { return SegmentIndex; } 3894 3895 uint64_t MachOBindEntry::segmentOffset() const { return SegmentOffset; } 3896 3897 StringRef MachOBindEntry::typeName() const { 3898 switch (BindType) { 3899 case MachO::BIND_TYPE_POINTER: 3900 return "pointer"; 3901 case MachO::BIND_TYPE_TEXT_ABSOLUTE32: 3902 return "text abs32"; 3903 case MachO::BIND_TYPE_TEXT_PCREL32: 3904 return "text rel32"; 3905 } 3906 return "unknown"; 3907 } 3908 3909 StringRef MachOBindEntry::symbolName() const { return SymbolName; } 3910 3911 int64_t MachOBindEntry::addend() const { return Addend; } 3912 3913 uint32_t MachOBindEntry::flags() const { return Flags; } 3914 3915 int MachOBindEntry::ordinal() const { return Ordinal; } 3916 3917 // For use with the SegIndex of a checked Mach-O Bind entry 3918 // to get the segment name. 3919 StringRef MachOBindEntry::segmentName() const { 3920 return O->BindRebaseSegmentName(SegmentIndex); 3921 } 3922 3923 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 3924 // to get the section name. 3925 StringRef MachOBindEntry::sectionName() const { 3926 return O->BindRebaseSectionName(SegmentIndex, SegmentOffset); 3927 } 3928 3929 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind entry 3930 // to get the address. 3931 uint64_t MachOBindEntry::address() const { 3932 return O->BindRebaseAddress(SegmentIndex, SegmentOffset); 3933 } 3934 3935 bool MachOBindEntry::operator==(const MachOBindEntry &Other) const { 3936 #ifdef EXPENSIVE_CHECKS 3937 assert(Opcodes == Other.Opcodes && "compare iterators of different files"); 3938 #else 3939 assert(Opcodes.data() == Other.Opcodes.data() && "compare iterators of different files"); 3940 #endif 3941 return (Ptr == Other.Ptr) && 3942 (RemainingLoopCount == Other.RemainingLoopCount) && 3943 (Done == Other.Done); 3944 } 3945 3946 // Build table of sections so SegIndex/SegOffset pairs can be translated. 3947 BindRebaseSegInfo::BindRebaseSegInfo(const object::MachOObjectFile *Obj) { 3948 uint32_t CurSegIndex = Obj->hasPageZeroSegment() ? 1 : 0; 3949 StringRef CurSegName; 3950 uint64_t CurSegAddress; 3951 for (const SectionRef &Section : Obj->sections()) { 3952 SectionInfo Info; 3953 Section.getName(Info.SectionName); 3954 Info.Address = Section.getAddress(); 3955 Info.Size = Section.getSize(); 3956 Info.SegmentName = 3957 Obj->getSectionFinalSegmentName(Section.getRawDataRefImpl()); 3958 if (!Info.SegmentName.equals(CurSegName)) { 3959 ++CurSegIndex; 3960 CurSegName = Info.SegmentName; 3961 CurSegAddress = Info.Address; 3962 } 3963 Info.SegmentIndex = CurSegIndex - 1; 3964 Info.OffsetInSegment = Info.Address - CurSegAddress; 3965 Info.SegmentStartAddress = CurSegAddress; 3966 Sections.push_back(Info); 3967 } 3968 MaxSegIndex = CurSegIndex; 3969 } 3970 3971 // For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to 3972 // validate a MachOBindEntry or MachORebaseEntry. 3973 const char * BindRebaseSegInfo::checkSegAndOffset(int32_t SegIndex, 3974 uint64_t SegOffset, 3975 bool endInvalid) { 3976 if (SegIndex == -1) 3977 return "missing preceding *_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB"; 3978 if (SegIndex >= MaxSegIndex) 3979 return "bad segIndex (too large)"; 3980 for (const SectionInfo &SI : Sections) { 3981 if (SI.SegmentIndex != SegIndex) 3982 continue; 3983 if (SI.OffsetInSegment > SegOffset) 3984 continue; 3985 if (SegOffset > (SI.OffsetInSegment + SI.Size)) 3986 continue; 3987 if (endInvalid && SegOffset >= (SI.OffsetInSegment + SI.Size)) 3988 continue; 3989 return nullptr; 3990 } 3991 return "bad segOffset, too large"; 3992 } 3993 3994 // For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for 3995 // the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode and for use in 3996 // MachORebaseEntry::moveNext() to validate a MachORebaseEntry for 3997 // REBASE_OPCODE_DO_*_TIMES* opcodes. The SegIndex and SegOffset must have 3998 // been already checked. 3999 const char * BindRebaseSegInfo::checkCountAndSkip(uint32_t Count, uint32_t Skip, 4000 uint8_t PointerSize, 4001 int32_t SegIndex, 4002 uint64_t SegOffset) { 4003 const SectionInfo &SI = findSection(SegIndex, SegOffset); 4004 uint64_t addr = SI.SegmentStartAddress + SegOffset; 4005 if (addr >= SI.Address + SI.Size) 4006 return "bad segOffset, too large"; 4007 uint64_t i = 0; 4008 if (Count > 1) 4009 i = (Skip + PointerSize) * (Count - 1); 4010 else if (Count == 1) 4011 i = Skip + PointerSize; 4012 if (addr + i >= SI.Address + SI.Size) { 4013 // For rebase opcodes they can step from one section to another. 4014 uint64_t TrailingSegOffset = (addr + i) - SI.SegmentStartAddress; 4015 const char *error = checkSegAndOffset(SegIndex, TrailingSegOffset, false); 4016 if (error) 4017 return "bad count and skip, too large"; 4018 } 4019 return nullptr; 4020 } 4021 4022 // For use with the SegIndex of a checked Mach-O Bind or Rebase entry 4023 // to get the segment name. 4024 StringRef BindRebaseSegInfo::segmentName(int32_t SegIndex) { 4025 for (const SectionInfo &SI : Sections) { 4026 if (SI.SegmentIndex == SegIndex) 4027 return SI.SegmentName; 4028 } 4029 llvm_unreachable("invalid SegIndex"); 4030 } 4031 4032 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4033 // to get the SectionInfo. 4034 const BindRebaseSegInfo::SectionInfo &BindRebaseSegInfo::findSection( 4035 int32_t SegIndex, uint64_t SegOffset) { 4036 for (const SectionInfo &SI : Sections) { 4037 if (SI.SegmentIndex != SegIndex) 4038 continue; 4039 if (SI.OffsetInSegment > SegOffset) 4040 continue; 4041 if (SegOffset >= (SI.OffsetInSegment + SI.Size)) 4042 continue; 4043 return SI; 4044 } 4045 llvm_unreachable("SegIndex and SegOffset not in any section"); 4046 } 4047 4048 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4049 // entry to get the section name. 4050 StringRef BindRebaseSegInfo::sectionName(int32_t SegIndex, 4051 uint64_t SegOffset) { 4052 return findSection(SegIndex, SegOffset).SectionName; 4053 } 4054 4055 // For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or Rebase 4056 // entry to get the address. 4057 uint64_t BindRebaseSegInfo::address(uint32_t SegIndex, uint64_t OffsetInSeg) { 4058 const SectionInfo &SI = findSection(SegIndex, OffsetInSeg); 4059 return SI.SegmentStartAddress + OffsetInSeg; 4060 } 4061 4062 iterator_range<bind_iterator> 4063 MachOObjectFile::bindTable(Error &Err, MachOObjectFile *O, 4064 ArrayRef<uint8_t> Opcodes, bool is64, 4065 MachOBindEntry::Kind BKind) { 4066 if (O->BindRebaseSectionTable == nullptr) 4067 O->BindRebaseSectionTable = llvm::make_unique<BindRebaseSegInfo>(O); 4068 MachOBindEntry Start(&Err, O, Opcodes, is64, BKind); 4069 Start.moveToFirst(); 4070 4071 MachOBindEntry Finish(&Err, O, Opcodes, is64, BKind); 4072 Finish.moveToEnd(); 4073 4074 return make_range(bind_iterator(Start), bind_iterator(Finish)); 4075 } 4076 4077 iterator_range<bind_iterator> MachOObjectFile::bindTable(Error &Err) { 4078 return bindTable(Err, this, getDyldInfoBindOpcodes(), is64Bit(), 4079 MachOBindEntry::Kind::Regular); 4080 } 4081 4082 iterator_range<bind_iterator> MachOObjectFile::lazyBindTable(Error &Err) { 4083 return bindTable(Err, this, getDyldInfoLazyBindOpcodes(), is64Bit(), 4084 MachOBindEntry::Kind::Lazy); 4085 } 4086 4087 iterator_range<bind_iterator> MachOObjectFile::weakBindTable(Error &Err) { 4088 return bindTable(Err, this, getDyldInfoWeakBindOpcodes(), is64Bit(), 4089 MachOBindEntry::Kind::Weak); 4090 } 4091 4092 MachOObjectFile::load_command_iterator 4093 MachOObjectFile::begin_load_commands() const { 4094 return LoadCommands.begin(); 4095 } 4096 4097 MachOObjectFile::load_command_iterator 4098 MachOObjectFile::end_load_commands() const { 4099 return LoadCommands.end(); 4100 } 4101 4102 iterator_range<MachOObjectFile::load_command_iterator> 4103 MachOObjectFile::load_commands() const { 4104 return make_range(begin_load_commands(), end_load_commands()); 4105 } 4106 4107 StringRef 4108 MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { 4109 ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); 4110 return parseSegmentOrSectionName(Raw.data()); 4111 } 4112 4113 ArrayRef<char> 4114 MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { 4115 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 4116 const section_base *Base = 4117 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 4118 return makeArrayRef(Base->sectname); 4119 } 4120 4121 ArrayRef<char> 4122 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { 4123 assert(Sec.d.a < Sections.size() && "Should have detected this earlier"); 4124 const section_base *Base = 4125 reinterpret_cast<const section_base *>(Sections[Sec.d.a]); 4126 return makeArrayRef(Base->segname); 4127 } 4128 4129 bool 4130 MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) 4131 const { 4132 if (getCPUType(*this) == MachO::CPU_TYPE_X86_64) 4133 return false; 4134 return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; 4135 } 4136 4137 unsigned MachOObjectFile::getPlainRelocationSymbolNum( 4138 const MachO::any_relocation_info &RE) const { 4139 if (isLittleEndian()) 4140 return RE.r_word1 & 0xffffff; 4141 return RE.r_word1 >> 8; 4142 } 4143 4144 bool MachOObjectFile::getPlainRelocationExternal( 4145 const MachO::any_relocation_info &RE) const { 4146 if (isLittleEndian()) 4147 return (RE.r_word1 >> 27) & 1; 4148 return (RE.r_word1 >> 4) & 1; 4149 } 4150 4151 bool MachOObjectFile::getScatteredRelocationScattered( 4152 const MachO::any_relocation_info &RE) const { 4153 return RE.r_word0 >> 31; 4154 } 4155 4156 uint32_t MachOObjectFile::getScatteredRelocationValue( 4157 const MachO::any_relocation_info &RE) const { 4158 return RE.r_word1; 4159 } 4160 4161 uint32_t MachOObjectFile::getScatteredRelocationType( 4162 const MachO::any_relocation_info &RE) const { 4163 return (RE.r_word0 >> 24) & 0xf; 4164 } 4165 4166 unsigned MachOObjectFile::getAnyRelocationAddress( 4167 const MachO::any_relocation_info &RE) const { 4168 if (isRelocationScattered(RE)) 4169 return getScatteredRelocationAddress(RE); 4170 return getPlainRelocationAddress(RE); 4171 } 4172 4173 unsigned MachOObjectFile::getAnyRelocationPCRel( 4174 const MachO::any_relocation_info &RE) const { 4175 if (isRelocationScattered(RE)) 4176 return getScatteredRelocationPCRel(RE); 4177 return getPlainRelocationPCRel(*this, RE); 4178 } 4179 4180 unsigned MachOObjectFile::getAnyRelocationLength( 4181 const MachO::any_relocation_info &RE) const { 4182 if (isRelocationScattered(RE)) 4183 return getScatteredRelocationLength(RE); 4184 return getPlainRelocationLength(*this, RE); 4185 } 4186 4187 unsigned 4188 MachOObjectFile::getAnyRelocationType( 4189 const MachO::any_relocation_info &RE) const { 4190 if (isRelocationScattered(RE)) 4191 return getScatteredRelocationType(RE); 4192 return getPlainRelocationType(*this, RE); 4193 } 4194 4195 SectionRef 4196 MachOObjectFile::getAnyRelocationSection( 4197 const MachO::any_relocation_info &RE) const { 4198 if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) 4199 return *section_end(); 4200 unsigned SecNum = getPlainRelocationSymbolNum(RE); 4201 if (SecNum == MachO::R_ABS || SecNum > Sections.size()) 4202 return *section_end(); 4203 DataRefImpl DRI; 4204 DRI.d.a = SecNum - 1; 4205 return SectionRef(DRI, this); 4206 } 4207 4208 MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { 4209 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 4210 return getStruct<MachO::section>(*this, Sections[DRI.d.a]); 4211 } 4212 4213 MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { 4214 assert(DRI.d.a < Sections.size() && "Should have detected this earlier"); 4215 return getStruct<MachO::section_64>(*this, Sections[DRI.d.a]); 4216 } 4217 4218 MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, 4219 unsigned Index) const { 4220 const char *Sec = getSectionPtr(*this, L, Index); 4221 return getStruct<MachO::section>(*this, Sec); 4222 } 4223 4224 MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, 4225 unsigned Index) const { 4226 const char *Sec = getSectionPtr(*this, L, Index); 4227 return getStruct<MachO::section_64>(*this, Sec); 4228 } 4229 4230 MachO::nlist 4231 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { 4232 const char *P = reinterpret_cast<const char *>(DRI.p); 4233 return getStruct<MachO::nlist>(*this, P); 4234 } 4235 4236 MachO::nlist_64 4237 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { 4238 const char *P = reinterpret_cast<const char *>(DRI.p); 4239 return getStruct<MachO::nlist_64>(*this, P); 4240 } 4241 4242 MachO::linkedit_data_command 4243 MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { 4244 return getStruct<MachO::linkedit_data_command>(*this, L.Ptr); 4245 } 4246 4247 MachO::segment_command 4248 MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { 4249 return getStruct<MachO::segment_command>(*this, L.Ptr); 4250 } 4251 4252 MachO::segment_command_64 4253 MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { 4254 return getStruct<MachO::segment_command_64>(*this, L.Ptr); 4255 } 4256 4257 MachO::linker_option_command 4258 MachOObjectFile::getLinkerOptionLoadCommand(const LoadCommandInfo &L) const { 4259 return getStruct<MachO::linker_option_command>(*this, L.Ptr); 4260 } 4261 4262 MachO::version_min_command 4263 MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const { 4264 return getStruct<MachO::version_min_command>(*this, L.Ptr); 4265 } 4266 4267 MachO::note_command 4268 MachOObjectFile::getNoteLoadCommand(const LoadCommandInfo &L) const { 4269 return getStruct<MachO::note_command>(*this, L.Ptr); 4270 } 4271 4272 MachO::build_version_command 4273 MachOObjectFile::getBuildVersionLoadCommand(const LoadCommandInfo &L) const { 4274 return getStruct<MachO::build_version_command>(*this, L.Ptr); 4275 } 4276 4277 MachO::build_tool_version 4278 MachOObjectFile::getBuildToolVersion(unsigned index) const { 4279 return getStruct<MachO::build_tool_version>(*this, BuildTools[index]); 4280 } 4281 4282 MachO::dylib_command 4283 MachOObjectFile::getDylibIDLoadCommand(const LoadCommandInfo &L) const { 4284 return getStruct<MachO::dylib_command>(*this, L.Ptr); 4285 } 4286 4287 MachO::dyld_info_command 4288 MachOObjectFile::getDyldInfoLoadCommand(const LoadCommandInfo &L) const { 4289 return getStruct<MachO::dyld_info_command>(*this, L.Ptr); 4290 } 4291 4292 MachO::dylinker_command 4293 MachOObjectFile::getDylinkerCommand(const LoadCommandInfo &L) const { 4294 return getStruct<MachO::dylinker_command>(*this, L.Ptr); 4295 } 4296 4297 MachO::uuid_command 4298 MachOObjectFile::getUuidCommand(const LoadCommandInfo &L) const { 4299 return getStruct<MachO::uuid_command>(*this, L.Ptr); 4300 } 4301 4302 MachO::rpath_command 4303 MachOObjectFile::getRpathCommand(const LoadCommandInfo &L) const { 4304 return getStruct<MachO::rpath_command>(*this, L.Ptr); 4305 } 4306 4307 MachO::source_version_command 4308 MachOObjectFile::getSourceVersionCommand(const LoadCommandInfo &L) const { 4309 return getStruct<MachO::source_version_command>(*this, L.Ptr); 4310 } 4311 4312 MachO::entry_point_command 4313 MachOObjectFile::getEntryPointCommand(const LoadCommandInfo &L) const { 4314 return getStruct<MachO::entry_point_command>(*this, L.Ptr); 4315 } 4316 4317 MachO::encryption_info_command 4318 MachOObjectFile::getEncryptionInfoCommand(const LoadCommandInfo &L) const { 4319 return getStruct<MachO::encryption_info_command>(*this, L.Ptr); 4320 } 4321 4322 MachO::encryption_info_command_64 4323 MachOObjectFile::getEncryptionInfoCommand64(const LoadCommandInfo &L) const { 4324 return getStruct<MachO::encryption_info_command_64>(*this, L.Ptr); 4325 } 4326 4327 MachO::sub_framework_command 4328 MachOObjectFile::getSubFrameworkCommand(const LoadCommandInfo &L) const { 4329 return getStruct<MachO::sub_framework_command>(*this, L.Ptr); 4330 } 4331 4332 MachO::sub_umbrella_command 4333 MachOObjectFile::getSubUmbrellaCommand(const LoadCommandInfo &L) const { 4334 return getStruct<MachO::sub_umbrella_command>(*this, L.Ptr); 4335 } 4336 4337 MachO::sub_library_command 4338 MachOObjectFile::getSubLibraryCommand(const LoadCommandInfo &L) const { 4339 return getStruct<MachO::sub_library_command>(*this, L.Ptr); 4340 } 4341 4342 MachO::sub_client_command 4343 MachOObjectFile::getSubClientCommand(const LoadCommandInfo &L) const { 4344 return getStruct<MachO::sub_client_command>(*this, L.Ptr); 4345 } 4346 4347 MachO::routines_command 4348 MachOObjectFile::getRoutinesCommand(const LoadCommandInfo &L) const { 4349 return getStruct<MachO::routines_command>(*this, L.Ptr); 4350 } 4351 4352 MachO::routines_command_64 4353 MachOObjectFile::getRoutinesCommand64(const LoadCommandInfo &L) const { 4354 return getStruct<MachO::routines_command_64>(*this, L.Ptr); 4355 } 4356 4357 MachO::thread_command 4358 MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { 4359 return getStruct<MachO::thread_command>(*this, L.Ptr); 4360 } 4361 4362 MachO::any_relocation_info 4363 MachOObjectFile::getRelocation(DataRefImpl Rel) const { 4364 uint32_t Offset; 4365 if (getHeader().filetype == MachO::MH_OBJECT) { 4366 DataRefImpl Sec; 4367 Sec.d.a = Rel.d.a; 4368 if (is64Bit()) { 4369 MachO::section_64 Sect = getSection64(Sec); 4370 Offset = Sect.reloff; 4371 } else { 4372 MachO::section Sect = getSection(Sec); 4373 Offset = Sect.reloff; 4374 } 4375 } else { 4376 MachO::dysymtab_command DysymtabLoadCmd = getDysymtabLoadCommand(); 4377 if (Rel.d.a == 0) 4378 Offset = DysymtabLoadCmd.extreloff; // Offset to the external relocations 4379 else 4380 Offset = DysymtabLoadCmd.locreloff; // Offset to the local relocations 4381 } 4382 4383 auto P = reinterpret_cast<const MachO::any_relocation_info *>( 4384 getPtr(*this, Offset)) + Rel.d.b; 4385 return getStruct<MachO::any_relocation_info>( 4386 *this, reinterpret_cast<const char *>(P)); 4387 } 4388 4389 MachO::data_in_code_entry 4390 MachOObjectFile::getDice(DataRefImpl Rel) const { 4391 const char *P = reinterpret_cast<const char *>(Rel.p); 4392 return getStruct<MachO::data_in_code_entry>(*this, P); 4393 } 4394 4395 const MachO::mach_header &MachOObjectFile::getHeader() const { 4396 return Header; 4397 } 4398 4399 const MachO::mach_header_64 &MachOObjectFile::getHeader64() const { 4400 assert(is64Bit()); 4401 return Header64; 4402 } 4403 4404 uint32_t MachOObjectFile::getIndirectSymbolTableEntry( 4405 const MachO::dysymtab_command &DLC, 4406 unsigned Index) const { 4407 uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); 4408 return getStruct<uint32_t>(*this, getPtr(*this, Offset)); 4409 } 4410 4411 MachO::data_in_code_entry 4412 MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, 4413 unsigned Index) const { 4414 uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); 4415 return getStruct<MachO::data_in_code_entry>(*this, getPtr(*this, Offset)); 4416 } 4417 4418 MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { 4419 if (SymtabLoadCmd) 4420 return getStruct<MachO::symtab_command>(*this, SymtabLoadCmd); 4421 4422 // If there is no SymtabLoadCmd return a load command with zero'ed fields. 4423 MachO::symtab_command Cmd; 4424 Cmd.cmd = MachO::LC_SYMTAB; 4425 Cmd.cmdsize = sizeof(MachO::symtab_command); 4426 Cmd.symoff = 0; 4427 Cmd.nsyms = 0; 4428 Cmd.stroff = 0; 4429 Cmd.strsize = 0; 4430 return Cmd; 4431 } 4432 4433 MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { 4434 if (DysymtabLoadCmd) 4435 return getStruct<MachO::dysymtab_command>(*this, DysymtabLoadCmd); 4436 4437 // If there is no DysymtabLoadCmd return a load command with zero'ed fields. 4438 MachO::dysymtab_command Cmd; 4439 Cmd.cmd = MachO::LC_DYSYMTAB; 4440 Cmd.cmdsize = sizeof(MachO::dysymtab_command); 4441 Cmd.ilocalsym = 0; 4442 Cmd.nlocalsym = 0; 4443 Cmd.iextdefsym = 0; 4444 Cmd.nextdefsym = 0; 4445 Cmd.iundefsym = 0; 4446 Cmd.nundefsym = 0; 4447 Cmd.tocoff = 0; 4448 Cmd.ntoc = 0; 4449 Cmd.modtaboff = 0; 4450 Cmd.nmodtab = 0; 4451 Cmd.extrefsymoff = 0; 4452 Cmd.nextrefsyms = 0; 4453 Cmd.indirectsymoff = 0; 4454 Cmd.nindirectsyms = 0; 4455 Cmd.extreloff = 0; 4456 Cmd.nextrel = 0; 4457 Cmd.locreloff = 0; 4458 Cmd.nlocrel = 0; 4459 return Cmd; 4460 } 4461 4462 MachO::linkedit_data_command 4463 MachOObjectFile::getDataInCodeLoadCommand() const { 4464 if (DataInCodeLoadCmd) 4465 return getStruct<MachO::linkedit_data_command>(*this, DataInCodeLoadCmd); 4466 4467 // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. 4468 MachO::linkedit_data_command Cmd; 4469 Cmd.cmd = MachO::LC_DATA_IN_CODE; 4470 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 4471 Cmd.dataoff = 0; 4472 Cmd.datasize = 0; 4473 return Cmd; 4474 } 4475 4476 MachO::linkedit_data_command 4477 MachOObjectFile::getLinkOptHintsLoadCommand() const { 4478 if (LinkOptHintsLoadCmd) 4479 return getStruct<MachO::linkedit_data_command>(*this, LinkOptHintsLoadCmd); 4480 4481 // If there is no LinkOptHintsLoadCmd return a load command with zero'ed 4482 // fields. 4483 MachO::linkedit_data_command Cmd; 4484 Cmd.cmd = MachO::LC_LINKER_OPTIMIZATION_HINT; 4485 Cmd.cmdsize = sizeof(MachO::linkedit_data_command); 4486 Cmd.dataoff = 0; 4487 Cmd.datasize = 0; 4488 return Cmd; 4489 } 4490 4491 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoRebaseOpcodes() const { 4492 if (!DyldInfoLoadCmd) 4493 return None; 4494 4495 MachO::dyld_info_command DyldInfo = 4496 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4497 const uint8_t *Ptr = 4498 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.rebase_off)); 4499 return makeArrayRef(Ptr, DyldInfo.rebase_size); 4500 } 4501 4502 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoBindOpcodes() const { 4503 if (!DyldInfoLoadCmd) 4504 return None; 4505 4506 MachO::dyld_info_command DyldInfo = 4507 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4508 const uint8_t *Ptr = 4509 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.bind_off)); 4510 return makeArrayRef(Ptr, DyldInfo.bind_size); 4511 } 4512 4513 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoWeakBindOpcodes() const { 4514 if (!DyldInfoLoadCmd) 4515 return None; 4516 4517 MachO::dyld_info_command DyldInfo = 4518 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4519 const uint8_t *Ptr = 4520 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.weak_bind_off)); 4521 return makeArrayRef(Ptr, DyldInfo.weak_bind_size); 4522 } 4523 4524 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoLazyBindOpcodes() const { 4525 if (!DyldInfoLoadCmd) 4526 return None; 4527 4528 MachO::dyld_info_command DyldInfo = 4529 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4530 const uint8_t *Ptr = 4531 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.lazy_bind_off)); 4532 return makeArrayRef(Ptr, DyldInfo.lazy_bind_size); 4533 } 4534 4535 ArrayRef<uint8_t> MachOObjectFile::getDyldInfoExportsTrie() const { 4536 if (!DyldInfoLoadCmd) 4537 return None; 4538 4539 MachO::dyld_info_command DyldInfo = 4540 getStruct<MachO::dyld_info_command>(*this, DyldInfoLoadCmd); 4541 const uint8_t *Ptr = 4542 reinterpret_cast<const uint8_t *>(getPtr(*this, DyldInfo.export_off)); 4543 return makeArrayRef(Ptr, DyldInfo.export_size); 4544 } 4545 4546 ArrayRef<uint8_t> MachOObjectFile::getUuid() const { 4547 if (!UuidLoadCmd) 4548 return None; 4549 // Returning a pointer is fine as uuid doesn't need endian swapping. 4550 const char *Ptr = UuidLoadCmd + offsetof(MachO::uuid_command, uuid); 4551 return makeArrayRef(reinterpret_cast<const uint8_t *>(Ptr), 16); 4552 } 4553 4554 StringRef MachOObjectFile::getStringTableData() const { 4555 MachO::symtab_command S = getSymtabLoadCommand(); 4556 return getData().substr(S.stroff, S.strsize); 4557 } 4558 4559 bool MachOObjectFile::is64Bit() const { 4560 return getType() == getMachOType(false, true) || 4561 getType() == getMachOType(true, true); 4562 } 4563 4564 void MachOObjectFile::ReadULEB128s(uint64_t Index, 4565 SmallVectorImpl<uint64_t> &Out) const { 4566 DataExtractor extractor(ObjectFile::getData(), true, 0); 4567 4568 uint32_t offset = Index; 4569 uint64_t data = 0; 4570 while (uint64_t delta = extractor.getULEB128(&offset)) { 4571 data += delta; 4572 Out.push_back(data); 4573 } 4574 } 4575 4576 bool MachOObjectFile::isRelocatableObject() const { 4577 return getHeader().filetype == MachO::MH_OBJECT; 4578 } 4579 4580 Expected<std::unique_ptr<MachOObjectFile>> 4581 ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer, 4582 uint32_t UniversalCputype, 4583 uint32_t UniversalIndex) { 4584 StringRef Magic = Buffer.getBuffer().slice(0, 4); 4585 if (Magic == "\xFE\xED\xFA\xCE") 4586 return MachOObjectFile::create(Buffer, false, false, 4587 UniversalCputype, UniversalIndex); 4588 if (Magic == "\xCE\xFA\xED\xFE") 4589 return MachOObjectFile::create(Buffer, true, false, 4590 UniversalCputype, UniversalIndex); 4591 if (Magic == "\xFE\xED\xFA\xCF") 4592 return MachOObjectFile::create(Buffer, false, true, 4593 UniversalCputype, UniversalIndex); 4594 if (Magic == "\xCF\xFA\xED\xFE") 4595 return MachOObjectFile::create(Buffer, true, true, 4596 UniversalCputype, UniversalIndex); 4597 return make_error<GenericBinaryError>("Unrecognized MachO magic number", 4598 object_error::invalid_file_type); 4599 } 4600 4601 StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const { 4602 return StringSwitch<StringRef>(Name) 4603 .Case("debug_str_offs", "debug_str_offsets") 4604 .Default(Name); 4605 } 4606