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