llvm.org GIT mirror llvm / f6cfc15
Convert MachOObjectFile to a template. For now it is templated only on being 64 or 32 bits. I will add little/big endian next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179097 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
6 changed file(s) with 919 addition(s) and 963 deletion(s). Raw diff Collapse all Expand all
1616
1717 #include "llvm/ADT/ArrayRef.h"
1818 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/Triple.h"
1920 #include "llvm/Object/MachOObject.h"
2021 #include "llvm/Object/ObjectFile.h"
2122 #include "llvm/Support/Endian.h"
163164 };
164165 }
165166
166 class MachOObjectFile : public ObjectFile {
167 class MachOObjectFileBase : public ObjectFile {
167168 public:
168 MachOObjectFile(MemoryBuffer *Object, bool Is64bits, error_code &ec);
169 typedef MachOFormat::SymbolTableEntryBase SymbolTableEntryBase;
170 typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand;
171 typedef MachOFormat::RelocationEntry RelocationEntry;
172 typedef MachOFormat::SectionBase SectionBase;
173 typedef MachOFormat::LoadCommand LoadCommand;
174 typedef MachOFormat::Header Header;
175
176 MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
169177
170178 virtual symbol_iterator begin_symbols() const;
171179 virtual symbol_iterator end_symbols() const;
173181 virtual symbol_iterator end_dynamic_symbols() const;
174182 virtual library_iterator begin_libraries_needed() const;
175183 virtual library_iterator end_libraries_needed() const;
176 virtual section_iterator begin_sections() const;
177184 virtual section_iterator end_sections() const;
178185
179186 virtual uint8_t getBytesInAddress() const;
191198 ArrayRef getSectionRawName(DataRefImpl Sec) const;
192199 ArrayRefgetSectionRawFinalSegmentName(DataRefImpl Sec) const;
193200
194 const MachOFormat::Section *getSection64(DataRefImpl DRI) const;
195 const MachOFormat::Section *getSection(DataRefImpl DRI) const;
196 const MachOFormat::SymbolTableEntry *
197 getSymbol64TableEntry(DataRefImpl DRI) const;
198 const MachOFormat::SymbolTableEntry *
199 getSymbolTableEntry(DataRefImpl DRI) const;
200201 bool is64Bit() const;
201 const MachOFormat::LoadCommand *getLoadCommandInfo(unsigned Index) const;
202 const LoadCommand *getLoadCommandInfo(unsigned Index) const;
202203 void ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const;
203 const MachOFormat::Header *getHeader() const;
204 const Header *getHeader() const;
204205 unsigned getHeaderSize() const;
205206 StringRef getData(size_t Offset, size_t Size) const;
206207
211212 protected:
212213 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
213214 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
214 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
215 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
216 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
217215 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
218216 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
219217 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
220218 virtual error_code getSymbolSection(DataRefImpl Symb,
221219 section_iterator &Res) const;
222220 virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
223
224 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
225221 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
222 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
223 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
224 virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
225 bool &Res) const;
226 virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
227 virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
228 virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
229
230 virtual error_code getRelocationNext(DataRefImpl Rel,
231 RelocationRef &Res) const;
232
233 virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
234 virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
235
236 std::size_t getSectionIndex(DataRefImpl Sec) const;
237
238 typedef SmallVector SectionList;
239 SectionList Sections;
240
241 void moveToNextSymbol(DataRefImpl &DRI) const;
242 void printRelocationTargetName(const RelocationEntry *RE,
243 raw_string_ostream &fmt) const;
244 const SectionBase *getSectionBase(DataRefImpl DRI) const;
245 const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI) const;
246
247 private:
248
249 const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI,
250 const SymtabLoadCommand *SymtabLoadCmd) const;
251 };
252
253 template
254 struct MachOObjectFileHelperCommon {
255 typedef MachOFormat::SegmentLoadCommand SegmentLoadCommand;
256 typedef MachOFormat::SymbolTableEntry SymbolTableEntry;
257 typedef MachOFormat::Section Section;
258 };
259
260 template
261 struct MachOObjectFileHelper;
262
263 template<>
264 struct MachOObjectFileHelper :
265 public MachOObjectFileHelperCommon {
266 static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment;
267 };
268
269 template<>
270 struct MachOObjectFileHelper :
271 public MachOObjectFileHelperCommon {
272 static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment64;
273 };
274
275 template
276 class MachOObjectFile : public MachOObjectFileBase {
277 public:
278 static const macho::LoadCommandType SegmentLoadType =
279 MachOObjectFileHelper::SegmentLoadType;
280 typedef typename MachOObjectFileHelper::SegmentLoadCommand
281 SegmentLoadCommand;
282 typedef typename MachOObjectFileHelper::SymbolTableEntry
283 SymbolTableEntry;
284 typedef typename MachOObjectFileHelper::Section Section;
285
286 MachOObjectFile(MemoryBuffer *Object, error_code &ec) :
287 MachOObjectFileBase(Object, is64Bits, ec) {
288 DataRefImpl DRI;
289 moveToNextSection(DRI);
290 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
291 while (DRI.d.a < LoadCommandCount) {
292 Sections.push_back(DRI);
293 DRI.d.b++;
294 moveToNextSection(DRI);
295 }
296 }
297
298 static inline bool classof(const Binary *v) {
299 return v->getType() == getMachOType(true, is64Bits);
300 }
301
302 const Section *getSection(DataRefImpl DRI) const;
303 const SymbolTableEntry *getSymbolTableEntry(DataRefImpl DRI) const;
304 const RelocationEntry *getRelocation(DataRefImpl Rel) const;
305
226306 virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
227307 virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
228308 virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
229309 virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
230310 virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
231 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
232 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
233 virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
234 bool &Res) const;
235 virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
236311 virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
237 virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
238 virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S,
239 bool &Result) const;
240 virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
241312 virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
242
243 virtual error_code getRelocationNext(DataRefImpl Rel,
244 RelocationRef &Res) const;
245 virtual error_code getRelocationAddress(DataRefImpl Rel,
246 uint64_t &Res) const;
247 virtual error_code getRelocationOffset(DataRefImpl Rel,
248 uint64_t &Res) const;
249 virtual error_code getRelocationSymbol(DataRefImpl Rel,
250 SymbolRef &Res) const;
251 virtual error_code getRelocationType(DataRefImpl Rel,
252 uint64_t &Res) const;
313 virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
314 virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
315 virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
316 virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
317 int64_t &Res) const;
318 virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
253319 virtual error_code getRelocationTypeName(DataRefImpl Rel,
254320 SmallVectorImpl &Result) const;
255 virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
256 int64_t &Res) const;
257321 virtual error_code getRelocationValueString(DataRefImpl Rel,
258322 SmallVectorImpl &Result) const;
259323 virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
260
261 virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
262 virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
263
264 private:
265 typedef SmallVector SectionList;
266 SectionList Sections;
267
268 const MachOFormat::SectionBase *getSectionBase(DataRefImpl DRI) const;
269
324 virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
325 virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
326 bool &Result) const;
327 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
328 virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
329 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
330 virtual section_iterator begin_sections() const;
270331 void moveToNextSection(DataRefImpl &DRI) const;
271
272 const MachOFormat::SymbolTableEntryBase *
273 getSymbolTableEntryBase(DataRefImpl DRI) const;
274
275 const MachOFormat::SymbolTableEntryBase *
276 getSymbolTableEntryBase(DataRefImpl DRI,
277 const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const;
278
279 void moveToNextSymbol(DataRefImpl &DRI) const;
280 const MachOFormat::RelocationEntry *getRelocation(DataRefImpl Rel) const;
281 std::size_t getSectionIndex(DataRefImpl Sec) const;
282
283 void printRelocationTargetName(const MachOFormat::RelocationEntry *RE,
284 raw_string_ostream &fmt) const;
285332 };
286333
334 template
335 const typename MachOObjectFile::Section *
336 MachOObjectFile::getSection(DataRefImpl DRI) const {
337 const SectionBase *Addr = getSectionBase(DRI);
338 return reinterpret_cast(Addr);
339 }
340
341 template
342 const typename MachOObjectFile::SymbolTableEntry *
343 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
344 const SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
345 return reinterpret_cast(Base);
346 }
347
348 template
349 const typename MachOObjectFile::RelocationEntry *
350 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
351 const Section *Sect = getSection(Sections[Rel.d.b]);
352 uint32_t RelOffset = Sect->RelocationTableOffset;
353 uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);
354 StringRef Data = getData(Offset, sizeof(RelocationEntry));
355 return reinterpret_cast(Data.data());
356 }
357
358 template
359 error_code
360 MachOObjectFile::getSectionAddress(DataRefImpl Sec,
361 uint64_t &Res) const {
362 const Section *Sect = getSection(Sec);
363 Res = Sect->Address;
364 return object_error::success;
365 }
366
367 template
368 error_code
369 MachOObjectFile::getSectionSize(DataRefImpl Sec,
370 uint64_t &Res) const {
371 const Section *Sect = getSection(Sec);
372 Res = Sect->Size;
373 return object_error::success;
374 }
375
376 template
377 error_code
378 MachOObjectFile::getSectionContents(DataRefImpl Sec,
379 StringRef &Res) const {
380 const Section *Sect = getSection(Sec);
381 Res = getData(Sect->Offset, Sect->Size);
382 return object_error::success;
383 }
384
385 template
386 error_code
387 MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
388 uint64_t &Res) const {
389 const Section *Sect = getSection(Sec);
390 Res = uint64_t(1) << Sect->Align;
391 return object_error::success;
392 }
393
394 template
395 error_code
396 MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
397 const Section *Sect = getSection(Sec);
398 Res = Sect->Flags & macho::SF_PureInstructions;
399 return object_error::success;
400 }
401
402 template
403 error_code
404 MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
405 const Section *Sect = getSection(Sec);
406 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
407 Res = SectionType == MachO::SectionTypeZeroFill ||
408 SectionType == MachO::SectionTypeZeroFillLarge;
409 return object_error::success;
410 }
411
412 template
413 relocation_iterator
414 MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
415 const Section *Sect = getSection(Sec);
416 uint32_t LastReloc = Sect->NumRelocationTableEntries;
417 DataRefImpl Ret;
418 Ret.d.a = LastReloc;
419 Ret.d.b = getSectionIndex(Sec);
420 return relocation_iterator(RelocationRef(Ret, this));
421 }
422
423 template
424 error_code
425 MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
426 uint64_t &Res) const {
427 const Section *Sect = getSection(Sections[Rel.d.b]);
428 uint64_t SectAddress = Sect->Address;
429 const RelocationEntry *RE = getRelocation(Rel);
430 unsigned Arch = getArch();
431 bool isScattered = (Arch != Triple::x86_64) &&
432 (RE->Word0 & macho::RF_Scattered);
433
434 uint64_t RelAddr;
435 if (isScattered)
436 RelAddr = RE->Word0 & 0xFFFFFF;
437 else
438 RelAddr = RE->Word0;
439
440 Res = SectAddress + RelAddr;
441 return object_error::success;
442 }
443
444 template
445 error_code
446 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
447 uint64_t &Res) const {
448 const RelocationEntry *RE = getRelocation(Rel);
449
450 unsigned Arch = getArch();
451 bool isScattered = (Arch != Triple::x86_64) &&
452 (RE->Word0 & macho::RF_Scattered);
453 if (isScattered)
454 Res = RE->Word0 & 0xFFFFFF;
455 else
456 Res = RE->Word0;
457 return object_error::success;
458 }
459
460 template
461 error_code
462 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
463 SymbolRef &Res) const {
464 const RelocationEntry *RE = getRelocation(Rel);
465 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
466 bool isExtern = (RE->Word1 >> 27) & 1;
467
468 DataRefImpl Sym;
469 moveToNextSymbol(Sym);
470 if (isExtern) {
471 for (unsigned i = 0; i < SymbolIdx; i++) {
472 Sym.d.b++;
473 moveToNextSymbol(Sym);
474 assert(Sym.d.a < getHeader()->NumLoadCommands &&
475 "Relocation symbol index out of range!");
476 }
477 }
478 Res = SymbolRef(Sym, this);
479 return object_error::success;
480 }
481
482 template
483 error_code
484 MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
485 int64_t &Res) const {
486 const RelocationEntry *RE = getRelocation(Rel);
487 bool isExtern = (RE->Word1 >> 27) & 1;
488 Res = 0;
489 if (!isExtern) {
490 const uint8_t* sectAddress = base();
491 const Section *Sect = getSection(Sections[Rel.d.b]);
492 sectAddress += Sect->Offset;
493 Res = reinterpret_cast(sectAddress);
494 }
495 return object_error::success;
496 }
497
498 template
499 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
500 uint64_t &Res) const {
501 const RelocationEntry *RE = getRelocation(Rel);
502 Res = RE->Word0;
503 Res <<= 32;
504 Res |= RE->Word1;
505 return object_error::success;
506 }
507
508 template
509 error_code
510 MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
511 SmallVectorImpl &Result) const {
512 // TODO: Support scattered relocations.
513 StringRef res;
514 const RelocationEntry *RE = getRelocation(Rel);
515
516 unsigned Arch = getArch();
517 bool isScattered = (Arch != Triple::x86_64) &&
518 (RE->Word0 & macho::RF_Scattered);
519
520 unsigned r_type;
521 if (isScattered)
522 r_type = (RE->Word0 >> 24) & 0xF;
523 else
524 r_type = (RE->Word1 >> 28) & 0xF;
525
526 switch (Arch) {
527 case Triple::x86: {
528 static const char *const Table[] = {
529 "GENERIC_RELOC_VANILLA",
530 "GENERIC_RELOC_PAIR",
531 "GENERIC_RELOC_SECTDIFF",
532 "GENERIC_RELOC_PB_LA_PTR",
533 "GENERIC_RELOC_LOCAL_SECTDIFF",
534 "GENERIC_RELOC_TLV" };
535
536 if (r_type > 6)
537 res = "Unknown";
538 else
539 res = Table[r_type];
540 break;
541 }
542 case Triple::x86_64: {
543 static const char *const Table[] = {
544 "X86_64_RELOC_UNSIGNED",
545 "X86_64_RELOC_SIGNED",
546 "X86_64_RELOC_BRANCH",
547 "X86_64_RELOC_GOT_LOAD",
548 "X86_64_RELOC_GOT",
549 "X86_64_RELOC_SUBTRACTOR",
550 "X86_64_RELOC_SIGNED_1",
551 "X86_64_RELOC_SIGNED_2",
552 "X86_64_RELOC_SIGNED_4",
553 "X86_64_RELOC_TLV" };
554
555 if (r_type > 9)
556 res = "Unknown";
557 else
558 res = Table[r_type];
559 break;
560 }
561 case Triple::arm: {
562 static const char *const Table[] = {
563 "ARM_RELOC_VANILLA",
564 "ARM_RELOC_PAIR",
565 "ARM_RELOC_SECTDIFF",
566 "ARM_RELOC_LOCAL_SECTDIFF",
567 "ARM_RELOC_PB_LA_PTR",
568 "ARM_RELOC_BR24",
569 "ARM_THUMB_RELOC_BR22",
570 "ARM_THUMB_32BIT_BRANCH",
571 "ARM_RELOC_HALF",
572 "ARM_RELOC_HALF_SECTDIFF" };
573
574 if (r_type > 9)
575 res = "Unknown";
576 else
577 res = Table[r_type];
578 break;
579 }
580 case Triple::ppc: {
581 static const char *const Table[] = {
582 "PPC_RELOC_VANILLA",
583 "PPC_RELOC_PAIR",
584 "PPC_RELOC_BR14",
585 "PPC_RELOC_BR24",
586 "PPC_RELOC_HI16",
587 "PPC_RELOC_LO16",
588 "PPC_RELOC_HA16",
589 "PPC_RELOC_LO14",
590 "PPC_RELOC_SECTDIFF",
591 "PPC_RELOC_PB_LA_PTR",
592 "PPC_RELOC_HI16_SECTDIFF",
593 "PPC_RELOC_LO16_SECTDIFF",
594 "PPC_RELOC_HA16_SECTDIFF",
595 "PPC_RELOC_JBSR",
596 "PPC_RELOC_LO14_SECTDIFF",
597 "PPC_RELOC_LOCAL_SECTDIFF" };
598
599 res = Table[r_type];
600 break;
601 }
602 case Triple::UnknownArch:
603 res = "Unknown";
604 break;
605 }
606 Result.append(res.begin(), res.end());
607 return object_error::success;
608 }
609
610 template
611 error_code
612 MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
613 SmallVectorImpl &Result) const {
614 const RelocationEntry *RE = getRelocation(Rel);
615
616 unsigned Arch = getArch();
617 bool isScattered = (Arch != Triple::x86_64) &&
618 (RE->Word0 & macho::RF_Scattered);
619
620 std::string fmtbuf;
621 raw_string_ostream fmt(fmtbuf);
622
623 unsigned Type;
624 if (isScattered)
625 Type = (RE->Word0 >> 24) & 0xF;
626 else
627 Type = (RE->Word1 >> 28) & 0xF;
628
629 bool isPCRel;
630 if (isScattered)
631 isPCRel = ((RE->Word0 >> 30) & 1);
632 else
633 isPCRel = ((RE->Word1 >> 24) & 1);
634
635 // Determine any addends that should be displayed with the relocation.
636 // These require decoding the relocation type, which is triple-specific.
637
638 // X86_64 has entirely custom relocation types.
639 if (Arch == Triple::x86_64) {
640 bool isPCRel = ((RE->Word1 >> 24) & 1);
641
642 switch (Type) {
643 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
644 case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
645 printRelocationTargetName(RE, fmt);
646 fmt << "@GOT";
647 if (isPCRel) fmt << "PCREL";
648 break;
649 }
650 case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
651 DataRefImpl RelNext = Rel;
652 RelNext.d.a++;
653 const RelocationEntry *RENext = getRelocation(RelNext);
654
655 // X86_64_SUBTRACTOR must be followed by a relocation of type
656 // X86_64_RELOC_UNSIGNED.
657 // NOTE: Scattered relocations don't exist on x86_64.
658 unsigned RType = (RENext->Word1 >> 28) & 0xF;
659 if (RType != 0)
660 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
661 "X86_64_RELOC_SUBTRACTOR.");
662
663 // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
664 // X86_64_SUBTRACTOR contains to the subtrahend.
665 printRelocationTargetName(RENext, fmt);
666 fmt << "-";
667 printRelocationTargetName(RE, fmt);
668 break;
669 }
670 case macho::RIT_X86_64_TLV:
671 printRelocationTargetName(RE, fmt);
672 fmt << "@TLV";
673 if (isPCRel) fmt << "P";
674 break;
675 case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
676 printRelocationTargetName(RE, fmt);
677 fmt << "-1";
678 break;
679 case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
680 printRelocationTargetName(RE, fmt);
681 fmt << "-2";
682 break;
683 case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
684 printRelocationTargetName(RE, fmt);
685 fmt << "-4";
686 break;
687 default:
688 printRelocationTargetName(RE, fmt);
689 break;
690 }
691 // X86 and ARM share some relocation types in common.
692 } else if (Arch == Triple::x86 || Arch == Triple::arm) {
693 // Generic relocation types...
694 switch (Type) {
695 case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
696 return object_error::success;
697 case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
698 DataRefImpl RelNext = Rel;
699 RelNext.d.a++;
700 const RelocationEntry *RENext = getRelocation(RelNext);
701
702 // X86 sect diff's must be followed by a relocation of type
703 // GENERIC_RELOC_PAIR.
704 bool isNextScattered = (Arch != Triple::x86_64) &&
705 (RENext->Word0 & macho::RF_Scattered);
706 unsigned RType;
707 if (isNextScattered)
708 RType = (RENext->Word0 >> 24) & 0xF;
709 else
710 RType = (RENext->Word1 >> 28) & 0xF;
711 if (RType != 1)
712 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
713 "GENERIC_RELOC_SECTDIFF.");
714
715 printRelocationTargetName(RE, fmt);
716 fmt << "-";
717 printRelocationTargetName(RENext, fmt);
718 break;
719 }
720 }
721
722 if (Arch == Triple::x86) {
723 // All X86 relocations that need special printing were already
724 // handled in the generic code.
725 switch (Type) {
726 case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
727 DataRefImpl RelNext = Rel;
728 RelNext.d.a++;
729 const RelocationEntry *RENext = getRelocation(RelNext);
730
731 // X86 sect diff's must be followed by a relocation of type
732 // GENERIC_RELOC_PAIR.
733 bool isNextScattered = (Arch != Triple::x86_64) &&
734 (RENext->Word0 & macho::RF_Scattered);
735 unsigned RType;
736 if (isNextScattered)
737 RType = (RENext->Word0 >> 24) & 0xF;
738 else
739 RType = (RENext->Word1 >> 28) & 0xF;
740 if (RType != 1)
741 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
742 "GENERIC_RELOC_LOCAL_SECTDIFF.");
743
744 printRelocationTargetName(RE, fmt);
745 fmt << "-";
746 printRelocationTargetName(RENext, fmt);
747 break;
748 }
749 case macho::RIT_Generic_TLV: {
750 printRelocationTargetName(RE, fmt);
751 fmt << "@TLV";
752 if (isPCRel) fmt << "P";
753 break;
754 }
755 default:
756 printRelocationTargetName(RE, fmt);
757 }
758 } else { // ARM-specific relocations
759 switch (Type) {
760 case macho::RIT_ARM_Half: // ARM_RELOC_HALF
761 case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
762 // Half relocations steal a bit from the length field to encode
763 // whether this is an upper16 or a lower16 relocation.
764 bool isUpper;
765 if (isScattered)
766 isUpper = (RE->Word0 >> 28) & 1;
767 else
768 isUpper = (RE->Word1 >> 25) & 1;
769
770 if (isUpper)
771 fmt << ":upper16:(";
772 else
773 fmt << ":lower16:(";
774 printRelocationTargetName(RE, fmt);
775
776 DataRefImpl RelNext = Rel;
777 RelNext.d.a++;
778 const RelocationEntry *RENext = getRelocation(RelNext);
779
780 // ARM half relocs must be followed by a relocation of type
781 // ARM_RELOC_PAIR.
782 bool isNextScattered = (Arch != Triple::x86_64) &&
783 (RENext->Word0 & macho::RF_Scattered);
784 unsigned RType;
785 if (isNextScattered)
786 RType = (RENext->Word0 >> 24) & 0xF;
787 else
788 RType = (RENext->Word1 >> 28) & 0xF;
789
790 if (RType != 1)
791 report_fatal_error("Expected ARM_RELOC_PAIR after "
792 "GENERIC_RELOC_HALF");
793
794 // NOTE: The half of the target virtual address is stashed in the
795 // address field of the secondary relocation, but we can't reverse
796 // engineer the constant offset from it without decoding the movw/movt
797 // instruction to find the other half in its immediate field.
798
799 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
800 // symbol/section pointer of the follow-on relocation.
801 if (Type == macho::RIT_ARM_HalfDifference) {
802 fmt << "-";
803 printRelocationTargetName(RENext, fmt);
804 }
805
806 fmt << ")";
807 break;
808 }
809 default: {
810 printRelocationTargetName(RE, fmt);
811 }
812 }
813 }
814 } else
815 printRelocationTargetName(RE, fmt);
816
817 fmt.flush();
818 Result.append(fmtbuf.begin(), fmtbuf.end());
819 return object_error::success;
820 }
821
822 template
823 error_code
824 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
825 bool &Result) const {
826 const RelocationEntry *RE = getRelocation(Rel);
827
828 unsigned Arch = getArch();
829 bool isScattered = (Arch != Triple::x86_64) &&
830 (RE->Word0 & macho::RF_Scattered);
831 unsigned Type;
832 if (isScattered)
833 Type = (RE->Word0 >> 24) & 0xF;
834 else
835 Type = (RE->Word1 >> 28) & 0xF;
836
837 Result = false;
838
839 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
840 // is always hidden.
841 if (Arch == Triple::x86 || Arch == Triple::arm) {
842 if (Type == macho::RIT_Pair) Result = true;
843 } else if (Arch == Triple::x86_64) {
844 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
845 // an X864_64_RELOC_SUBTRACTOR.
846 if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
847 DataRefImpl RelPrev = Rel;
848 RelPrev.d.a--;
849 const RelocationEntry *REPrev = getRelocation(RelPrev);
850
851 unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
852
853 if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
854 }
855 }
856
857 return object_error::success;
858 }
859
860 template
861 error_code
862 MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
863 uint64_t &Res) const {
864 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
865 Res = Entry->Value;
866 if (Entry->SectionIndex) {
867 const Section *Sec = getSection(Sections[Entry->SectionIndex-1]);
868 Res += Sec->Offset - Sec->Address;
869 }
870
871 return object_error::success;
872 }
873
874 template
875 error_code
876 MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
877 DataRefImpl Symb,
878 bool &Result) const {
879 SymbolRef::Type ST;
880 getSymbolType(Symb, ST);
881 if (ST == SymbolRef::ST_Unknown) {
882 Result = false;
883 return object_error::success;
884 }
885
886 uint64_t SectBegin, SectEnd;
887 getSectionAddress(Sec, SectBegin);
888 getSectionSize(Sec, SectEnd);
889 SectEnd += SectBegin;
890
891 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
892 uint64_t SymAddr= Entry->Value;
893 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
894
895 return object_error::success;
896 }
897
898 template
899 error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
900 uint64_t &Res) const {
901 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
902 Res = Entry->Value;
903 return object_error::success;
904 }
905
906 template
907 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
908 uint64_t &Result) const {
909 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
910 uint64_t BeginOffset;
911 uint64_t EndOffset = 0;
912 uint8_t SectionIndex;
913
914 const SymbolTableEntry *Entry = getSymbolTableEntry(DRI);
915 BeginOffset = Entry->Value;
916 SectionIndex = Entry->SectionIndex;
917 if (!SectionIndex) {
918 uint32_t flags = SymbolRef::SF_None;
919 getSymbolFlags(DRI, flags);
920 if (flags & SymbolRef::SF_Common)
921 Result = Entry->Value;
922 else
923 Result = UnknownAddressOrSize;
924 return object_error::success;
925 }
926 // Unfortunately symbols are unsorted so we need to touch all
927 // symbols from load command
928 DRI.d.b = 0;
929 uint32_t Command = DRI.d.a;
930 while (Command == DRI.d.a) {
931 moveToNextSymbol(DRI);
932 if (DRI.d.a < LoadCommandCount) {
933 Entry = getSymbolTableEntry(DRI);
934 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
935 if (!EndOffset || Entry->Value < EndOffset)
936 EndOffset = Entry->Value;
937 }
938 DRI.d.b++;
939 }
940 if (!EndOffset) {
941 uint64_t Size;
942 getSectionSize(Sections[SectionIndex-1], Size);
943 getSectionAddress(Sections[SectionIndex-1], EndOffset);
944 EndOffset += Size;
945 }
946 Result = EndOffset - BeginOffset;
947 return object_error::success;
948 }
949
950 template
951 error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
952 SectionRef &Res) const {
953 Sec.d.b++;
954 moveToNextSection(Sec);
955 Res = SectionRef(Sec, this);
956 return object_error::success;
957 }
958
959 template
960 section_iterator MachOObjectFile::begin_sections() const {
961 DataRefImpl DRI;
962 moveToNextSection(DRI);
963 return section_iterator(SectionRef(DRI, this));
964 }
965
966 template
967 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
968 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
969 while (DRI.d.a < LoadCommandCount) {
970 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
971 if (Command->Type == SegmentLoadType) {
972 const SegmentLoadCommand *SegmentLoadCmd =
973 reinterpret_cast(Command);
974 if (DRI.d.b < SegmentLoadCmd->NumSections)
975 return;
976 }
977
978 DRI.d.a++;
979 DRI.d.b = 0;
980 }
981 }
982
287983 }
288984 }
289985
1414 #include "llvm/Object/MachO.h"
1515 #include "llvm/ADT/Triple.h"
1616 #include "llvm/Object/MachOFormat.h"
17 #include "llvm/Support/Casting.h"
1718 #include "llvm/Support/DataExtractor.h"
1819 #include "llvm/Support/Format.h"
1920 #include "llvm/Support/MemoryBuffer.h"
2728 namespace llvm {
2829 namespace object {
2930
30 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool Is64bits,
31 error_code &ec)
31 MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits,
32 error_code &ec)
3233 : ObjectFile(getMachOType(true, Is64bits), Object) {
33 DataRefImpl DRI;
34 moveToNextSection(DRI);
35 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
36 while (DRI.d.a < LoadCommandCount) {
37 Sections.push_back(DRI);
38 DRI.d.b++;
39 moveToNextSection(DRI);
40 }
41 }
42
43 bool MachOObjectFile::is64Bit() const {
44 unsigned int Type = getType();
45 return Type == ID_MachO64L || Type == ID_MachO64B;
46 }
47
48 const MachOFormat::LoadCommand *
49 MachOObjectFile::getLoadCommandInfo(unsigned Index) const {
34 }
35
36 bool MachOObjectFileBase::is64Bit() const {
37 return isa >(this);
38 }
39
40 const MachOObjectFileBase::LoadCommand *
41 MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const {
5042 uint64_t Offset;
5143 uint64_t NewOffset = getHeaderSize();
52 const MachOFormat::LoadCommand *Load;
44 const LoadCommand *Load;
5345 unsigned I = 0;
5446 do {
5547 Offset = NewOffset;
56 StringRef Data = getData(Offset, sizeof(MachOFormat::LoadCommand));
57 Load = reinterpret_cast(Data.data());
48 StringRef Data = getData(Offset, sizeof(LoadCommand));
49 Load = reinterpret_cast(Data.data());
5850 NewOffset = Offset + Load->Size;
5951 ++I;
6052 } while (I != Index + 1);
6254 return Load;
6355 }
6456
65 void MachOObjectFile::ReadULEB128s(uint64_t Index,
66 SmallVectorImpl &Out) const {
57 void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
58 SmallVectorImpl &Out) const {
6759 DataExtractor extractor(ObjectFile::getData(), true, 0);
6860
6961 uint32_t offset = Index;
7466 }
7567 }
7668
77 const MachOFormat::Header *MachOObjectFile::getHeader() const {
78 StringRef Data = getData(0, sizeof(MachOFormat::Header));
79 return reinterpret_cast(Data.data());
80 }
81
82 unsigned MachOObjectFile::getHeaderSize() const {
69 const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const {
70 StringRef Data = getData(0, sizeof(Header));
71 return reinterpret_cast(Data.data());
72 }
73
74 unsigned MachOObjectFileBase::getHeaderSize() const {
8375 return is64Bit() ? macho::Header64Size : macho::Header32Size;
8476 }
8577
86 StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const {
78 StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
8779 return ObjectFile::getData().substr(Offset, Size);
8880 }
8981
9183 StringRef Magic = Buffer->getBuffer().slice(0, 4);
9284 error_code ec;
9385 bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
94 ObjectFile *Ret = new MachOObjectFile(Buffer, Is64Bits, ec);
86 ObjectFile *Ret;
87 if (Is64Bits)
88 Ret = new MachOObjectFile(Buffer, ec);
89 else
90 Ret = new MachOObjectFile(Buffer, ec);
9591 if (ec)
9692 return NULL;
9793 return Ret;
9995
10096 /*===-- Symbols -----------------------------------------------------------===*/
10197
102 void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const {
98 void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const {
10399 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
104100 while (DRI.d.a < LoadCommandCount) {
105 const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
101 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
106102 if (Command->Type == macho::LCT_Symtab) {
107 const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
108 reinterpret_cast(Command);
103 const SymtabLoadCommand *SymtabLoadCmd =
104 reinterpret_cast(Command);
109105 if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
110106 return;
111107 }
115111 }
116112 }
117113
118 const MachOFormat::SymbolTableEntryBase *
119 MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI) const {
120 const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
121 const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
122 reinterpret_cast(Command);
114 const MachOObjectFileBase::SymbolTableEntryBase *
115 MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const {
116 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
117 const SymtabLoadCommand *SymtabLoadCmd =
118 reinterpret_cast(Command);
123119 return getSymbolTableEntryBase(DRI, SymtabLoadCmd);
124120 }
125121
126 const MachOFormat::SymbolTableEntry *
127 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
128 const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
129 return reinterpret_cast*>(Base);
130 }
131
132 const MachOFormat::SymbolTableEntryBase *
133 MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI,
134 const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const {
122 const MachOObjectFileBase::SymbolTableEntryBase *
123 MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI,
124 const SymtabLoadCommand *SymtabLoadCmd) const {
135125 uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset;
136126 unsigned Index = DRI.d.b;
137127
141131
142132 uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
143133 StringRef Data = getData(Offset, SymbolTableEntrySize);
144 return
145 reinterpret_cast(Data.data());
146 }
147
148 const MachOFormat::SymbolTableEntry*
149 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
150 const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
151 return reinterpret_cast*>(Base);
152 }
153
154 error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI,
155 SymbolRef &Result) const {
134 return reinterpret_cast(Data.data());
135 }
136
137 error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI,
138 SymbolRef &Result) const {
156139 DRI.d.b++;
157140 moveToNextSymbol(DRI);
158141 Result = SymbolRef(DRI, this);
159142 return object_error::success;
160143 }
161144
162 error_code MachOObjectFile::getSymbolName(DataRefImpl DRI,
163 StringRef &Result) const {
164 const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
165 const MachOFormat::SymtabLoadCommand *SymtabLoadCmd =
166 reinterpret_cast(Command);
145 error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI,
146 StringRef &Result) const {
147 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
148 const SymtabLoadCommand *SymtabLoadCmd =
149 reinterpret_cast(Command);
167150
168151 StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset,
169152 SymtabLoadCmd->StringTableSize);
170153
171 const MachOFormat::SymbolTableEntryBase *Entry =
154 const SymbolTableEntryBase *Entry =
172155 getSymbolTableEntryBase(DRI, SymtabLoadCmd);
173156 uint32_t StringIndex = Entry->StringIndex;
174157
178161 return object_error::success;
179162 }
180163
181 error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI,
182 uint64_t &Result) const {
183 if (is64Bit()) {
184 const MachOFormat::SymbolTableEntry *Entry =
185 getSymbol64TableEntry(DRI);
186 Result = Entry->Value;
187 if (Entry->SectionIndex) {
188 const MachOFormat::Section *Section =
189 getSection64(Sections[Entry->SectionIndex-1]);
190 Result += Section->Offset - Section->Address;
191 }
192 } else {
193 const MachOFormat::SymbolTableEntry *Entry =
194 getSymbolTableEntry(DRI);
195 Result = Entry->Value;
196 if (Entry->SectionIndex) {
197 const MachOFormat::Section *Section =
198 getSection(Sections[Entry->SectionIndex-1]);
199 Result += Section->Offset - Section->Address;
200 }
201 }
202
203 return object_error::success;
204 }
205
206 error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI,
207 uint64_t &Result) const {
208 if (is64Bit()) {
209 const MachOFormat::SymbolTableEntry *Entry =
210 getSymbol64TableEntry(DRI);
211 Result = Entry->Value;
212 } else {
213 const MachOFormat::SymbolTableEntry *Entry =
214 getSymbolTableEntry(DRI);
215 Result = Entry->Value;
216 }
217 return object_error::success;
218 }
219
220 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
221 uint64_t &Result) const {
222 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
223 uint64_t BeginOffset;
224 uint64_t EndOffset = 0;
225 uint8_t SectionIndex;
226 if (is64Bit()) {
227 const MachOFormat::SymbolTableEntry *Entry =
228 getSymbol64TableEntry(DRI);
229 BeginOffset = Entry->Value;
230 SectionIndex = Entry->SectionIndex;
231 if (!SectionIndex) {
232 uint32_t flags = SymbolRef::SF_None;
233 getSymbolFlags(DRI, flags);
234 if (flags & SymbolRef::SF_Common)
235 Result = Entry->Value;
236 else
237 Result = UnknownAddressOrSize;
238 return object_error::success;
239 }
240 // Unfortunately symbols are unsorted so we need to touch all
241 // symbols from load command
242 DRI.d.b = 0;
243 uint32_t Command = DRI.d.a;
244 while (Command == DRI.d.a) {
245 moveToNextSymbol(DRI);
246 if (DRI.d.a < LoadCommandCount) {
247 Entry = getSymbol64TableEntry(DRI);
248 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
249 if (!EndOffset || Entry->Value < EndOffset)
250 EndOffset = Entry->Value;
251 }
252 DRI.d.b++;
253 }
254 } else {
255 const MachOFormat::SymbolTableEntry *Entry =
256 getSymbolTableEntry(DRI);
257 BeginOffset = Entry->Value;
258 SectionIndex = Entry->SectionIndex;
259 if (!SectionIndex) {
260 uint32_t flags = SymbolRef::SF_None;
261 getSymbolFlags(DRI, flags);
262 if (flags & SymbolRef::SF_Common)
263 Result = Entry->Value;
264 else
265 Result = UnknownAddressOrSize;
266 return object_error::success;
267 }
268 // Unfortunately symbols are unsorted so we need to touch all
269 // symbols from load command
270 DRI.d.b = 0;
271 uint32_t Command = DRI.d.a;
272 while (Command == DRI.d.a) {
273 moveToNextSymbol(DRI);
274 if (DRI.d.a < LoadCommandCount) {
275 Entry = getSymbolTableEntry(DRI);
276 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
277 if (!EndOffset || Entry->Value < EndOffset)
278 EndOffset = Entry->Value;
279 }
280 DRI.d.b++;
281 }
282 }
283 if (!EndOffset) {
284 uint64_t Size;
285 getSectionSize(Sections[SectionIndex-1], Size);
286 getSectionAddress(Sections[SectionIndex-1], EndOffset);
287 EndOffset += Size;
288 }
289 Result = EndOffset - BeginOffset;
290 return object_error::success;
291 }
292
293 error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI,
294 char &Result) const {
295 const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
164 error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI,
165 char &Result) const {
166 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
296167 uint8_t Type = Entry->Type;
297168 uint16_t Flags = Entry->Flags;
298169
316187 return object_error::success;
317188 }
318189
319 error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
320 uint32_t &Result) const {
321 const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
190 error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI,
191 uint32_t &Result) const {
192 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
322193 uint8_t MachOType = Entry->Type;
323194 uint16_t MachOFlags = Entry->Flags;
324195
346217 return object_error::success;
347218 }
348219
349 error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb,
350 section_iterator &Res) const {
351 const MachOFormat::SymbolTableEntryBase *Entry =
352 getSymbolTableEntryBase(Symb);
220 error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb,
221 section_iterator &Res) const {
222 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
353223 uint8_t index = Entry->SectionIndex;
354224
355225 if (index == 0)
360230 return object_error::success;
361231 }
362232
363 error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
364 SymbolRef::Type &Res) const {
365 const MachOFormat::SymbolTableEntryBase *Entry =
366 getSymbolTableEntryBase(Symb);
233 error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb,
234 SymbolRef::Type &Res) const {
235 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
367236 uint8_t n_type = Entry->Type;
368237
369238 Res = SymbolRef::ST_Other;
385254 return object_error::success;
386255 }
387256
388 error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
389 uint64_t &Val) const {
390 report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
391 }
392
393 symbol_iterator MachOObjectFile::begin_symbols() const {
257 error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
258 uint64_t &Val) const {
259 report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
260 }
261
262 symbol_iterator MachOObjectFileBase::begin_symbols() const {
394263 // DRI.d.a = segment number; DRI.d.b = symbol index.
395264 DataRefImpl DRI;
396265 moveToNextSymbol(DRI);
397266 return symbol_iterator(SymbolRef(DRI, this));
398267 }
399268
400 symbol_iterator MachOObjectFile::end_symbols() const {
269 symbol_iterator MachOObjectFileBase::end_symbols() const {
401270 DataRefImpl DRI;
402271 DRI.d.a = getHeader()->NumLoadCommands;
403272 return symbol_iterator(SymbolRef(DRI, this));
404273 }
405274
406 symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
275 symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
407276 // TODO: implement
408 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
409 }
410
411 symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
277 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
278 }
279
280 symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const {
412281 // TODO: implement
413 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
414 }
415
416 library_iterator MachOObjectFile::begin_libraries_needed() const {
282 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
283 }
284
285 library_iterator MachOObjectFileBase::begin_libraries_needed() const {
417286 // TODO: implement
418 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
419 }
420
421 library_iterator MachOObjectFile::end_libraries_needed() const {
287 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
288 }
289
290 library_iterator MachOObjectFileBase::end_libraries_needed() const {
422291 // TODO: implement
423 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
424 }
425
426 StringRef MachOObjectFile::getLoadName() const {
292 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
293 }
294
295 StringRef MachOObjectFileBase::getLoadName() const {
427296 // TODO: Implement
428 report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
297 report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase");
429298 }
430299
431300 /*===-- Sections ----------------------------------------------------------===*/
432301
433 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
434 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
435 while (DRI.d.a < LoadCommandCount) {
436 const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
437 if (Command->Type == macho::LCT_Segment) {
438 const MachOFormat::SegmentLoadCommand *SegmentLoadCmd =
439 reinterpret_cast*>(Command);
440 if (DRI.d.b < SegmentLoadCmd->NumSections)
441 return;
442 } else if (Command->Type == macho::LCT_Segment64) {
443 const MachOFormat::SegmentLoadCommand *SegmentLoadCmd =
444 reinterpret_cast*>(Command);
445 if (DRI.d.b < SegmentLoadCmd->NumSections)
446 return;
447 }
448
449 DRI.d.a++;
450 DRI.d.b = 0;
451 }
452 }
453
454 error_code MachOObjectFile::getSectionNext(DataRefImpl DRI,
455 SectionRef &Result) const {
456 DRI.d.b++;
457 moveToNextSection(DRI);
458 Result = SectionRef(DRI, this);
459 return object_error::success;
460 }
461
462 const MachOFormat::Section *
463 MachOObjectFile::getSection(DataRefImpl DRI) const {
464 assert(!is64Bit());
465 const MachOFormat::SectionBase *Addr = getSectionBase(DRI);
466 return reinterpret_cast*>(Addr);
467 }
468
469 std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const {
302 std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {
470303 SectionList::const_iterator loc =
471304 std::find(Sections.begin(), Sections.end(), Sec);
472305 assert(loc != Sections.end() && "Sec is not a valid section!");
473306 return std::distance(Sections.begin(), loc);
474307 }
475308
476 const MachOFormat::SectionBase*
477 MachOObjectFile::getSectionBase(DataRefImpl DRI) const {
478 const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
309 const MachOObjectFileBase::SectionBase*
310 MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const {
311 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
479312 uintptr_t CommandAddr = reinterpret_cast(Command);
480313
481314 bool Is64 = is64Bit();
486319 sizeof(MachOFormat::Section);
487320
488321 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
489 return reinterpret_cast(SectionAddr);
490 }
491
492 const MachOFormat::Section *
493 MachOObjectFile::getSection64(DataRefImpl DRI) const {
494 assert(is64Bit());
495 const MachOFormat::SectionBase *Addr = getSectionBase(DRI);
496 return reinterpret_castMachOFormat::Section*>(Addr);
322 return reinterpret_castSectionBase*>(SectionAddr);
497323 }
498324
499325 static StringRef parseSegmentOrSectionName(const char *P) {
504330 return StringRef(P, 16);
505331 }
506332
507 ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl DRI) const {
508 const MachOFormat::SectionBase *Base = getSectionBase(DRI);
333 ArrayRef MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const {
334 const SectionBase *Base = getSectionBase(DRI);
509335 return ArrayRef(Base->Name);
510336 }
511337
512 error_code MachOObjectFile::getSectionName(DataRefImpl DRI,
513 StringRef &Result) const {
338 error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI,
339 StringRef &Result) const {
514340 ArrayRef Raw = getSectionRawName(DRI);
515341 Result = parseSegmentOrSectionName(Raw.data());
516342 return object_error::success;
517343 }
518344
519345 ArrayRef
520 MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
521 const MachOFormat::SectionBase *Base = getSectionBase(Sec);
346 MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
347 const SectionBase *Base = getSectionBase(Sec);
522348 return ArrayRef(Base->SegmentName);
523349 }
524350
525 StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const {
351 StringRef
352 MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const {
526353 ArrayRef Raw = getSectionRawFinalSegmentName(DRI);
527354 return parseSegmentOrSectionName(Raw.data());
528355 }
529356
530 error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI,
531 uint64_t &Result) const {
532 if (is64Bit()) {
533 const MachOFormat::Section *Sect = getSection64(DRI);
534 Result = Sect->Address;
535 } else {
536 const MachOFormat::Section *Sect = getSection(DRI);
537 Result = Sect->Address;
538 }
539 return object_error::success;
540 }
541
542 error_code MachOObjectFile::getSectionSize(DataRefImpl DRI,
543 uint64_t &Result) const {
544 if (is64Bit()) {
545 const MachOFormat::Section *Sect = getSection64(DRI);
546 Result = Sect->Size;
547 } else {
548 const MachOFormat::Section *Sect = getSection(DRI);
549 Result = Sect->Size;
550 }
551 return object_error::success;
552 }
553
554 error_code MachOObjectFile::getSectionContents(DataRefImpl DRI,
555 StringRef &Result) const {
556 if (is64Bit()) {
557 const MachOFormat::Section *Sect = getSection64(DRI);
558 Result = getData(Sect->Offset, Sect->Size);
559 } else {
560 const MachOFormat::Section *Sect = getSection(DRI);
561 Result = getData(Sect->Offset, Sect->Size);
562 }
563 return object_error::success;
564 }
565
566 error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI,
567 uint64_t &Result) const {
568 if (is64Bit()) {
569 const MachOFormat::Section *Sect = getSection64(DRI);
570 Result = uint64_t(1) << Sect->Align;
571 } else {
572 const MachOFormat::Section *Sect = getSection(DRI);
573 Result = uint64_t(1) << Sect->Align;
574 }
575 return object_error::success;
576 }
577
578 error_code MachOObjectFile::isSectionText(DataRefImpl DRI,
579 bool &Result) const {
580 if (is64Bit()) {
581 const MachOFormat::Section *Sect = getSection64(DRI);
582 Result = Sect->Flags & macho::SF_PureInstructions;
583 } else {
584 const MachOFormat::Section *Sect = getSection(DRI);
585 Result = Sect->Flags & macho::SF_PureInstructions;
586 }
587 return object_error::success;
588 }
589
590 error_code MachOObjectFile::isSectionData(DataRefImpl DRI,
591 bool &Result) const {
357 error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
358 bool &Result) const {
592359 // FIXME: Unimplemented.
593360 Result = false;
594361 return object_error::success;
595362 }
596363
597 error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
598 bool &Result) const {
599 // FIXME: Unimplemented.
600 Result = false;
601 return object_error::success;
602 }
603
604 error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
605 bool &Result) const {
606 // FIXME: Unimplemented.
607 Result = true;
608 return object_error::success;
609 }
610
611 error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
364 error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI,
612365 bool &Result) const {
613366 // FIXME: Unimplemented.
614367 Result = false;
615368 return object_error::success;
616369 }
617370
618 error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI,
619 bool &Result) const {
620 if (is64Bit()) {
621 const MachOFormat::Section *Sect = getSection64(DRI);
622 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
623 Result = (SectionType == MachO::SectionTypeZeroFill ||
624 SectionType == MachO::SectionTypeZeroFillLarge);
625 } else {
626 const MachOFormat::Section *Sect = getSection(DRI);
627 unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
628 Result = (SectionType == MachO::SectionTypeZeroFill ||
629 SectionType == MachO::SectionTypeZeroFillLarge);
630 }
631
632 return object_error::success;
633 }
634
635 error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
636 bool &Result) const {
371 error_code
372 MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec,
373 bool &Result) const {
374 // FIXME: Unimplemented.
375 Result = true;
376 return object_error::success;
377 }
378
379 error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec,
380 bool &Result) const {
381 // FIXME: Unimplemented.
382 Result = false;
383 return object_error::success;
384 }
385
386 error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec,
387 bool &Result) const {
637388 // Consider using the code from isSectionText to look for __const sections.
638389 // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
639390 // to use section attributes to distinguish code from data.
643394 return object_error::success;
644395 }
645396
646 error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
647 DataRefImpl Symb,
648 bool &Result) const {
649 SymbolRef::Type ST;
650 getSymbolType(Symb, ST);
651 if (ST == SymbolRef::ST_Unknown) {
652 Result = false;
653 return object_error::success;
654 }
655
656 uint64_t SectBegin, SectEnd;
657 getSectionAddress(Sec, SectBegin);
658 getSectionSize(Sec, SectEnd);
659 SectEnd += SectBegin;
660
661 if (is64Bit()) {
662 const MachOFormat::SymbolTableEntry *Entry =
663 getSymbol64TableEntry(Symb);
664 uint64_t SymAddr= Entry->Value;
665 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
666 } else {
667 const MachOFormat::SymbolTableEntry *Entry =
668 getSymbolTableEntry(Symb);
669 uint64_t SymAddr= Entry->Value;
670 Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
671 }
672
673 return object_error::success;
674 }
675
676 relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
397 relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const {
677398 DataRefImpl ret;
678399 ret.d.b = getSectionIndex(Sec);
679400 return relocation_iterator(RelocationRef(ret, this));
680401 }
681402
682 relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
683 uint32_t last_reloc;
684 if (is64Bit()) {
685 const MachOFormat::Section *Sect = getSection64(Sec);
686 last_reloc = Sect->NumRelocationTableEntries;
687 } else {
688 const MachOFormat::Section *Sect = getSection(Sec);
689 last_reloc = Sect->NumRelocationTableEntries;
690 }
691 DataRefImpl ret;
692 ret.d.a = last_reloc;
693 ret.d.b = getSectionIndex(Sec);
694 return relocation_iterator(RelocationRef(ret, this));
695 }
696
697 section_iterator MachOObjectFile::begin_sections() const {
698 DataRefImpl DRI;
699 moveToNextSection(DRI);
700 return section_iterator(SectionRef(DRI, this));
701 }
702
703 section_iterator MachOObjectFile::end_sections() const {
403 section_iterator MachOObjectFileBase::end_sections() const {
704404 DataRefImpl DRI;
705405 DRI.d.a = getHeader()->NumLoadCommands;
706406 return section_iterator(SectionRef(DRI, this));
708408
709409 /*===-- Relocations -------------------------------------------------------===*/
710410
711 const MachOFormat::RelocationEntry *
712 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
713 uint32_t relOffset;
714 if (is64Bit()) {
715 const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]);
716 relOffset = Sect->RelocationTableOffset;
717 } else {
718 const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
719 relOffset = Sect->RelocationTableOffset;
720 }
721 uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry);
722 StringRef Data = getData(Offset, sizeof(MachOFormat::RelocationEntry));
723 return reinterpret_cast(Data.data());
724 }
725
726 error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
727 RelocationRef &Res) const {
411 error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,
412 RelocationRef &Res) const {
728413 ++Rel.d.a;
729414 Res = RelocationRef(Rel, this);
730 return object_error::success;
731 }
732 error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
733 uint64_t &Res) const {
734 const uint8_t* sectAddress = 0;
735 if (is64Bit()) {
736 const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]);
737 sectAddress += Sect->Address;
738 } else {
739 const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
740 sectAddress += Sect->Address;
741 }
742 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
743
744 unsigned Arch = getArch();
745 bool isScattered = (Arch != Triple::x86_64) &&
746 (RE->Word0 & macho::RF_Scattered);
747 uint64_t RelAddr = 0;
748 if (isScattered)
749 RelAddr = RE->Word0 & 0xFFFFFF;
750 else
751 RelAddr = RE->Word0;
752
753 Res = reinterpret_cast(sectAddress + RelAddr);
754 return object_error::success;
755 }
756 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
757 uint64_t &Res) const {
758 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
759
760 unsigned Arch = getArch();
761 bool isScattered = (Arch != Triple::x86_64) &&
762 (RE->Word0 & macho::RF_Scattered);
763 if (isScattered)
764 Res = RE->Word0 & 0xFFFFFF;
765 else
766 Res = RE->Word0;
767 return object_error::success;
768 }
769 error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
770 SymbolRef &Res) const {
771 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
772 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
773 bool isExtern = (RE->Word1 >> 27) & 1;
774
775 DataRefImpl Sym;
776 moveToNextSymbol(Sym);
777 if (isExtern) {
778 for (unsigned i = 0; i < SymbolIdx; i++) {
779 Sym.d.b++;
780 moveToNextSymbol(Sym);
781 assert(Sym.d.a < getHeader()->NumLoadCommands &&
782 "Relocation symbol index out of range!");
783 }
784 }
785 Res = SymbolRef(Sym, this);
786 return object_error::success;
787 }
788 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
789 uint64_t &Res) const {
790 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
791 Res = RE->Word0;
792 Res <<= 32;
793 Res |= RE->Word1;
794 return object_error::success;
795 }
796 error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
797 SmallVectorImpl &Result) const {
798 // TODO: Support scattered relocations.
799 StringRef res;
800 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
801
802 unsigned Arch = getArch();
803 bool isScattered = (Arch != Triple::x86_64) &&
804 (RE->Word0 & macho::RF_Scattered);
805
806 unsigned r_type;
807 if (isScattered)
808 r_type = (RE->Word0 >> 24) & 0xF;
809 else
810 r_type = (RE->Word1 >> 28) & 0xF;
811
812 switch (Arch) {
813 case Triple::x86: {
814 static const char *const Table[] = {
815 "GENERIC_RELOC_VANILLA",
816 "GENERIC_RELOC_PAIR",
817 "GENERIC_RELOC_SECTDIFF",
818 "GENERIC_RELOC_PB_LA_PTR",
819 "GENERIC_RELOC_LOCAL_SECTDIFF",
820 "GENERIC_RELOC_TLV" };
821
822 if (r_type > 6)
823 res = "Unknown";
824 else
825 res = Table[r_type];
826 break;
827 }
828 case Triple::x86_64: {
829 static const char *const Table[] = {
830 "X86_64_RELOC_UNSIGNED",
831 "X86_64_RELOC_SIGNED",
832 "X86_64_RELOC_BRANCH",
833 "X86_64_RELOC_GOT_LOAD",
834 "X86_64_RELOC_GOT",
835 "X86_64_RELOC_SUBTRACTOR",
836 "X86_64_RELOC_SIGNED_1",
837 "X86_64_RELOC_SIGNED_2",
838 "X86_64_RELOC_SIGNED_4",
839 "X86_64_RELOC_TLV" };
840
841 if (r_type > 9)
842 res = "Unknown";
843 else
844 res = Table[r_type];
845 break;
846 }
847 case Triple::arm: {
848 static const char *const Table[] = {
849 "ARM_RELOC_VANILLA",
850 "ARM_RELOC_PAIR",
851 "ARM_RELOC_SECTDIFF",
852 "ARM_RELOC_LOCAL_SECTDIFF",
853 "ARM_RELOC_PB_LA_PTR",
854 "ARM_RELOC_BR24",
855 "ARM_THUMB_RELOC_BR22",
856 "ARM_THUMB_32BIT_BRANCH",
857 "ARM_RELOC_HALF",
858 "ARM_RELOC_HALF_SECTDIFF" };
859
860 if (r_type > 9)
861 res = "Unknown";
862 else
863 res = Table[r_type];
864 break;
865 }
866 case Triple::ppc: {
867 static const char *const Table[] = {
868 "PPC_RELOC_VANILLA",
869 "PPC_RELOC_PAIR",
870 "PPC_RELOC_BR14",
871 "PPC_RELOC_BR24",
872 "PPC_RELOC_HI16",
873 "PPC_RELOC_LO16",
874 "PPC_RELOC_HA16",
875 "PPC_RELOC_LO14",
876 "PPC_RELOC_SECTDIFF",
877 "PPC_RELOC_PB_LA_PTR",
878 "PPC_RELOC_HI16_SECTDIFF",
879 "PPC_RELOC_LO16_SECTDIFF",
880 "PPC_RELOC_HA16_SECTDIFF",
881 "PPC_RELOC_JBSR",
882 "PPC_RELOC_LO14_SECTDIFF",
883 "PPC_RELOC_LOCAL_SECTDIFF" };
884
885 res = Table[r_type];
886 break;
887 }
888 case Triple::UnknownArch:
889 res = "Unknown";
890 break;
891 }
892 Result.append(res.begin(), res.end());
893 return object_error::success;
894 }
895 error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
896 int64_t &Res) const {
897 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
898 bool isExtern = (RE->Word1 >> 27) & 1;
899 Res = 0;
900 if (!isExtern) {
901 const uint8_t* sectAddress = base();
902 if (is64Bit()) {
903 const MachOFormat::Section *Sect = getSection64(Sections[Rel.d.b]);
904 sectAddress += Sect->Offset;
905 } else {
906 const MachOFormat::Section *Sect = getSection(Sections[Rel.d.b]);
907 sectAddress += Sect->Offset;
908 }
909 Res = reinterpret_cast(sectAddress);
910 }
911415 return object_error::success;
912416 }
913417
927431 report_fatal_error(ec.message());
928432 }
929433
930 void MachOObjectFile::printRelocationTargetName(
931 const MachOFormat::RelocationEntry *RE,
932 raw_string_ostream &fmt) const {
434 void
435 MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
436 raw_string_ostream &fmt) const {
933437 unsigned Arch = getArch();
934438 bool isScattered = (Arch != Triple::x86_64) &&
935439 (RE->Word0 & macho::RF_Scattered);
997501 fmt << S;
998502 }
999503
1000 error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
1001 SmallVectorImpl &Result) const {
1002 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
1003
1004 unsigned Arch = getArch();
1005 bool isScattered = (Arch != Triple::x86_64) &&
1006 (RE->Word0 & macho::RF_Scattered);
1007
1008 std::string fmtbuf;
1009 raw_string_ostream fmt(fmtbuf);
1010
1011 unsigned Type;
1012 if (isScattered)
1013 Type = (RE->Word0 >> 24) & 0xF;
1014 else
1015 Type = (RE->Word1 >> 28) & 0xF;
1016
1017 bool isPCRel;
1018 if (isScattered)
1019 isPCRel = ((RE->Word0 >> 30) & 1);
1020 else
1021 isPCRel = ((RE->Word1 >> 24) & 1);
1022
1023 // Determine any addends that should be displayed with the relocation.
1024 // These require decoding the relocation type, which is triple-specific.
1025
1026 // X86_64 has entirely custom relocation types.
1027 if (Arch == Triple::x86_64) {
1028 bool isPCRel = ((RE->Word1 >> 24) & 1);
1029
1030 switch (Type) {
1031 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
1032 case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
1033 printRelocationTargetName(RE, fmt);
1034 fmt << "@GOT";
1035 if (isPCRel) fmt << "PCREL";
1036 break;
1037 }
1038 case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
1039 DataRefImpl RelNext = Rel;
1040 RelNext.d.a++;
1041 const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1042
1043 // X86_64_SUBTRACTOR must be followed by a relocation of type
1044 // X86_64_RELOC_UNSIGNED.
1045 // NOTE: Scattered relocations don't exist on x86_64.
1046 unsigned RType = (RENext->Word1 >> 28) & 0xF;
1047 if (RType != 0)
1048 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
1049 "X86_64_RELOC_SUBTRACTOR.");
1050
1051 // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
1052 // X86_64_SUBTRACTOR contains to the subtrahend.
1053 printRelocationTargetName(RENext, fmt);
1054 fmt << "-";
1055 printRelocationTargetName(RE, fmt);
1056 break;
1057 }
1058 case macho::RIT_X86_64_TLV:
1059 printRelocationTargetName(RE, fmt);
1060 fmt << "@TLV";
1061 if (isPCRel) fmt << "P";
1062 break;
1063 case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
1064 printRelocationTargetName(RE, fmt);
1065 fmt << "-1";
1066 break;
1067 case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
1068 printRelocationTargetName(RE, fmt);
1069 fmt << "-2";
1070 break;
1071 case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
1072 printRelocationTargetName(RE, fmt);
1073 fmt << "-4";
1074 break;
1075 default:
1076 printRelocationTargetName(RE, fmt);
1077 break;
1078 }
1079 // X86 and ARM share some relocation types in common.
1080 } else if (Arch == Triple::x86 || Arch == Triple::arm) {
1081 // Generic relocation types...
1082 switch (Type) {
1083 case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
1084 return object_error::success;
1085 case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
1086 DataRefImpl RelNext = Rel;
1087 RelNext.d.a++;
1088 const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1089
1090 // X86 sect diff's must be followed by a relocation of type
1091 // GENERIC_RELOC_PAIR.
1092 bool isNextScattered = (Arch != Triple::x86_64) &&
1093 (RENext->Word0 & macho::RF_Scattered);
1094 unsigned RType;
1095 if (isNextScattered)
1096 RType = (RENext->Word0 >> 24) & 0xF;
1097 else
1098 RType = (RENext->Word1 >> 28) & 0xF;
1099 if (RType != 1)
1100 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1101 "GENERIC_RELOC_SECTDIFF.");
1102
1103 printRelocationTargetName(RE, fmt);
1104 fmt << "-";
1105 printRelocationTargetName(RENext, fmt);
1106 break;
1107 }
1108 }
1109
1110 if (Arch == Triple::x86) {
1111 // All X86 relocations that need special printing were already
1112 // handled in the generic code.
1113 switch (Type) {
1114 case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
1115 DataRefImpl RelNext = Rel;
1116 RelNext.d.a++;
1117 const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1118
1119 // X86 sect diff's must be followed by a relocation of type
1120 // GENERIC_RELOC_PAIR.
1121 bool isNextScattered = (Arch != Triple::x86_64) &&
1122 (RENext->Word0 & macho::RF_Scattered);
1123 unsigned RType;
1124 if (isNextScattered)
1125 RType = (RENext->Word0 >> 24) & 0xF;
1126 else
1127 RType = (RENext->Word1 >> 28) & 0xF;
1128 if (RType != 1)
1129 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
1130 "GENERIC_RELOC_LOCAL_SECTDIFF.");
1131
1132 printRelocationTargetName(RE, fmt);
1133 fmt << "-";
1134 printRelocationTargetName(RENext, fmt);
1135 break;
1136 }
1137 case macho::RIT_Generic_TLV: {
1138 printRelocationTargetName(RE, fmt);
1139 fmt << "@TLV";
1140 if (isPCRel) fmt << "P";
1141 break;
1142 }
1143 default:
1144 printRelocationTargetName(RE, fmt);
1145 }
1146 } else { // ARM-specific relocations
1147 switch (Type) {
1148 case macho::RIT_ARM_Half: // ARM_RELOC_HALF
1149 case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
1150 // Half relocations steal a bit from the length field to encode
1151 // whether this is an upper16 or a lower16 relocation.
1152 bool isUpper;
1153 if (isScattered)
1154 isUpper = (RE->Word0 >> 28) & 1;
1155 else
1156 isUpper = (RE->Word1 >> 25) & 1;
1157
1158 if (isUpper)
1159 fmt << ":upper16:(";
1160 else
1161 fmt << ":lower16:(";
1162 printRelocationTargetName(RE, fmt);
1163
1164 DataRefImpl RelNext = Rel;
1165 RelNext.d.a++;
1166 const MachOFormat::RelocationEntry *RENext = getRelocation(RelNext);
1167
1168 // ARM half relocs must be followed by a relocation of type
1169 // ARM_RELOC_PAIR.
1170 bool isNextScattered = (Arch != Triple::x86_64) &&
1171 (RENext->Word0 & macho::RF_Scattered);
1172 unsigned RType;
1173 if (isNextScattered)
1174 RType = (RENext->Word0 >> 24) & 0xF;
1175 else
1176 RType = (RENext->Word1 >> 28) & 0xF;
1177
1178 if (RType != 1)
1179 report_fatal_error("Expected ARM_RELOC_PAIR after "
1180 "GENERIC_RELOC_HALF");
1181
1182 // NOTE: The half of the target virtual address is stashed in the
1183 // address field of the secondary relocation, but we can't reverse
1184 // engineer the constant offset from it without decoding the movw/movt
1185 // instruction to find the other half in its immediate field.
1186
1187 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
1188 // symbol/section pointer of the follow-on relocation.
1189 if (Type == macho::RIT_ARM_HalfDifference) {
1190 fmt << "-";
1191 printRelocationTargetName(RENext, fmt);
1192 }
1193
1194 fmt << ")";
1195 break;
1196 }
1197 default: {
1198 printRelocationTargetName(RE, fmt);
1199 }
1200 }
1201 }
1202 } else
1203 printRelocationTargetName(RE, fmt);
1204
1205 fmt.flush();
1206 Result.append(fmtbuf.begin(), fmtbuf.end());
1207 return object_error::success;
1208 }
1209
1210 error_code MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
1211 bool &Result) const {
1212 const MachOFormat::RelocationEntry *RE = getRelocation(Rel);
1213
1214 unsigned Arch = getArch();
1215 bool isScattered = (Arch != Triple::x86_64) &&
1216 (RE->Word0 & macho::RF_Scattered);
1217 unsigned Type;
1218 if (isScattered)
1219 Type = (RE->Word0 >> 24) & 0xF;
1220 else
1221 Type = (RE->Word1 >> 28) & 0xF;
1222
1223 Result = false;
1224
1225 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
1226 // is always hidden.
1227 if (Arch == Triple::x86 || Arch == Triple::arm) {
1228 if (Type == macho::RIT_Pair) Result = true;
1229 } else if (Arch == Triple::x86_64) {
1230 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
1231 // an X864_64_RELOC_SUBTRACTOR.
1232 if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
1233 DataRefImpl RelPrev = Rel;
1234 RelPrev.d.a--;
1235 const MachOFormat::RelocationEntry *REPrev = getRelocation(RelPrev);
1236
1237 unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
1238
1239 if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
1240 }
1241 }
1242
1243 return object_error::success;
1244 }
1245
1246 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1247 LibraryRef &Res) const {
1248 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1249 }
1250
1251 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1252 StringRef &Res) const {
1253 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
504 error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
505 LibraryRef &Res) const {
506 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
507 }
508
509 error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData,
510 StringRef &Res) const {
511 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
1254512 }
1255513
1256514
1257515 /*===-- Miscellaneous -----------------------------------------------------===*/
1258516
1259 uint8_t MachOObjectFile::getBytesInAddress() const {
517 uint8_t MachOObjectFileBase::getBytesInAddress() const {
1260518 return is64Bit() ? 8 : 4;
1261519 }
1262520
1263 StringRef MachOObjectFile::getFileFormatName() const {
521 StringRef MachOObjectFileBase::getFileFormatName() const {
1264522 if (!is64Bit()) {
1265523 switch (getHeader()->CPUType) {
1266524 case llvm::MachO::CPUTypeI386:
1291549 }
1292550 }
1293551
1294 unsigned MachOObjectFile::getArch() const {
552 unsigned MachOObjectFileBase::getArch() const {
1295553 switch (getHeader()->CPUType) {
1296554 case llvm::MachO::CPUTypeI386:
1297555 return Triple::x86;
5151 static cl::opt
5252 DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
5353
54 static const Target *GetTarget(const MachOObjectFile *MachOObj) {
54 static const Target *GetTarget(const MachOObjectFileBase *MachOObj) {
5555 // Figure out the target triple.
5656 if (TripleName.empty()) {
5757 llvm::Triple TT("unknown-unknown-unknown");
107107
108108 // Print additional information about an address, if available.
109109 static void DumpAddress(uint64_t Address, ArrayRef Sections,
110 const MachOObjectFile *MachOObj, raw_ostream &OS) {
110 const MachOObjectFileBase *MachOObj, raw_ostream &OS) {
111111 for (unsigned i = 0; i != Sections.size(); ++i) {
112112 uint64_t SectAddr = 0, SectSize = 0;
113113 Sections[i].getAddress(SectAddr);
199199 }
200200
201201 static void getSectionsAndSymbols(const MachOFormat::Header *Header,
202 MachOObjectFile *MachOObj,
202 MachOObjectFileBase *MachOObj,
203203 std::vector &Sections,
204204 std::vector &Symbols,
205205 SmallVectorImpl &FoundFns) {
237237 return;
238238 }
239239
240 OwningPtr> MachOOF(static_caste*>(
240 OwningPtrBase> MachOOF(static_caste*>(
241241 ObjectFile::createMachOObjectFile(Buff.take())));
242242
243243 const Target *TheTarget = GetTarget(MachOOF.get());
254254 std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
255255
256256 StringRef SegmentName = "";
257 if (const MachOObjectFile *MachO = dyn_caste>(Obj)) {
257 if (const MachOObjectFileBase *MachO = dyn_caste>(Obj)) {
258258 DataRefImpl DR = i->getRawDataRefImpl();
259259 SegmentName = MachO->getSectionFinalSegmentName(DR);
260260 }
590590 else if (Section == o->end_sections())
591591 outs() << "*UND*";
592592 else {
593 if (const MachOObjectFile *MachO = dyn_caste>(o)) {
593 if (const MachOObjectFileBase *MachO = dyn_caste>(o)) {
594594 DataRefImpl DR = Section->getRawDataRefImpl();
595595 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
596596 outs() << SegmentName << ",";
2626
2727 class MachODumper : public ObjDumper {
2828 public:
29 MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer)
29 MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer)
3030 : ObjDumper(Writer)
3131 , Obj(Obj) { }
3232
4242
4343 void printRelocation(section_iterator SecI, relocation_iterator RelI);
4444
45 const llvm::object::MachOObjectFile *Obj;
45 const llvm::object::MachOObjectFileBase *Obj;
4646 };
4747
4848 } // namespace
5353 error_code createMachODumper(const object::ObjectFile *Obj,
5454 StreamWriter& Writer,
5555 OwningPtr &Result) {
56 const MachOObjectFile *MachOObj = dyn_caste>(Obj);
56 const MachOObjectFileBase *MachOObj = dyn_caste>(Obj);
5757 if (!MachOObj)
5858 return readobj_error::unsupported_obj_file_format;
5959
156156 };
157157 }
158158
159 static void getSection(const MachOObjectFile *Obj,
159 static void getSection(const MachOObjectFileBase *Obj,
160160 DataRefImpl DRI,
161161 MachOSection &Section) {
162 if (Obj->is64Bit()) {
163 const MachOFormat::Section *Sect = Obj->getSection64(DRI);
162 if (const MachOObjectFile *O = dyn_cast >(Obj)) {
163 const MachOObjectFile::Section *Sect = O->getSection(DRI);
164164
165165 Section.Address = Sect->Address;
166166 Section.Size = Sect->Size;
172172 Section.Reserved1 = Sect->Reserved1;
173173 Section.Reserved2 = Sect->Reserved2;
174174 } else {
175 const MachOFormat::Section *Sect = Obj->getSection(DRI);
175 const MachOObjectFile *O2 = cast >(Obj);
176 const MachOObjectFile::Section *Sect = O2->getSection(DRI);
176177
177178 Section.Address = Sect->Address;
178179 Section.Size = Sect->Size;
186187 }
187188 }
188189
189 static void getSymbol(const MachOObjectFile *Obj,
190 static void getSymbol(const MachOObjectFileBase *Obj,
190191 DataRefImpl DRI,
191192 MachOSymbol &Symbol) {
192 if (Obj->is64Bit()) {
193 const MachOFormat::SymbolTableEntry *Entry =
194 Obj->getSymbol64TableEntry(DRI);
193 if (const MachOObjectFile *O = dyn_cast >(Obj)) {
194 const MachOObjectFile::SymbolTableEntry *Entry =
195 O->getSymbolTableEntry(DRI);
195196 Symbol.StringIndex = Entry->StringIndex;
196197 Symbol.Type = Entry->Type;
197198 Symbol.SectionIndex = Entry->SectionIndex;
198199 Symbol.Flags = Entry->Flags;
199200 Symbol.Value = Entry->Value;
200201 } else {
201 const MachOFormat::SymbolTableEntry *Entry =
202 Obj->getSymbolTableEntry(DRI);
202 const MachOObjectFile *O2 = cast >(Obj);
203 const MachOObjectFile::SymbolTableEntry *Entry =
204 O2->getSymbolTableEntry(DRI);
203205 Symbol.StringIndex = Entry->StringIndex;
204206 Symbol.Type = Entry->Type;
205207 Symbol.SectionIndex = Entry->SectionIndex;
232232 // On Darwin we may find DWARF in separate object file in
233233 // resource directory.
234234 ObjectFile *DbgObj = Obj;
235 if (isa>(Obj)) {
235 if (isaBase>(Obj)) {
236236 const std::string &ResourceName =
237237 getDarwinDWARFResourceForModule(ModuleName);
238238 ObjectFile *ResourceObj = getObjectFile(ResourceName);