llvm.org GIT mirror llvm / da2a237
Finish templating MachObjectFile over endianness. We are now able to handle big endian macho files in llvm-readobject. Thanks to David Fang for providing the object files. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179440 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
10 changed file(s) with 1357 addition(s) and 597 deletion(s). Raw diff Collapse all Expand all
1919 #include "llvm/ADT/Triple.h"
2020 #include "llvm/Object/MachOFormat.h"
2121 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Support/Casting.h"
2223 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Format.h"
2325 #include "llvm/Support/MachO.h"
2426 #include "llvm/Support/raw_ostream.h"
2527
3234 struct MachOType {
3335 static const endianness TargetEndianness = E;
3436 static const bool Is64Bits = B;
37 };
38
39 template
40 struct MachOInt24Impl;
41
42 template<>
43 struct MachOInt24Impl {
44 uint8_t bytes[3];
45 operator uint32_t() const {
46 return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];
47 }
48 };
49
50 template<>
51 struct MachOInt24Impl {
52 uint8_t bytes[3];
53 operator uint32_t() const {
54 return (bytes[0] << 24) | (bytes[1] << 16) | bytes[2];
55 }
3556 };
3657
3758 template
4263 MachOInt32;
4364 typedef support::detail::packed_endian_specific_integral
4465 MachOInt64;
66 typedef MachOInt24Impl MachOInt24;
4567 };
4668
4769 #define LLVM_MACHOB_IMPORT_TYPES(E) \
4870 typedef typename MachODataTypeTypedefHelperCommon::MachOInt16 MachOInt16; \
4971 typedef typename MachODataTypeTypedefHelperCommon::MachOInt32 MachOInt32; \
50 typedef typename MachODataTypeTypedefHelperCommon::MachOInt64 MachOInt64;
72 typedef typename MachODataTypeTypedefHelperCommon::MachOInt64 MachOInt64; \
73 typedef typename MachODataTypeTypedefHelperCommon::MachOInt24 MachOInt24;
5174
5275 template
5376 struct MachODataTypeTypedefHelper;
119142 };
120143
121144 template
122 struct RelocationEntry {
123 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
145 struct RelocationEntry;
146
147 template<>
148 struct RelocationEntry {
149 LLVM_MACHOB_IMPORT_TYPES(support::little)
124150 MachOInt32 Address;
125151 MachOInt24 SymbolNum;
126152 uint8_t Bits;
139165 }
140166 };
141167
168 template<>
169 struct RelocationEntry {
170 LLVM_MACHOB_IMPORT_TYPES(support::big)
171 MachOInt32 Address;
172 MachOInt24 SymbolNum;
173 uint8_t Bits;
174
175 unsigned getType() const {
176 return Bits &0xf;
177 }
178 unsigned getExternal() const {
179 return (Bits >> 4) & 0x1;
180 }
181 unsigned getLength() const {
182 return (Bits >> 5) & 0x3;
183 }
184 unsigned getPCRel() const {
185 return Bits >> 7;
186 }
187 };
188
142189 template
143 struct ScatteredRelocationEntry {
144 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
190 struct ScatteredRelocationEntry;
191
192 template<>
193 struct ScatteredRelocationEntry {
194 LLVM_MACHOB_IMPORT_TYPES(support::little)
145195 MachOInt24 Address;
146196 uint8_t Bits;
147197 MachOInt32 Value;
158208 unsigned getScattered() const {
159209 return Bits >> 7;
160210 }
211 };
212
213 template<>
214 struct ScatteredRelocationEntry {
215 LLVM_MACHOB_IMPORT_TYPES(support::big)
216 uint8_t Bits;
217 unsigned getType() const {
218 return Bits & 0xf;
219 }
220 unsigned getLength() const {
221 return (Bits >> 4) & 0x3;
222 }
223 unsigned getPCRel() const {
224 return (Bits >> 6) & 0x1;
225 }
226 unsigned getScattered() const {
227 return Bits >> 7;
228 }
229 MachOInt24 Address;
230 MachOInt32 Value;
161231 };
162232
163233 template
243313
244314 class MachOObjectFileBase : public ObjectFile {
245315 public:
246 typedef MachOFormat::SymbolTableEntryBase
247 SymbolTableEntryBase;
248 typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand;
249 typedef MachOFormat::RelocationEntry RelocationEntry;
250 typedef MachOFormat::ScatteredRelocationEntry
251 ScatteredRelocationEntry;
252316 typedef MachOFormat::SectionBase SectionBase;
253 typedef MachOFormat::LoadCommand LoadCommand;
254 typedef MachOFormat::Header Header;
255 typedef MachOFormat::LinkeditDataLoadCommand
256 LinkeditDataLoadCommand;
257
258 MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
259
260 virtual symbol_iterator begin_symbols() const;
261 virtual symbol_iterator end_symbols() const;
317
318 MachOObjectFileBase(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
319 error_code &ec);
320
262321 virtual symbol_iterator begin_dynamic_symbols() const;
263322 virtual symbol_iterator end_dynamic_symbols() const;
264323 virtual library_iterator begin_libraries_needed() const;
265324 virtual library_iterator end_libraries_needed() const;
266 virtual section_iterator end_sections() const;
267325
268326 virtual uint8_t getBytesInAddress() const;
269 virtual StringRef getFileFormatName() const;
270 virtual unsigned getArch() const;
271327 virtual StringRef getLoadName() const;
272328
273 // In a MachO file, sections have a segment name. This is used in the .o
274 // files. They have a single segment, but this field specifies which segment
275 // a section should be put in in the final object.
276 StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
277
278 // Names are stored as 16 bytes. These returns the raw 16 bytes without
279 // interpreting them as a C string.
280 ArrayRef getSectionRawName(DataRefImpl Sec) const;
281 ArrayRefgetSectionRawFinalSegmentName(DataRefImpl Sec) const;
282
283329 bool is64Bit() const;
284 const LoadCommand *getLoadCommandInfo(unsigned Index) const;
285330 void ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const;
286 const Header *getHeader() const;
287331 unsigned getHeaderSize() const;
288332 StringRef getData(size_t Offset, size_t Size) const;
289 const RelocationEntry *getRelocation(DataRefImpl Rel) const;
290 bool isScattered(const RelocationEntry *RE) const;
291 bool isPCRel(const RelocationEntry *RE) const;
292 unsigned getLength(const RelocationEntry *RE) const;
293 unsigned getType(const RelocationEntry *RE) const;
294333
295334 static inline bool classof(const Binary *v) {
296335 return v->isMachO();
297336 }
298337
299338 protected:
300 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
301 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
302 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
303 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
304 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
305 virtual error_code getSymbolSection(DataRefImpl Symb,
306 section_iterator &Res) const;
339 StringRef parseSegmentOrSectionName(const char *P) const;
340
307341 virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
308 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
309342 virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
310343 virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
311344 virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
326359
327360 typedef SmallVector SectionList;
328361 SectionList Sections;
362 };
363
364 template
365 class MachOObjectFileMiddle : public MachOObjectFileBase {
366 public:
367
368 typedef MachOFormat::SymbolTableEntryBase
369 SymbolTableEntryBase;
370 typedef MachOFormat::LinkeditDataLoadCommand
371 LinkeditDataLoadCommand;
372 typedef MachOFormat::Header Header;
373 typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand;
374 typedef MachOFormat::RelocationEntry RelocationEntry;
375 typedef MachOFormat::ScatteredRelocationEntry
376 ScatteredRelocationEntry;
377 typedef MachOFormat::LoadCommand LoadCommand;
378
379 MachOObjectFileMiddle(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
380
381 const Header *getHeader() const;
382 const LoadCommand *getLoadCommandInfo(unsigned Index) const;
383 const RelocationEntry *getRelocation(DataRefImpl Rel) const;
384 bool isRelocationScattered(const RelocationEntry *RE) const;
385 bool isRelocationPCRel(const RelocationEntry *RE) const;
386 unsigned getRelocationLength(const RelocationEntry *RE) const;
387 unsigned getRelocationTypeImpl(const RelocationEntry *RE) const;
329388
330389 void moveToNextSymbol(DataRefImpl &DRI) const;
331390 void printRelocationTargetName(const RelocationEntry *RE,
332391 raw_string_ostream &fmt) const;
333392 const SectionBase *getSectionBase(DataRefImpl DRI) const;
334393 const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI) const;
394 unsigned getCPUType() const;
395
396 // In a MachO file, sections have a segment name. This is used in the .o
397 // files. They have a single segment, but this field specifies which segment
398 // a section should be put in in the final object.
399 StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
400
401 // Names are stored as 16 bytes. These returns the raw 16 bytes without
402 // interpreting them as a C string.
403 ArrayRef getSectionRawName(DataRefImpl Sec) const;
404 ArrayRef getSectionRawFinalSegmentName(DataRefImpl Sec) const;
405
406 virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
407 virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
408 virtual error_code getSymbolType(DataRefImpl Symb,
409 SymbolRef::Type &Res) const;
410 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
411 virtual error_code getSymbolSection(DataRefImpl Symb,
412 section_iterator &Res) const;
413 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
414 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
415 virtual symbol_iterator begin_symbols() const;
416 virtual unsigned getArch() const;
417 virtual StringRef getFileFormatName() const;
418 virtual symbol_iterator end_symbols() const;
419 virtual section_iterator end_sections() const;
420
421 static bool classof(const Binary *v);
335422
336423 private:
337
338 const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI,
339 const SymtabLoadCommand *SymtabLoadCmd) const;
424 // Helper to advance a section or symbol iterator multiple increments at a
425 // time.
426 template
427 static error_code advance(T &it, size_t Val);
428
429 template
430 static void advanceTo(T &it, size_t Val);
340431 };
341432
342433 template
368459 };
369460
370461 template
371 class MachOObjectFile : public MachOObjectFileBase {
462 class MachOObjectFile : public MachOObjectFileMiddle {
372463 public:
373464 static const endianness TargetEndianness = MachOT::TargetEndianness;
374465 static const bool Is64Bits = MachOT::Is64Bits;
466
467 typedef MachOObjectFileMiddle Base;
468 typedef typename Base::RelocationEntry RelocationEntry;
469 typedef typename Base::SectionBase SectionBase;
470 typedef typename Base::SymbolTableEntryBase SymbolTableEntryBase;
471 typedef typename Base::LoadCommand LoadCommand;
375472
376473 typedef MachOObjectFileHelper Helper;
377474 static const macho::LoadCommandType SegmentLoadType = Helper::SegmentLoadType;
412509 void moveToNextSection(DataRefImpl &DRI) const;
413510 };
414511
512 typedef MachOObjectFileMiddle MachOObjectFileLE;
513 typedef MachOObjectFileMiddle MachOObjectFileBE;
514
515 typedef MachOObjectFile >
516 MachOObjectFileLE32;
517 typedef MachOObjectFile >
518 MachOObjectFileBE32;
519 typedef MachOObjectFile >
520 MachOObjectFileLE64;
521 typedef MachOObjectFile >
522 MachOObjectFileBE64;
523
524 template
525 MachOObjectFileMiddle::MachOObjectFileMiddle(MemoryBuffer *O,
526 bool Is64Bits,
527 error_code &ec) :
528 MachOObjectFileBase(O, TargetEndianness == support::little, Is64Bits, ec) {
529 }
530
531 template
532 const typename MachOObjectFileMiddle::SymbolTableEntryBase *
533 MachOObjectFileMiddle::getSymbolTableEntryBase(DataRefImpl DRI) const {
534 const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
535 const SymtabLoadCommand *S = reinterpret_cast(L);
536
537 unsigned Index = DRI.d.b;
538
539 unsigned SymbolTableEntrySize = is64Bit() ?
540 sizeof(MachOObjectFileLE64::SymbolTableEntry) :
541 sizeof(MachOObjectFileLE32::SymbolTableEntry);
542
543 uint64_t Offset = S->SymbolTableOffset + Index * SymbolTableEntrySize;
544 StringRef Data = getData(Offset, SymbolTableEntrySize);
545 return reinterpret_cast(Data.data());
546 }
547
548 template
549 const typename MachOObjectFileMiddle::Header *
550 MachOObjectFileMiddle::getHeader() const {
551 StringRef Data = getData(0, sizeof(Header));
552 return reinterpret_cast(Data.data());
553 }
554
555 template
556 const typename MachOObjectFileMiddle::LoadCommand *
557 MachOObjectFileMiddle::getLoadCommandInfo(unsigned Index) const {
558 assert(Index < getHeader()->NumLoadCommands);
559 uint64_t Offset;
560 uint64_t NewOffset = getHeaderSize();
561 const LoadCommand *Load;
562 unsigned I = 0;
563 do {
564 Offset = NewOffset;
565 StringRef Data = getData(Offset, sizeof(MachOObjectFileLE::LoadCommand));
566 Load = reinterpret_cast(Data.data());
567 NewOffset = Offset + Load->Size;
568 ++I;
569 } while (I != Index + 1);
570
571 return reinterpret_cast(Load);
572 }
573
574 template
575 const typename MachOObjectFileMiddle::RelocationEntry *
576 MachOObjectFileMiddle::getRelocation(DataRefImpl Rel) const {
577 if (const MachOObjectFile > *O =
578 dyn_cast > >(this))
579 return O->getRelocation(Rel);
580
581 const MachOObjectFile > *O =
582 cast > >(this);
583 return O->getRelocation(Rel);
584 }
585
586 template
587 bool
588 MachOObjectFileMiddle::isRelocationScattered(const RelocationEntry *RE)
589 const {
590 if (this->getCPUType() == llvm::MachO::CPUTypeX86_64)
591 return false;
592 return RE->Address & macho::RF_Scattered;
593 }
594
595 template
596 bool
597 MachOObjectFileMiddle::isRelocationPCRel(const RelocationEntry *RE) const {
598 typedef MachOObjectFileMiddle ObjType;
599 if (isRelocationScattered(RE)) {
600 const ObjType::ScatteredRelocationEntry *SRE =
601 reinterpret_cast(RE);
602 return SRE->getPCRel();
603 }
604 return RE->getPCRel();
605 }
606
607 template
608 unsigned
609 MachOObjectFileMiddle::getRelocationLength(const RelocationEntry *RE) const {
610 typedef MachOObjectFileMiddle ObjType;
611 if (isRelocationScattered(RE)) {
612 const ObjType::ScatteredRelocationEntry *SRE =
613 reinterpret_cast(RE);
614 return SRE->getLength();
615 }
616 return RE->getLength();
617 }
618
619 template
620 unsigned
621 MachOObjectFileMiddle::getRelocationTypeImpl(const RelocationEntry *RE)
622 const {
623 typedef MachOObjectFileMiddle ObjType;
624 if (isRelocationScattered(RE)) {
625 const ObjType::ScatteredRelocationEntry *SRE =
626 reinterpret_cast(RE);
627 return SRE->getType();
628 }
629 return RE->getType();
630 }
631
632 // Helper to advance a section or symbol iterator multiple increments at a time.
633 template
634 template
635 error_code MachOObjectFileMiddle::advance(T &it, size_t Val) {
636 error_code ec;
637 while (Val--) {
638 it.increment(ec);
639 }
640 return ec;
641 }
642
643 template
644 template
645 void MachOObjectFileMiddle::advanceTo(T &it, size_t Val) {
646 if (error_code ec = advance(it, Val))
647 report_fatal_error(ec.message());
648 }
649
650 template
651 void
652 MachOObjectFileMiddle::printRelocationTargetName(const RelocationEntry *RE,
653 raw_string_ostream &fmt) const {
654 bool IsScattered = isRelocationScattered(RE);
655
656 // Target of a scattered relocation is an address. In the interest of
657 // generating pretty output, scan through the symbol table looking for a
658 // symbol that aligns with that address. If we find one, print it.
659 // Otherwise, we just print the hex address of the target.
660 if (IsScattered) {
661 uint32_t Val = RE->SymbolNum;
662
663 error_code ec;
664 for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
665 SI.increment(ec)) {
666 if (ec) report_fatal_error(ec.message());
667
668 uint64_t Addr;
669 StringRef Name;
670
671 if ((ec = SI->getAddress(Addr)))
672 report_fatal_error(ec.message());
673 if (Addr != Val) continue;
674 if ((ec = SI->getName(Name)))
675 report_fatal_error(ec.message());
676 fmt << Name;
677 return;
678 }
679
680 // If we couldn't find a symbol that this relocation refers to, try
681 // to find a section beginning instead.
682 for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
683 SI.increment(ec)) {
684 if (ec) report_fatal_error(ec.message());
685
686 uint64_t Addr;
687 StringRef Name;
688
689 if ((ec = SI->getAddress(Addr)))
690 report_fatal_error(ec.message());
691 if (Addr != Val) continue;
692 if ((ec = SI->getName(Name)))
693 report_fatal_error(ec.message());
694 fmt << Name;
695 return;
696 }
697
698 fmt << format("0x%x", Val);
699 return;
700 }
701
702 StringRef S;
703 bool isExtern = RE->getExternal();
704 uint64_t Val = RE->Address;
705
706 if (isExtern) {
707 symbol_iterator SI = begin_symbols();
708 advanceTo(SI, Val);
709 SI->getName(S);
710 } else {
711 section_iterator SI = begin_sections();
712 advanceTo(SI, Val);
713 SI->getName(S);
714 }
715
716 fmt << S;
717 }
718
719 template
720 const typename MachOObjectFileMiddle::SectionBase *
721 MachOObjectFileMiddle::getSectionBase(DataRefImpl DRI) const {
722 uintptr_t CommandAddr =
723 reinterpret_cast(getLoadCommandInfo(DRI.d.a));
724
725 bool Is64 = is64Bit();
726 unsigned SegmentLoadSize =
727 Is64 ? sizeof(MachOObjectFileLE64::SegmentLoadCommand) :
728 sizeof(MachOObjectFileLE32::SegmentLoadCommand);
729 unsigned SectionSize = Is64 ? sizeof(MachOObjectFileLE64::Section) :
730 sizeof(MachOObjectFileLE32::Section);
731
732 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
733 return reinterpret_cast(SectionAddr);
734 }
735
736 template
737 unsigned MachOObjectFileMiddle::getCPUType() const {
738 return getHeader()->CPUType;
739 }
740
741 template
742 void MachOObjectFileMiddle::moveToNextSymbol(DataRefImpl &DRI) const {
743 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
744 while (DRI.d.a < LoadCommandCount) {
745 const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
746 if (L->Type == macho::LCT_Symtab) {
747 const SymtabLoadCommand *S =
748 reinterpret_cast(L);
749 if (DRI.d.b < S->NumSymbolTableEntries)
750 return;
751 }
752
753 DRI.d.a++;
754 DRI.d.b = 0;
755 }
756 }
757
758 template
759 StringRef
760 MachOObjectFileMiddle::getSectionFinalSegmentName(DataRefImpl Sec) const {
761 ArrayRef Raw = getSectionRawFinalSegmentName(Sec);
762 return parseSegmentOrSectionName(Raw.data());
763 }
764
765 template
766 ArrayRef
767 MachOObjectFileMiddle::getSectionRawName(DataRefImpl Sec) const {
768 const SectionBase *Base = getSectionBase(Sec);
769 return ArrayRef(Base->Name);
770 }
771
772 template
773 ArrayRef
774 MachOObjectFileMiddle::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
775 const SectionBase *Base = getSectionBase(Sec);
776 return ArrayRef(Base->SegmentName);
777 }
778
779 template
780 error_code MachOObjectFileMiddle::getSymbolFlags(DataRefImpl DRI,
781 uint32_t &Result) const {
782 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
783
784 uint8_t MachOType = Entry->Type;
785 uint16_t MachOFlags = Entry->Flags;
786
787 // TODO: Correctly set SF_ThreadLocal
788 Result = SymbolRef::SF_None;
789
790 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
791 Result |= SymbolRef::SF_Undefined;
792
793 if (MachOFlags & macho::STF_StabsEntryMask)
794 Result |= SymbolRef::SF_FormatSpecific;
795
796 if (MachOType & MachO::NlistMaskExternal) {
797 Result |= SymbolRef::SF_Global;
798 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
799 Result |= SymbolRef::SF_Common;
800 }
801
802 if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
803 Result |= SymbolRef::SF_Weak;
804
805 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
806 Result |= SymbolRef::SF_Absolute;
807
808 return object_error::success;
809 }
810
811 template
812 error_code MachOObjectFileMiddle::getSymbolType(DataRefImpl Symb,
813 SymbolRef::Type &Res) const {
814 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
815 uint8_t n_type = Entry->Type;
816
817 Res = SymbolRef::ST_Other;
818
819 // If this is a STAB debugging symbol, we can do nothing more.
820 if (n_type & MachO::NlistMaskStab) {
821 Res = SymbolRef::ST_Debug;
822 return object_error::success;
823 }
824
825 switch (n_type & MachO::NlistMaskType) {
826 case MachO::NListTypeUndefined :
827 Res = SymbolRef::ST_Unknown;
828 break;
829 case MachO::NListTypeSection :
830 Res = SymbolRef::ST_Function;
831 break;
832 }
833 return object_error::success;
834 }
835
836 template
837 error_code MachOObjectFileMiddle::getSymbolName(DataRefImpl Symb,
838 StringRef &Res) const {
839 const LoadCommand *L = getLoadCommandInfo(Symb.d.a);
840 const SymtabLoadCommand *S = reinterpret_cast(L);
841 StringRef StringTable = getData(S->StringTableOffset, S->StringTableSize);
842 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
843 const char *Start = &StringTable.data()[Entry->StringIndex];
844 Res = StringRef(Start);
845 return object_error::success;
846 }
847
848 template
849 error_code
850 MachOObjectFileMiddle::getSymbolSection(DataRefImpl Symb,
851 section_iterator &Res) const {
852 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
853 uint8_t index = Entry->SectionIndex;
854
855 if (index == 0)
856 Res = end_sections();
857 else
858 Res = section_iterator(SectionRef(Sections[index-1], this));
859
860 return object_error::success;
861 }
862
863
864 template
865 error_code MachOObjectFileMiddle::getSymbolNMTypeChar(DataRefImpl Symb,
866 char &Res) const {
867 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
868 uint8_t Type = Entry->Type;
869 uint16_t Flags = Entry->Flags;
870
871 char Char;
872 switch (Type & macho::STF_TypeMask) {
873 case macho::STT_Undefined:
874 Char = 'u';
875 break;
876 case macho::STT_Absolute:
877 case macho::STT_Section:
878 Char = 's';
879 break;
880 default:
881 Char = '?';
882 break;
883 }
884
885 if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
886 Char = toupper(static_cast(Char));
887 Res = Char;
888 return object_error::success;
889 }
890
891 template
892 error_code
893 MachOObjectFileMiddle::getSectionName(DataRefImpl Sec,
894 StringRef &Result) const {
895 ArrayRef Raw = getSectionRawName(Sec);
896 Result = parseSegmentOrSectionName(Raw.data());
897 return object_error::success;
898 }
899
900 template
901 error_code MachOObjectFileMiddle::getSymbolNext(DataRefImpl Symb,
902 SymbolRef &Res) const {
903 Symb.d.b++;
904 moveToNextSymbol(Symb);
905 Res = SymbolRef(Symb, this);
906 return object_error::success;
907 }
908
909 template
910 symbol_iterator MachOObjectFileMiddle::begin_symbols() const {
911 // DRI.d.a = segment number; DRI.d.b = symbol index.
912 DataRefImpl DRI;
913 moveToNextSymbol(DRI);
914 return symbol_iterator(SymbolRef(DRI, this));
915 }
916
917 template
918 unsigned MachOObjectFileMiddle::getArch() const {
919 switch (getCPUType()) {
920 case llvm::MachO::CPUTypeI386:
921 return Triple::x86;
922 case llvm::MachO::CPUTypeX86_64:
923 return Triple::x86_64;
924 case llvm::MachO::CPUTypeARM:
925 return Triple::arm;
926 case llvm::MachO::CPUTypePowerPC:
927 return Triple::ppc;
928 case llvm::MachO::CPUTypePowerPC64:
929 return Triple::ppc64;
930 default:
931 return Triple::UnknownArch;
932 }
933 }
934
935 template
936 StringRef MachOObjectFileMiddle::getFileFormatName() const {
937 unsigned CPUType = getCPUType();
938 if (!is64Bit()) {
939 switch (CPUType) {
940 case llvm::MachO::CPUTypeI386:
941 return "Mach-O 32-bit i386";
942 case llvm::MachO::CPUTypeARM:
943 return "Mach-O arm";
944 case llvm::MachO::CPUTypePowerPC:
945 return "Mach-O 32-bit ppc";
946 default:
947 assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&
948 "64-bit object file when we're not 64-bit?");
949 return "Mach-O 32-bit unknown";
950 }
951 }
952
953 // Make sure the cpu type has the correct mask.
954 assert((CPUType & llvm::MachO::CPUArchABI64)
955 == llvm::MachO::CPUArchABI64 &&
956 "32-bit object file when we're 64-bit?");
957
958 switch (CPUType) {
959 case llvm::MachO::CPUTypeX86_64:
960 return "Mach-O 64-bit x86-64";
961 case llvm::MachO::CPUTypePowerPC64:
962 return "Mach-O 64-bit ppc64";
963 default:
964 return "Mach-O 64-bit unknown";
965 }
966 }
967
968 template
969 symbol_iterator MachOObjectFileMiddle::end_symbols() const {
970 DataRefImpl DRI;
971 DRI.d.a = getHeader()->NumLoadCommands;
972 return symbol_iterator(SymbolRef(DRI, this));
973 }
974
975 template
976 section_iterator MachOObjectFileMiddle::end_sections() const {
977 DataRefImpl DRI;
978 DRI.d.a = getHeader()->NumLoadCommands;
979 return section_iterator(SectionRef(DRI, this));
980 }
981
982 template
983 bool MachOObjectFileMiddle::classof(const Binary *v) {
984 return isa > >(v) ||
985 isa > >(v);
986 }
987
415988 template
416989 MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
417990 error_code &ec) :
418 MachOObjectFileBase(Object, Is64Bits, ec) {
991 MachOObjectFileMiddle(Object, Is64Bits, ec) {
419992 DataRefImpl DRI;
420993 moveToNextSection(DRI);
421 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
994 uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
422995 while (DRI.d.a < LoadCommandCount) {
423 Sections.push_back(DRI);
996 this->Sections.push_back(DRI);
424997 DRI.d.b++;
425998 moveToNextSection(DRI);
426999 }
4281001
4291002 template
4301003 bool MachOObjectFile::classof(const Binary *v) {
431 return v->getType() == getMachOType(true, Is64Bits);
1004 return v->getType() ==
1005 Base::getMachOType(TargetEndianness == support::little, Is64Bits);
4321006 }
4331007
4341008 template
4351009 const typename MachOObjectFile::Section *
4361010 MachOObjectFile::getSection(DataRefImpl DRI) const {
437 const SectionBase *Addr = getSectionBase(DRI);
1011 const SectionBase *Addr = this->getSectionBase(DRI);
4381012 return reinterpret_cast(Addr);
4391013 }
4401014
4411015 template
4421016 const typename MachOObjectFile::SymbolTableEntry *
4431017 MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
444 const SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI);
1018 const SymbolTableEntryBase *Base = this->getSymbolTableEntryBase(DRI);
4451019 return reinterpret_cast(Base);
4461020 }
4471021
4481022 template
4491023 const typename MachOObjectFile::RelocationEntry *
4501024 MachOObjectFile::getRelocation(DataRefImpl Rel) const {
451 const Section *Sect = getSection(Sections[Rel.d.b]);
1025 const Section *Sect = getSection(this->Sections[Rel.d.b]);
4521026 uint32_t RelOffset = Sect->RelocationTableOffset;
4531027 uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);
454 StringRef Data = getData(Offset, sizeof(RelocationEntry));
1028 StringRef Data = this->getData(Offset, sizeof(RelocationEntry));
4551029 return reinterpret_cast(Data.data());
4561030 }
4571031
4781052 MachOObjectFile::getSectionContents(DataRefImpl Sec,
4791053 StringRef &Res) const {
4801054 const Section *Sect = getSection(Sec);
481 Res = getData(Sect->Offset, Sect->Size);
1055 Res = this->getData(Sect->Offset, Sect->Size);
4821056 return object_error::success;
4831057 }
4841058
5161090 uint32_t LastReloc = Sect->NumRelocationTableEntries;
5171091 DataRefImpl Ret;
5181092 Ret.d.a = LastReloc;
519 Ret.d.b = getSectionIndex(Sec);
1093 Ret.d.b = this->getSectionIndex(Sec);
5201094 return relocation_iterator(RelocationRef(Ret, this));
5211095 }
5221096
5241098 error_code
5251099 MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
5261100 uint64_t &Res) const {
527 const Section *Sect = getSection(Sections[Rel.d.b]);
1101 const Section *Sect = getSection(this->Sections[Rel.d.b]);
5281102 uint64_t SectAddress = Sect->Address;
5291103 const RelocationEntry *RE = getRelocation(Rel);
5301104
5311105 uint64_t RelAddr;
532 if (isScattered(RE))
1106 if (this->isRelocationScattered(RE))
5331107 RelAddr = RE->Address & 0xFFFFFF;
5341108 else
5351109 RelAddr = RE->Address;
5431117 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
5441118 uint64_t &Res) const {
5451119 const RelocationEntry *RE = getRelocation(Rel);
546 if (isScattered(RE))
1120 if (this->isRelocationScattered(RE))
5471121 Res = RE->Address & 0xFFFFFF;
5481122 else
5491123 Res = RE->Address;
5591133 bool isExtern = RE->getExternal();
5601134
5611135 DataRefImpl Sym;
562 moveToNextSymbol(Sym);
1136 this->moveToNextSymbol(Sym);
5631137 if (isExtern) {
5641138 for (unsigned i = 0; i < SymbolIdx; i++) {
5651139 Sym.d.b++;
566 moveToNextSymbol(Sym);
567 assert(Sym.d.a < getHeader()->NumLoadCommands &&
1140 this->moveToNextSymbol(Sym);
1141 assert(Sym.d.a < this->getHeader()->NumLoadCommands &&
5681142 "Relocation symbol index out of range!");
5691143 }
5701144 }
5761150 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
5771151 uint64_t &Res) const {
5781152 const RelocationEntry *RE = getRelocation(Rel);
579 Res = getType(RE);
1153 Res = this->getRelocationTypeImpl(RE);
5801154 return object_error::success;
5811155 }
5821156
5881162 StringRef res;
5891163 const RelocationEntry *RE = getRelocation(Rel);
5901164
591 unsigned Arch = getArch();
592
593 unsigned r_type = getType(RE);
1165 unsigned Arch = this->getArch();
1166
1167 unsigned r_type = this->getRelocationTypeImpl(RE);
5941168
5951169 switch (Arch) {
5961170 case Triple::x86: {
6821256 SmallVectorImpl &Result) const {
6831257 const RelocationEntry *RE = getRelocation(Rel);
6841258
685 unsigned Arch = getArch();
686 bool IsScattered = isScattered(RE);
1259 unsigned Arch = this->getArch();
1260 bool IsScattered = this->isRelocationScattered(RE);
6871261
6881262 std::string fmtbuf;
6891263 raw_string_ostream fmt(fmtbuf);
6901264
691 unsigned Type = getType(RE);
692 bool IsPCRel = isPCRel(RE);
1265 unsigned Type = this->getRelocationTypeImpl(RE);
1266 bool IsPCRel = this->isRelocationPCRel(RE);
6931267
6941268 // Determine any addends that should be displayed with the relocation.
6951269 // These require decoding the relocation type, which is triple-specific.
7011275 switch (Type) {
7021276 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
7031277 case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
704 printRelocationTargetName(RE, fmt);
1278 this->printRelocationTargetName(RE, fmt);
7051279 fmt << "@GOT";
7061280 if (isPCRel) fmt << "PCREL";
7071281 break;
7211295
7221296 // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
7231297 // X86_64_SUBTRACTOR contains to the subtrahend.
724 printRelocationTargetName(RENext, fmt);
1298 this->printRelocationTargetName(RENext, fmt);
7251299 fmt << "-";
726 printRelocationTargetName(RE, fmt);
1300 this->printRelocationTargetName(RE, fmt);
7271301 break;
7281302 }
7291303 case macho::RIT_X86_64_TLV:
730 printRelocationTargetName(RE, fmt);
1304 this->printRelocationTargetName(RE, fmt);
7311305 fmt << "@TLV";
7321306 if (isPCRel) fmt << "P";
7331307 break;
7341308 case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
735 printRelocationTargetName(RE, fmt);
1309 this->printRelocationTargetName(RE, fmt);
7361310 fmt << "-1";
7371311 break;
7381312 case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
739 printRelocationTargetName(RE, fmt);
1313 this->printRelocationTargetName(RE, fmt);
7401314 fmt << "-2";
7411315 break;
7421316 case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
743 printRelocationTargetName(RE, fmt);
1317 this->printRelocationTargetName(RE, fmt);
7441318 fmt << "-4";
7451319 break;
7461320 default:
747 printRelocationTargetName(RE, fmt);
1321 this->printRelocationTargetName(RE, fmt);
7481322 break;
7491323 }
7501324 // X86 and ARM share some relocation types in common.
7711345 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
7721346 "GENERIC_RELOC_SECTDIFF.");
7731347
774 printRelocationTargetName(RE, fmt);
1348 this->printRelocationTargetName(RE, fmt);
7751349 fmt << "-";
776 printRelocationTargetName(RENext, fmt);
1350 this->printRelocationTargetName(RENext, fmt);
7771351 break;
7781352 }
7791353 }
8001374 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
8011375 "GENERIC_RELOC_LOCAL_SECTDIFF.");
8021376
803 printRelocationTargetName(RE, fmt);
1377 this->printRelocationTargetName(RE, fmt);
8041378 fmt << "-";
805 printRelocationTargetName(RENext, fmt);
1379 this->printRelocationTargetName(RENext, fmt);
8061380 break;
8071381 }
8081382 case macho::RIT_Generic_TLV: {
809 printRelocationTargetName(RE, fmt);
1383 this->printRelocationTargetName(RE, fmt);
8101384 fmt << "@TLV";
8111385 if (IsPCRel) fmt << "P";
8121386 break;
8131387 }
8141388 default:
815 printRelocationTargetName(RE, fmt);
1389 this->printRelocationTargetName(RE, fmt);
8161390 }
8171391 } else { // ARM-specific relocations
8181392 switch (Type) {
8301404 fmt << ":upper16:(";
8311405 else
8321406 fmt << ":lower16:(";
833 printRelocationTargetName(RE, fmt);
1407 this->printRelocationTargetName(RE, fmt);
8341408
8351409 DataRefImpl RelNext = Rel;
8361410 RelNext.d.a++;
8591433 // symbol/section pointer of the follow-on relocation.
8601434 if (Type == macho::RIT_ARM_HalfDifference) {
8611435 fmt << "-";
862 printRelocationTargetName(RENext, fmt);
1436 this->printRelocationTargetName(RENext, fmt);
8631437 }
8641438
8651439 fmt << ")";
8661440 break;
8671441 }
8681442 default: {
869 printRelocationTargetName(RE, fmt);
1443 this->printRelocationTargetName(RE, fmt);
8701444 }
8711445 }
8721446 }
8731447 } else
874 printRelocationTargetName(RE, fmt);
1448 this->printRelocationTargetName(RE, fmt);
8751449
8761450 fmt.flush();
8771451 Result.append(fmtbuf.begin(), fmtbuf.end());
8831457 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
8841458 bool &Result) const {
8851459 const RelocationEntry *RE = getRelocation(Rel);
886 unsigned Arch = getArch();
887 unsigned Type = getType(RE);
1460 unsigned Arch = this->getArch();
1461 unsigned Type = this->getRelocationTypeImpl(RE);
8881462
8891463 Result = false;
8901464
8981472 if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
8991473 DataRefImpl RelPrev = Rel;
9001474 RelPrev.d.a--;
901 const RelocationEntry *REPrev = getRelocation(RelPrev);
1475 const RelocationEntry *REPrev = this->getRelocation(RelPrev);
9021476
9031477 unsigned PrevType = REPrev->getType();
9041478
9161490 const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
9171491 Res = Entry->Value;
9181492 if (Entry->SectionIndex) {
919 const Section *Sec = getSection(Sections[Entry->SectionIndex-1]);
1493 const Section *Sec =
1494 this->getSection(this->Sections[Entry->SectionIndex-1]);
9201495 Res += Sec->Offset - Sec->Address;
9211496 }
9221497
9291504 DataRefImpl Symb,
9301505 bool &Result) const {
9311506 SymbolRef::Type ST;
932 getSymbolType(Symb, ST);
1507 this->getSymbolType(Symb, ST);
9331508 if (ST == SymbolRef::ST_Unknown) {
9341509 Result = false;
9351510 return object_error::success;
9581533 template
9591534 error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
9601535 uint64_t &Result) const {
961 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
1536 uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
9621537 uint64_t BeginOffset;
9631538 uint64_t EndOffset = 0;
9641539 uint8_t SectionIndex;
9681543 SectionIndex = Entry->SectionIndex;
9691544 if (!SectionIndex) {
9701545 uint32_t flags = SymbolRef::SF_None;
971 getSymbolFlags(DRI, flags);
1546 this->getSymbolFlags(DRI, flags);
9721547 if (flags & SymbolRef::SF_Common)
9731548 Result = Entry->Value;
9741549 else
9801555 DRI.d.b = 0;
9811556 uint32_t Command = DRI.d.a;
9821557 while (Command == DRI.d.a) {
983 moveToNextSymbol(DRI);
1558 this->moveToNextSymbol(DRI);
9841559 if (DRI.d.a < LoadCommandCount) {
9851560 Entry = getSymbolTableEntry(DRI);
9861561 if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
9911566 }
9921567 if (!EndOffset) {
9931568 uint64_t Size;
994 getSectionSize(Sections[SectionIndex-1], Size);
995 getSectionAddress(Sections[SectionIndex-1], EndOffset);
1569 this->getSectionSize(this->Sections[SectionIndex-1], Size);
1570 this->getSectionAddress(this->Sections[SectionIndex-1], EndOffset);
9961571 EndOffset += Size;
9971572 }
9981573 Result = EndOffset - BeginOffset;
10171592
10181593 template
10191594 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
1020 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
1595 uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
10211596 while (DRI.d.a < LoadCommandCount) {
1022 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
1597 const LoadCommand *Command = this->getLoadCommandInfo(DRI.d.a);
10231598 if (Command->Type == SegmentLoadType) {
10241599 const SegmentLoadCommand *SegmentLoadCmd =
10251600 reinterpret_cast(Command);
10321607 }
10331608 }
10341609
1035 typedef MachOObjectFile >
1036 MachOObjectFile32Le;
1037 typedef MachOObjectFile >
1038 MachOObjectFile64Le;
10391610 }
10401611 }
10411612
2828 namespace llvm {
2929 namespace object {
3030
31 MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits,
31 MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
32 bool IsLittleEndian, bool Is64bits,
3233 error_code &ec)
33 : ObjectFile(getMachOType(true, Is64bits), Object) {
34 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
3435 }
3536
3637 bool MachOObjectFileBase::is64Bit() const {
37 return isa(this);
38 }
39
40 const MachOObjectFileBase::LoadCommand *
41 MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const {
42 uint64_t Offset;
43 uint64_t NewOffset = getHeaderSize();
44 const LoadCommand *Load;
45 unsigned I = 0;
46 do {
47 Offset = NewOffset;
48 StringRef Data = getData(Offset, sizeof(LoadCommand));
49 Load = reinterpret_cast(Data.data());
50 NewOffset = Offset + Load->Size;
51 ++I;
52 } while (I != Index + 1);
53
54 return Load;
38 return isa(this) || isa(this);
5539 }
5640
5741 void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
6650 }
6751 }
6852
69 const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const {
70 StringRef Data = getData(0, sizeof(Header));
71 return reinterpret_cast(Data.data());
72 }
73
7453 unsigned MachOObjectFileBase::getHeaderSize() const {
7554 return is64Bit() ? macho::Header64Size : macho::Header32Size;
7655 }
7756
7857 StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
7958 return ObjectFile::getData().substr(Offset, Size);
80 }
81
82 const MachOObjectFileBase::RelocationEntry *
83 MachOObjectFileBase::getRelocation(DataRefImpl Rel) const {
84 if (const MachOObjectFile32Le *O = dyn_cast(this))
85 return O->getRelocation(Rel);
86 const MachOObjectFile64Le *O = dyn_cast(this);
87 return O->getRelocation(Rel);
88 }
89
90 bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const {
91 unsigned Arch = getArch();
92 return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered);
93 }
94
95 bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const {
96 if (isScattered(RE)) {
97 const ScatteredRelocationEntry *SRE =
98 reinterpret_cast(RE);
99 return SRE->getPCRel();
100 }
101 return RE->getPCRel();
102 }
103
104 unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const {
105 if (isScattered(RE)) {
106 const ScatteredRelocationEntry *SRE =
107 reinterpret_cast(RE);
108 return SRE->getLength();
109 }
110 return RE->getLength();
111 }
112
113 unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const {
114 if (isScattered(RE)) {
115 const ScatteredRelocationEntry *SRE =
116 reinterpret_cast(RE);
117 return SRE->getType();
118 }
119 return RE->getType();
12059 }
12160
12261 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
12362 StringRef Magic = Buffer->getBuffer().slice(0, 4);
12463 error_code ec;
125 bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE";
12664 ObjectFile *Ret;
127 if (Is64Bits)
128 Ret = new MachOObjectFile64Le(Buffer, ec);
65 if (Magic == "\xFE\xED\xFA\xCE")
66 Ret = new MachOObjectFileBE32(Buffer, ec);
67 else if (Magic == "\xCE\xFA\xED\xFE")
68 Ret = new MachOObjectFileLE32(Buffer, ec);
69 else if (Magic == "\xFE\xED\xFA\xCF")
70 Ret = new MachOObjectFileBE64(Buffer, ec);
71 else if (Magic == "\xCF\xFA\xED\xFE")
72 Ret = new MachOObjectFileLE64(Buffer, ec);
12973 else
130 Ret = new MachOObjectFile32Le(Buffer, ec);
74 return NULL;
75
13176 if (ec)
13277 return NULL;
13378 return Ret;
13580
13681 /*===-- Symbols -----------------------------------------------------------===*/
13782
138 void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const {
139 uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
140 while (DRI.d.a < LoadCommandCount) {
141 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
142 if (Command->Type == macho::LCT_Symtab) {
143 const SymtabLoadCommand *SymtabLoadCmd =
144 reinterpret_cast(Command);
145 if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries)
146 return;
147 }
148
149 DRI.d.a++;
150 DRI.d.b = 0;
151 }
152 }
153
154 const MachOObjectFileBase::SymbolTableEntryBase *
155 MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const {
156 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
157 const SymtabLoadCommand *SymtabLoadCmd =
158 reinterpret_cast(Command);
159 return getSymbolTableEntryBase(DRI, SymtabLoadCmd);
160 }
161
162 const MachOObjectFileBase::SymbolTableEntryBase *
163 MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI,
164 const SymtabLoadCommand *SymtabLoadCmd) const {
165 uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset;
166 unsigned Index = DRI.d.b;
167
168 unsigned SymbolTableEntrySize = is64Bit() ?
169 sizeof(MachOObjectFile64Le::SymbolTableEntry) :
170 sizeof(MachOObjectFile32Le::SymbolTableEntry);
171
172 uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
173 StringRef Data = getData(Offset, SymbolTableEntrySize);
174 return reinterpret_cast(Data.data());
175 }
176
177 error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI,
178 SymbolRef &Result) const {
179 DRI.d.b++;
180 moveToNextSymbol(DRI);
181 Result = SymbolRef(DRI, this);
182 return object_error::success;
183 }
184
185 error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI,
186 StringRef &Result) const {
187 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
188 const SymtabLoadCommand *SymtabLoadCmd =
189 reinterpret_cast(Command);
190
191 StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset,
192 SymtabLoadCmd->StringTableSize);
193
194 const SymbolTableEntryBase *Entry =
195 getSymbolTableEntryBase(DRI, SymtabLoadCmd);
196 uint32_t StringIndex = Entry->StringIndex;
197
198 const char *Start = &StringTable.data()[StringIndex];
199 Result = StringRef(Start);
200
201 return object_error::success;
202 }
203
204 error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI,
205 char &Result) const {
206 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
207 uint8_t Type = Entry->Type;
208 uint16_t Flags = Entry->Flags;
209
210 char Char;
211 switch (Type & macho::STF_TypeMask) {
212 case macho::STT_Undefined:
213 Char = 'u';
214 break;
215 case macho::STT_Absolute:
216 case macho::STT_Section:
217 Char = 's';
218 break;
219 default:
220 Char = '?';
221 break;
222 }
223
224 if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
225 Char = toupper(static_cast(Char));
226 Result = Char;
227 return object_error::success;
228 }
229
230 error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI,
231 uint32_t &Result) const {
232 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
233 uint8_t MachOType = Entry->Type;
234 uint16_t MachOFlags = Entry->Flags;
235
236 // TODO: Correctly set SF_ThreadLocal
237 Result = SymbolRef::SF_None;
238
239 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
240 Result |= SymbolRef::SF_Undefined;
241
242 if (MachOFlags & macho::STF_StabsEntryMask)
243 Result |= SymbolRef::SF_FormatSpecific;
244
245 if (MachOType & MachO::NlistMaskExternal) {
246 Result |= SymbolRef::SF_Global;
247 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
248 Result |= SymbolRef::SF_Common;
249 }
250
251 if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
252 Result |= SymbolRef::SF_Weak;
253
254 if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
255 Result |= SymbolRef::SF_Absolute;
256
257 return object_error::success;
258 }
259
260 error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb,
261 section_iterator &Res) const {
262 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
263 uint8_t index = Entry->SectionIndex;
264
265 if (index == 0)
266 Res = end_sections();
267 else
268 Res = section_iterator(SectionRef(Sections[index-1], this));
269
270 return object_error::success;
271 }
272
273 error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb,
274 SymbolRef::Type &Res) const {
275 const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
276 uint8_t n_type = Entry->Type;
277
278 Res = SymbolRef::ST_Other;
279
280 // If this is a STAB debugging symbol, we can do nothing more.
281 if (n_type & MachO::NlistMaskStab) {
282 Res = SymbolRef::ST_Debug;
283 return object_error::success;
284 }
285
286 switch (n_type & MachO::NlistMaskType) {
287 case MachO::NListTypeUndefined :
288 Res = SymbolRef::ST_Unknown;
289 break;
290 case MachO::NListTypeSection :
291 Res = SymbolRef::ST_Function;
292 break;
293 }
294 return object_error::success;
295 }
296
29783 error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
29884 uint64_t &Val) const {
29985 report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
300 }
301
302 symbol_iterator MachOObjectFileBase::begin_symbols() const {
303 // DRI.d.a = segment number; DRI.d.b = symbol index.
304 DataRefImpl DRI;
305 moveToNextSymbol(DRI);
306 return symbol_iterator(SymbolRef(DRI, this));
307 }
308
309 symbol_iterator MachOObjectFileBase::end_symbols() const {
310 DataRefImpl DRI;
311 DRI.d.a = getHeader()->NumLoadCommands;
312 return symbol_iterator(SymbolRef(DRI, this));
31386 }
31487
31588 symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
346119 return std::distance(Sections.begin(), loc);
347120 }
348121
349 const MachOObjectFileBase::SectionBase*
350 MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const {
351 const LoadCommand *Command = getLoadCommandInfo(DRI.d.a);
352 uintptr_t CommandAddr = reinterpret_cast(Command);
353
354 bool Is64 = is64Bit();
355 unsigned SegmentLoadSize =
356 Is64 ? sizeof(MachOObjectFile64Le::SegmentLoadCommand) :
357 sizeof(MachOObjectFile32Le::SegmentLoadCommand);
358 unsigned SectionSize = Is64 ? sizeof(MachOObjectFile64Le::Section) :
359 sizeof(MachOObjectFile32Le::Section);
360
361 uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
362 return reinterpret_cast(SectionAddr);
363 }
364
365 static StringRef parseSegmentOrSectionName(const char *P) {
122 StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
366123 if (P[15] == 0)
367124 // Null terminated.
368125 return P;
370127 return StringRef(P, 16);
371128 }
372129
373 ArrayRef MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const {
374 const SectionBase *Base = getSectionBase(DRI);
375 return ArrayRef(Base->Name);
376 }
377
378 error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI,
379 StringRef &Result) const {
380 ArrayRef Raw = getSectionRawName(DRI);
381 Result = parseSegmentOrSectionName(Raw.data());
382 return object_error::success;
383 }
384
385 ArrayRef
386 MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
387 const SectionBase *Base = getSectionBase(Sec);
388 return ArrayRef(Base->SegmentName);
389 }
390
391 StringRef
392 MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const {
393 ArrayRef Raw = getSectionRawFinalSegmentName(DRI);
394 return parseSegmentOrSectionName(Raw.data());
395 }
396
397130 error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
398131 bool &Result) const {
399132 // FIXME: Unimplemented.
440173 return relocation_iterator(RelocationRef(ret, this));
441174 }
442175
443 section_iterator MachOObjectFileBase::end_sections() const {
444 DataRefImpl DRI;
445 DRI.d.a = getHeader()->NumLoadCommands;
446 return section_iterator(SectionRef(DRI, this));
447 }
448176
449177 /*===-- Relocations -------------------------------------------------------===*/
450178
455183 return object_error::success;
456184 }
457185
458 // Helper to advance a section or symbol iterator multiple increments at a time.
459 template
460 error_code advance(T &it, size_t Val) {
461 error_code ec;
462 while (Val--) {
463 it.increment(ec);
464 }
465 return ec;
466 }
467
468 template
469 void advanceTo(T &it, size_t Val) {
470 if (error_code ec = advance(it, Val))
471 report_fatal_error(ec.message());
472 }
473
474 void
475 MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
476 raw_string_ostream &fmt) const {
477 // Target of a scattered relocation is an address. In the interest of
478 // generating pretty output, scan through the symbol table looking for a
479 // symbol that aligns with that address. If we find one, print it.
480 // Otherwise, we just print the hex address of the target.
481 if (isScattered(RE)) {
482 uint32_t Val = RE->SymbolNum;
483
484 error_code ec;
485 for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
486 SI.increment(ec)) {
487 if (ec) report_fatal_error(ec.message());
488
489 uint64_t Addr;
490 StringRef Name;
491
492 if ((ec = SI->getAddress(Addr)))
493 report_fatal_error(ec.message());
494 if (Addr != Val) continue;
495 if ((ec = SI->getName(Name)))
496 report_fatal_error(ec.message());
497 fmt << Name;
498 return;
499 }
500
501 // If we couldn't find a symbol that this relocation refers to, try
502 // to find a section beginning instead.
503 for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
504 SI.increment(ec)) {
505 if (ec) report_fatal_error(ec.message());
506
507 uint64_t Addr;
508 StringRef Name;
509
510 if ((ec = SI->getAddress(Addr)))
511 report_fatal_error(ec.message());
512 if (Addr != Val) continue;
513 if ((ec = SI->getName(Name)))
514 report_fatal_error(ec.message());
515 fmt << Name;
516 return;
517 }
518
519 fmt << format("0x%x", Val);
520 return;
521 }
522
523 StringRef S;
524 bool isExtern = RE->getExternal();
525 uint32_t Val = RE->Address;
526
527 if (isExtern) {
528 symbol_iterator SI = begin_symbols();
529 advanceTo(SI, Val);
530 SI->getName(S);
531 } else {
532 section_iterator SI = begin_sections();
533 advanceTo(SI, Val);
534 SI->getName(S);
535 }
536
537 fmt << S;
538 }
539
540186 error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
541187 LibraryRef &Res) const {
542188 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
560206 return is64Bit() ? 8 : 4;
561207 }
562208
563 StringRef MachOObjectFileBase::getFileFormatName() const {
564 if (!is64Bit()) {
565 switch (getHeader()->CPUType) {
566 case llvm::MachO::CPUTypeI386:
567 return "Mach-O 32-bit i386";
568 case llvm::MachO::CPUTypeARM:
569 return "Mach-O arm";
570 case llvm::MachO::CPUTypePowerPC:
571 return "Mach-O 32-bit ppc";
572 default:
573 assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64) == 0 &&
574 "64-bit object file when we're not 64-bit?");
575 return "Mach-O 32-bit unknown";
576 }
577 }
578
579 // Make sure the cpu type has the correct mask.
580 assert((getHeader()->CPUType & llvm::MachO::CPUArchABI64)
581 == llvm::MachO::CPUArchABI64 &&
582 "32-bit object file when we're 64-bit?");
583
584 switch (getHeader()->CPUType) {
585 case llvm::MachO::CPUTypeX86_64:
586 return "Mach-O 64-bit x86-64";
587 case llvm::MachO::CPUTypePowerPC64:
588 return "Mach-O 64-bit ppc64";
589 default:
590 return "Mach-O 64-bit unknown";
591 }
592 }
593
594 unsigned MachOObjectFileBase::getArch() const {
595 switch (getHeader()->CPUType) {
596 case llvm::MachO::CPUTypeI386:
597 return Triple::x86;
598 case llvm::MachO::CPUTypeX86_64:
599 return Triple::x86_64;
600 case llvm::MachO::CPUTypeARM:
601 return Triple::arm;
602 case llvm::MachO::CPUTypePowerPC:
603 return Triple::ppc;
604 case llvm::MachO::CPUTypePowerPC64:
605 return Triple::ppc64;
606 default:
607 return Triple::UnknownArch;
608 }
609 }
610
611209 } // end namespace object
612210 } // end namespace llvm
55 RUN: | FileCheck %s -check-prefix MACHO-I386
66 RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-x86-64 \
77 RUN: | FileCheck %s -check-prefix MACHO-X86-64
8 RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc \
9 RUN: | FileCheck %s -check-prefix MACHO-PPC
10 RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc64 \
11 RUN: | FileCheck %s -check-prefix MACHO-PPC64
812
913 COFF: Relocations [
1014 COFF-NEXT: Section (1) .text {
3943 MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
4044 MACHO-X86-64-NEXT: }
4145 MACHO-X86-64-NEXT:]
46
47 MACHO-PPC: Relocations [
48 MACHO-PPC-NEXT: Section __text {
49 MACHO-PPC-NEXT: 0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
50 MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
51 MACHO-PPC-NEXT: 0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
52 MACHO-PPC-NEXT: 0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
53 MACHO-PPC-NEXT: 0x18 1 2 0 PPC_RELOC_BR24 0 _b
54 MACHO-PPC-NEXT: }
55 MACHO-PPC-NEXT: Section __picsymbolstub1 {
56 MACHO-PPC-NEXT: 0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
57 MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
58 MACHO-PPC-NEXT: 0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
59 MACHO-PPC-NEXT: 0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
60 MACHO-PPC-NEXT: }
61 MACHO-PPC-NEXT: Section __la_symbol_ptr {
62 MACHO-PPC-NEXT: 0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
63 MACHO-PPC-NEXT: }
64 MACHO-PPC-NEXT: ]
65
66 MACHO-PPC64: Relocations [
67 MACHO-PPC64-NEXT: Section __text {
68 MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
69 MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
70 MACHO-PPC64-NEXT: 0x1C 0 2 n/a 1 _b
71 MACHO-PPC64-NEXT: 0x58 0 2 n/a 1 _b
72 MACHO-PPC64-NEXT: 0x18 1 2 0 0 _b
73 MACHO-PPC64-NEXT: }
74 MACHO-PPC64-NEXT: Section __picsymbolstub1 {
75 MACHO-PPC64-NEXT: 0x14 0 2 n/a 1 _b
76 MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
77 MACHO-PPC64-NEXT: 0xC 0 2 n/a 1 _b
78 MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
79 MACHO-PPC64-NEXT: }
80 MACHO-PPC64-NEXT: Section __la_symbol_ptr {
81 MACHO-PPC64-NEXT: 0x0 0 3 1 0 dyld_stub_binding_helper
82 MACHO-PPC64-NEXT: }
83 MACHO-PPC64-NEXT: ]
55 RUN: | FileCheck %s -check-prefix MACHO-I386
66 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-x86-64 \
77 RUN: | FileCheck %s -check-prefix MACHO-X86-64
8 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc \
9 RUN: | FileCheck %s -check-prefix MACHO-PPC
10 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc64 \
11 RUN: | FileCheck %s -check-prefix MACHO-PPC64
812
913 COFF: Sections [
1014 COFF-NEXT: Section {
248252 MACHO-X86-64-NEXT: )
249253 MACHO-X86-64-NEXT: }
250254 MACHO-X86-64-NEXT:]
255
256 MACHO-PPC: Sections [
257 MACHO-PPC-NEXT: Section {
258 MACHO-PPC-NEXT: Index: 0
259 MACHO-PPC-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
260 MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
261 MACHO-PPC-NEXT: Address: 0x0
262 MACHO-PPC-NEXT: Size: 0x3C
263 MACHO-PPC-NEXT: Offset: 528
264 MACHO-PPC-NEXT: Alignment: 2
265 MACHO-PPC-NEXT: RelocationOffset: 0x27C
266 MACHO-PPC-NEXT: RelocationCount: 5
267 MACHO-PPC-NEXT: Type: 0x0
268 MACHO-PPC-NEXT: Attributes [ (0x800004)
269 MACHO-PPC-NEXT: PureInstructions (0x800000)
270 MACHO-PPC-NEXT: SomeInstructions (0x4)
271 MACHO-PPC-NEXT: ]
272 MACHO-PPC-NEXT: Reserved1: 0x0
273 MACHO-PPC-NEXT: Reserved2: 0x0
274 MACHO-PPC-NEXT: Relocations [
275 MACHO-PPC-NEXT: 0x24 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
276 MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
277 MACHO-PPC-NEXT: 0x1C 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
278 MACHO-PPC-NEXT: 0x58 0 2 n/a PPC_RELOC_PAIR 1 _b
279 MACHO-PPC-NEXT: 0x18 1 2 0 PPC_RELOC_BR24 0 _b
280 MACHO-PPC-NEXT: ]
281 MACHO-PPC-NEXT: Symbols [
282 MACHO-PPC-NEXT: Symbol {
283 MACHO-PPC-NEXT: Name: _f (4)
284 MACHO-PPC-NEXT: Type: 0xF
285 MACHO-PPC-NEXT: Section: __text (0x1)
286 MACHO-PPC-NEXT: RefType: UndefinedNonLazy (0x0)
287 MACHO-PPC-NEXT: Flags [ (0x0)
288 MACHO-PPC-NEXT: ]
289 MACHO-PPC-NEXT: Value: 0x0
290 MACHO-PPC-NEXT: }
291 MACHO-PPC-NEXT: ]
292 MACHO-PPC-NEXT: SectionData (
293 MACHO-PPC-NEXT: 0000: 7C0802A6 93E1FFFC 429F0005 7FE802A6 ||.......B.......|
294 MACHO-PPC-NEXT: 0010: 90010008 9421FFB0 48000029 3C5F0000 |.....!..H..)<_..|
295 MACHO-PPC-NEXT: 0020: 38210050 80420058 80010008 83E1FFFC |8!.P.B.X........|
296 MACHO-PPC-NEXT: 0030: 7C0803A6 80620000 4E800020 ||....b..N.. |
297 MACHO-PPC-NEXT: )
298 MACHO-PPC-NEXT: }
299 MACHO-PPC-NEXT: Section {
300 MACHO-PPC-NEXT: Index: 1
301 MACHO-PPC-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
302 MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
303 MACHO-PPC-NEXT: Address: 0x40
304 MACHO-PPC-NEXT: Size: 0x20
305 MACHO-PPC-NEXT: Offset: 592
306 MACHO-PPC-NEXT: Alignment: 5
307 MACHO-PPC-NEXT: RelocationOffset: 0x2A4
308 MACHO-PPC-NEXT: RelocationCount: 4
309 MACHO-PPC-NEXT: Type: 0x8
310 MACHO-PPC-NEXT: Attributes [ (0x800004)
311 MACHO-PPC-NEXT: PureInstructions (0x800000)
312 MACHO-PPC-NEXT: SomeInstructions (0x4)
313 MACHO-PPC-NEXT: ]
314 MACHO-PPC-NEXT: Reserved1: 0x0
315 MACHO-PPC-NEXT: Reserved2: 0x20
316 MACHO-PPC-NEXT: Relocations [
317 MACHO-PPC-NEXT: 0x14 0 2 n/a PPC_RELOC_LO16_SECTDIFF 1 _b
318 MACHO-PPC-NEXT: 0x0 0 2 n/a PPC_RELOC_PAIR 1 _b
319 MACHO-PPC-NEXT: 0xC 0 2 n/a PPC_RELOC_HA16_SECTDIFF 1 _b
320 MACHO-PPC-NEXT: 0x20 0 2 n/a PPC_RELOC_PAIR 1 _b
321 MACHO-PPC-NEXT: ]
322 MACHO-PPC-NEXT: Symbols [
323 MACHO-PPC-NEXT: ]
324 MACHO-PPC-NEXT: SectionData (
325 MACHO-PPC-NEXT: 0000: 7C0802A6 429F0005 7D6802A6 3D6B0000 ||...B...}h..=k..|
326 MACHO-PPC-NEXT: 0010: 7C0803A6 858B0020 7D8903A6 4E800420 ||...... }...N.. |
327 MACHO-PPC-NEXT: )
328 MACHO-PPC-NEXT: }
329 MACHO-PPC-NEXT: Section {
330 MACHO-PPC-NEXT: Index: 2
331 MACHO-PPC-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
332 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
333 MACHO-PPC-NEXT: Address: 0x60
334 MACHO-PPC-NEXT: Size: 0x4
335 MACHO-PPC-NEXT: Offset: 624
336 MACHO-PPC-NEXT: Alignment: 2
337 MACHO-PPC-NEXT: RelocationOffset: 0x0
338 MACHO-PPC-NEXT: RelocationCount: 0
339 MACHO-PPC-NEXT: Type: 0x0
340 MACHO-PPC-NEXT: Attributes [ (0x0)
341 MACHO-PPC-NEXT: ]
342 MACHO-PPC-NEXT: Reserved1: 0x0
343 MACHO-PPC-NEXT: Reserved2: 0x0
344 MACHO-PPC-NEXT: Relocations [
345 MACHO-PPC-NEXT: ]
346 MACHO-PPC-NEXT: Symbols [
347 MACHO-PPC-NEXT: Symbol {
348 MACHO-PPC-NEXT: Name: _b (1)
349 MACHO-PPC-NEXT: Type: 0xF
350 MACHO-PPC-NEXT: Section: __data (0x3)
351 MACHO-PPC-NEXT: RefType: UndefinedNonLazy (0x0)
352 MACHO-PPC-NEXT: Flags [ (0x0)
353 MACHO-PPC-NEXT: ]
354 MACHO-PPC-NEXT: Value: 0x60
355 MACHO-PPC-NEXT: }
356 MACHO-PPC-NEXT: ]
357 MACHO-PPC-NEXT: SectionData (
358 MACHO-PPC-NEXT: 0000: 0000002A |...*|
359 MACHO-PPC-NEXT: )
360 MACHO-PPC-NEXT: }
361 MACHO-PPC-NEXT: Section {
362 MACHO-PPC-NEXT: Index: 3
363 MACHO-PPC-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
364 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
365 MACHO-PPC-NEXT: Address: 0x64
366 MACHO-PPC-NEXT: Size: 0x4
367 MACHO-PPC-NEXT: Offset: 628
368 MACHO-PPC-NEXT: Alignment: 2
369 MACHO-PPC-NEXT: RelocationOffset: 0x0
370 MACHO-PPC-NEXT: RelocationCount: 0
371 MACHO-PPC-NEXT: Type: 0x6
372 MACHO-PPC-NEXT: Attributes [ (0x0)
373 MACHO-PPC-NEXT: ]
374 MACHO-PPC-NEXT: Reserved1: 0x1
375 MACHO-PPC-NEXT: Reserved2: 0x0
376 MACHO-PPC-NEXT: Relocations [
377 MACHO-PPC-NEXT: ]
378 MACHO-PPC-NEXT: Symbols [
379 MACHO-PPC-NEXT: ]
380 MACHO-PPC-NEXT: SectionData (
381 MACHO-PPC-NEXT: 0000: 00000000 |....|
382 MACHO-PPC-NEXT: )
383 MACHO-PPC-NEXT: }
384 MACHO-PPC-NEXT: Section {
385 MACHO-PPC-NEXT: Index: 4
386 MACHO-PPC-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
387 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
388 MACHO-PPC-NEXT: Address: 0x68
389 MACHO-PPC-NEXT: Size: 0x4
390 MACHO-PPC-NEXT: Offset: 632
391 MACHO-PPC-NEXT: Alignment: 2
392 MACHO-PPC-NEXT: RelocationOffset: 0x2C4
393 MACHO-PPC-NEXT: RelocationCount: 1
394 MACHO-PPC-NEXT: Type: 0x7
395 MACHO-PPC-NEXT: Attributes [ (0x0)
396 MACHO-PPC-NEXT: ]
397 MACHO-PPC-NEXT: Reserved1: 0x2
398 MACHO-PPC-NEXT: Reserved2: 0x0
399 MACHO-PPC-NEXT: Relocations [
400 MACHO-PPC-NEXT: 0x0 0 2 1 PPC_RELOC_VANILLA 0 dyld_stub_binding_helper
401 MACHO-PPC-NEXT: ]
402 MACHO-PPC-NEXT: Symbols [
403 MACHO-PPC-NEXT: ]
404 MACHO-PPC-NEXT: SectionData (
405 MACHO-PPC-NEXT: 0000: 00000000 |....|
406 MACHO-PPC-NEXT: )
407 MACHO-PPC-NEXT: }
408 MACHO-PPC-NEXT: ]
409
410
411 MACHO-PPC64: Sections [
412 MACHO-PPC64-NEXT: Section {
413 MACHO-PPC64-NEXT: Index: 0
414 MACHO-PPC64-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
415 MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
416 MACHO-PPC64-NEXT: Address: 0x0
417 MACHO-PPC64-NEXT: Size: 0x3C
418 MACHO-PPC64-NEXT: Offset: 608
419 MACHO-PPC64-NEXT: Alignment: 2
420 MACHO-PPC64-NEXT: RelocationOffset: 0x2D4
421 MACHO-PPC64-NEXT: RelocationCount: 5
422 MACHO-PPC64-NEXT: Type: 0x0
423 MACHO-PPC64-NEXT: Attributes [ (0x800004)
424 MACHO-PPC64-NEXT: PureInstructions (0x800000)
425 MACHO-PPC64-NEXT: SomeInstructions (0x4)
426 MACHO-PPC64-NEXT: ]
427 MACHO-PPC64-NEXT: Reserved1: 0x0
428 MACHO-PPC64-NEXT: Reserved2: 0x0
429 MACHO-PPC64-NEXT: Relocations [
430 MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
431 MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
432 MACHO-PPC64-NEXT: 0x1C 0 2 n/a 1 _b
433 MACHO-PPC64-NEXT: 0x58 0 2 n/a 1 _b
434 MACHO-PPC64-NEXT: 0x18 1 2 0 0 _b
435 MACHO-PPC64-NEXT: ]
436 MACHO-PPC64-NEXT: Symbols [
437 MACHO-PPC64-NEXT: Symbol {
438 MACHO-PPC64-NEXT: Name: _f (4)
439 MACHO-PPC64-NEXT: Type: 0xF
440 MACHO-PPC64-NEXT: Section: __text (0x1)
441 MACHO-PPC64-NEXT: RefType: UndefinedNonLazy (0x0)
442 MACHO-PPC64-NEXT: Flags [ (0x0)
443 MACHO-PPC64-NEXT: ]
444 MACHO-PPC64-NEXT: Value: 0x0
445 MACHO-PPC64-NEXT: }
446 MACHO-PPC64-NEXT: ]
447 MACHO-PPC64-NEXT: SectionData (
448 MACHO-PPC64-NEXT: 0000: 7C0802A6 FBE1FFF8 429F0005 7FE802A6 ||.......B.......|
449 MACHO-PPC64-NEXT: 0010: F8010010 F821FF81 48000029 3C5F0000 |.....!..H..)<_..|
450 MACHO-PPC64-NEXT: 0020: 38210080 E8420058 E8010010 EBE1FFF8 |8!...B.X........|
451 MACHO-PPC64-NEXT: 0030: 7C0803A6 E8620002 4E800020 ||....b..N.. |
452 MACHO-PPC64-NEXT: )
453 MACHO-PPC64-NEXT: }
454 MACHO-PPC64-NEXT: Section {
455 MACHO-PPC64-NEXT: Index: 1
456 MACHO-PPC64-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
457 MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
458 MACHO-PPC64-NEXT: Address: 0x40
459 MACHO-PPC64-NEXT: Size: 0x20
460 MACHO-PPC64-NEXT: Offset: 672
461 MACHO-PPC64-NEXT: Alignment: 5
462 MACHO-PPC64-NEXT: RelocationOffset: 0x2FC
463 MACHO-PPC64-NEXT: RelocationCount: 4
464 MACHO-PPC64-NEXT: Type: 0x8
465 MACHO-PPC64-NEXT: Attributes [ (0x800004)
466 MACHO-PPC64-NEXT: PureInstructions (0x800000)
467 MACHO-PPC64-NEXT: SomeInstructions (0x4)
468 MACHO-PPC64-NEXT: ]
469 MACHO-PPC64-NEXT: Reserved1: 0x0
470 MACHO-PPC64-NEXT: Reserved2: 0x20
471 MACHO-PPC64-NEXT: Relocations [
472 MACHO-PPC64-NEXT: 0x14 0 2 n/a 1 _b
473 MACHO-PPC64-NEXT: 0x0 0 2 n/a 1 _b
474 MACHO-PPC64-NEXT: 0xC 0 2 n/a 1 _b
475 MACHO-PPC64-NEXT: 0x24 0 2 n/a 1 _b
476 MACHO-PPC64-NEXT: ]
477 MACHO-PPC64-NEXT: Symbols [
478 MACHO-PPC64-NEXT: ]
479 MACHO-PPC64-NEXT: SectionData (
480 MACHO-PPC64-NEXT: 0000: 7C0802A6 429F0005 7D6802A6 3D6B0000 ||...B...}h..=k..|
481 MACHO-PPC64-NEXT: 0010: 7C0803A6 E98B0025 7D8903A6 4E800420 ||......%}...N.. |
482 MACHO-PPC64-NEXT: )
483 MACHO-PPC64-NEXT: }
484 MACHO-PPC64-NEXT: Section {
485 MACHO-PPC64-NEXT: Index: 2
486 MACHO-PPC64-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
487 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
488 MACHO-PPC64-NEXT: Address: 0x60
489 MACHO-PPC64-NEXT: Size: 0x4
490 MACHO-PPC64-NEXT: Offset: 704
491 MACHO-PPC64-NEXT: Alignment: 2
492 MACHO-PPC64-NEXT: RelocationOffset: 0x0
493 MACHO-PPC64-NEXT: RelocationCount: 0
494 MACHO-PPC64-NEXT: Type: 0x0
495 MACHO-PPC64-NEXT: Attributes [ (0x0)
496 MACHO-PPC64-NEXT: ]
497 MACHO-PPC64-NEXT: Reserved1: 0x0
498 MACHO-PPC64-NEXT: Reserved2: 0x0
499 MACHO-PPC64-NEXT: Relocations [
500 MACHO-PPC64-NEXT: ]
501 MACHO-PPC64-NEXT: Symbols [
502 MACHO-PPC64-NEXT: Symbol {
503 MACHO-PPC64-NEXT: Name: _b (1)
504 MACHO-PPC64-NEXT: Type: 0xF
505 MACHO-PPC64-NEXT: Section: __data (0x3)
506 MACHO-PPC64-NEXT: RefType: UndefinedNonLazy (0x0)
507 MACHO-PPC64-NEXT: Flags [ (0x0)
508 MACHO-PPC64-NEXT: ]
509 MACHO-PPC64-NEXT: Value: 0x60
510 MACHO-PPC64-NEXT: }
511 MACHO-PPC64-NEXT: ]
512 MACHO-PPC64-NEXT: SectionData (
513 MACHO-PPC64-NEXT: 0000: 0000002A |...*|
514 MACHO-PPC64-NEXT: )
515 MACHO-PPC64-NEXT: }
516 MACHO-PPC64-NEXT: Section {
517 MACHO-PPC64-NEXT: Index: 3
518 MACHO-PPC64-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
519 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
520 MACHO-PPC64-NEXT: Address: 0x64
521 MACHO-PPC64-NEXT: Size: 0x8
522 MACHO-PPC64-NEXT: Offset: 708
523 MACHO-PPC64-NEXT: Alignment: 2
524 MACHO-PPC64-NEXT: RelocationOffset: 0x0
525 MACHO-PPC64-NEXT: RelocationCount: 0
526 MACHO-PPC64-NEXT: Type: 0x6
527 MACHO-PPC64-NEXT: Attributes [ (0x0)
528 MACHO-PPC64-NEXT: ]
529 MACHO-PPC64-NEXT: Reserved1: 0x1
530 MACHO-PPC64-NEXT: Reserved2: 0x0
531 MACHO-PPC64-NEXT: Relocations [
532 MACHO-PPC64-NEXT: ]
533 MACHO-PPC64-NEXT: Symbols [
534 MACHO-PPC64-NEXT: ]
535 MACHO-PPC64-NEXT: SectionData (
536 MACHO-PPC64-NEXT: 0000: 00000000 00000000 |........|
537 MACHO-PPC64-NEXT: )
538 MACHO-PPC64-NEXT: }
539 MACHO-PPC64-NEXT: Section {
540 MACHO-PPC64-NEXT: Index: 4
541 MACHO-PPC64-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
542 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
543 MACHO-PPC64-NEXT: Address: 0x6C
544 MACHO-PPC64-NEXT: Size: 0x8
545 MACHO-PPC64-NEXT: Offset: 716
546 MACHO-PPC64-NEXT: Alignment: 2
547 MACHO-PPC64-NEXT: RelocationOffset: 0x31C
548 MACHO-PPC64-NEXT: RelocationCount: 1
549 MACHO-PPC64-NEXT: Type: 0x7
550 MACHO-PPC64-NEXT: Attributes [ (0x0)
551 MACHO-PPC64-NEXT: ]
552 MACHO-PPC64-NEXT: Reserved1: 0x2
553 MACHO-PPC64-NEXT: Reserved2: 0x0
554 MACHO-PPC64-NEXT: Relocations [
555 MACHO-PPC64-NEXT: 0x0 0 3 1 0 dyld_stub_binding_helper
556 MACHO-PPC64-NEXT: ]
557 MACHO-PPC64-NEXT: Symbols [
558 MACHO-PPC64-NEXT: ]
559 MACHO-PPC64-NEXT: SectionData (
560 MACHO-PPC64-NEXT: 0000: 00000000 00000000 |........|
561 MACHO-PPC64-NEXT: )
562 MACHO-PPC64-NEXT: }
563 MACHO-PPC64-NEXT: ]
55 RUN: | FileCheck %s -check-prefix MACHO-I386
66 RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-x86-64 \
77 RUN: | FileCheck %s -check-prefix MACHO-X86-64
8 RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc \
9 RUN: | FileCheck %s -check-prefix MACHO-PPC
10 RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
11 RUN: | FileCheck %s -check-prefix MACHO-PPC64
812
913 COFF: Sections [
1014 COFF-NEXT: Section {
150154 MACHO-X86-64-NEXT: Reserved2: 0x0
151155 MACHO-X86-64-NEXT: }
152156 MACHO-X86-64-NEXT:]
157
158 MACHO-PPC: Sections [
159 MACHO-PPC-NEXT: Section {
160 MACHO-PPC-NEXT: Index: 0
161 MACHO-PPC-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
162 MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
163 MACHO-PPC-NEXT: Address: 0x0
164 MACHO-PPC-NEXT: Size: 0x3C
165 MACHO-PPC-NEXT: Offset: 528
166 MACHO-PPC-NEXT: Alignment: 2
167 MACHO-PPC-NEXT: RelocationOffset: 0x27C
168 MACHO-PPC-NEXT: RelocationCount: 5
169 MACHO-PPC-NEXT: Type: 0x0
170 MACHO-PPC-NEXT: Attributes [ (0x800004)
171 MACHO-PPC-NEXT: PureInstructions (0x800000)
172 MACHO-PPC-NEXT: SomeInstructions (0x4)
173 MACHO-PPC-NEXT: ]
174 MACHO-PPC-NEXT: Reserved1: 0x0
175 MACHO-PPC-NEXT: Reserved2: 0x0
176 MACHO-PPC-NEXT: }
177 MACHO-PPC-NEXT: Section {
178 MACHO-PPC-NEXT: Index: 1
179 MACHO-PPC-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
180 MACHO-PPC-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
181 MACHO-PPC-NEXT: Address: 0x40
182 MACHO-PPC-NEXT: Size: 0x20
183 MACHO-PPC-NEXT: Offset: 592
184 MACHO-PPC-NEXT: Alignment: 5
185 MACHO-PPC-NEXT: RelocationOffset: 0x2A4
186 MACHO-PPC-NEXT: RelocationCount: 4
187 MACHO-PPC-NEXT: Type: 0x8
188 MACHO-PPC-NEXT: Attributes [ (0x800004)
189 MACHO-PPC-NEXT: PureInstructions (0x800000)
190 MACHO-PPC-NEXT: SomeInstructions (0x4)
191 MACHO-PPC-NEXT: ]
192 MACHO-PPC-NEXT: Reserved1: 0x0
193 MACHO-PPC-NEXT: Reserved2: 0x20
194 MACHO-PPC-NEXT: }
195 MACHO-PPC-NEXT: Section {
196 MACHO-PPC-NEXT: Index: 2
197 MACHO-PPC-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
198 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
199 MACHO-PPC-NEXT: Address: 0x60
200 MACHO-PPC-NEXT: Size: 0x4
201 MACHO-PPC-NEXT: Offset: 624
202 MACHO-PPC-NEXT: Alignment: 2
203 MACHO-PPC-NEXT: RelocationOffset: 0x0
204 MACHO-PPC-NEXT: RelocationCount: 0
205 MACHO-PPC-NEXT: Type: 0x0
206 MACHO-PPC-NEXT: Attributes [ (0x0)
207 MACHO-PPC-NEXT: ]
208 MACHO-PPC-NEXT: Reserved1: 0x0
209 MACHO-PPC-NEXT: Reserved2: 0x0
210 MACHO-PPC-NEXT: }
211 MACHO-PPC-NEXT: Section {
212 MACHO-PPC-NEXT: Index: 3
213 MACHO-PPC-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
214 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
215 MACHO-PPC-NEXT: Address: 0x64
216 MACHO-PPC-NEXT: Size: 0x4
217 MACHO-PPC-NEXT: Offset: 628
218 MACHO-PPC-NEXT: Alignment: 2
219 MACHO-PPC-NEXT: RelocationOffset: 0x0
220 MACHO-PPC-NEXT: RelocationCount: 0
221 MACHO-PPC-NEXT: Type: 0x6
222 MACHO-PPC-NEXT: Attributes [ (0x0)
223 MACHO-PPC-NEXT: ]
224 MACHO-PPC-NEXT: Reserved1: 0x1
225 MACHO-PPC-NEXT: Reserved2: 0x0
226 MACHO-PPC-NEXT: }
227 MACHO-PPC-NEXT: Section {
228 MACHO-PPC-NEXT: Index: 4
229 MACHO-PPC-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
230 MACHO-PPC-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
231 MACHO-PPC-NEXT: Address: 0x68
232 MACHO-PPC-NEXT: Size: 0x4
233 MACHO-PPC-NEXT: Offset: 632
234 MACHO-PPC-NEXT: Alignment: 2
235 MACHO-PPC-NEXT: RelocationOffset: 0x2C4
236 MACHO-PPC-NEXT: RelocationCount: 1
237 MACHO-PPC-NEXT: Type: 0x7
238 MACHO-PPC-NEXT: Attributes [ (0x0)
239 MACHO-PPC-NEXT: ]
240 MACHO-PPC-NEXT: Reserved1: 0x2
241 MACHO-PPC-NEXT: Reserved2: 0x0
242 MACHO-PPC-NEXT: }
243 MACHO-PPC-NEXT: ]
244
245 MACHO-PPC64: Sections [
246 MACHO-PPC64-NEXT: Section {
247 MACHO-PPC64-NEXT: Index: 0
248 MACHO-PPC64-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
249 MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
250 MACHO-PPC64-NEXT: Address: 0x0
251 MACHO-PPC64-NEXT: Size: 0x3C
252 MACHO-PPC64-NEXT: Offset: 608
253 MACHO-PPC64-NEXT: Alignment: 2
254 MACHO-PPC64-NEXT: RelocationOffset: 0x2D4
255 MACHO-PPC64-NEXT: RelocationCount: 5
256 MACHO-PPC64-NEXT: Type: 0x0
257 MACHO-PPC64-NEXT: Attributes [ (0x800004)
258 MACHO-PPC64-NEXT: PureInstructions (0x800000)
259 MACHO-PPC64-NEXT: SomeInstructions (0x4)
260 MACHO-PPC64-NEXT: ]
261 MACHO-PPC64-NEXT: Reserved1: 0x0
262 MACHO-PPC64-NEXT: Reserved2: 0x0
263 MACHO-PPC64-NEXT: }
264 MACHO-PPC64-NEXT: Section {
265 MACHO-PPC64-NEXT: Index: 1
266 MACHO-PPC64-NEXT: Name: __picsymbolstub1 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 31)
267 MACHO-PPC64-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
268 MACHO-PPC64-NEXT: Address: 0x40
269 MACHO-PPC64-NEXT: Size: 0x20
270 MACHO-PPC64-NEXT: Offset: 672
271 MACHO-PPC64-NEXT: Alignment: 5
272 MACHO-PPC64-NEXT: RelocationOffset: 0x2FC
273 MACHO-PPC64-NEXT: RelocationCount: 4
274 MACHO-PPC64-NEXT: Type: 0x8
275 MACHO-PPC64-NEXT: Attributes [ (0x800004)
276 MACHO-PPC64-NEXT: PureInstructions (0x800000)
277 MACHO-PPC64-NEXT: SomeInstructions (0x4)
278 MACHO-PPC64-NEXT: ]
279 MACHO-PPC64-NEXT: Reserved1: 0x0
280 MACHO-PPC64-NEXT: Reserved2: 0x20
281 MACHO-PPC64-NEXT: }
282 MACHO-PPC64-NEXT: Section {
283 MACHO-PPC64-NEXT: Index: 2
284 MACHO-PPC64-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
285 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
286 MACHO-PPC64-NEXT: Address: 0x60
287 MACHO-PPC64-NEXT: Size: 0x4
288 MACHO-PPC64-NEXT: Offset: 704
289 MACHO-PPC64-NEXT: Alignment: 2
290 MACHO-PPC64-NEXT: RelocationOffset: 0x0
291 MACHO-PPC64-NEXT: RelocationCount: 0
292 MACHO-PPC64-NEXT: Type: 0x0
293 MACHO-PPC64-NEXT: Attributes [ (0x0)
294 MACHO-PPC64-NEXT: ]
295 MACHO-PPC64-NEXT: Reserved1: 0x0
296 MACHO-PPC64-NEXT: Reserved2: 0x0
297 MACHO-PPC64-NEXT: }
298 MACHO-PPC64-NEXT: Section {
299 MACHO-PPC64-NEXT: Index: 3
300 MACHO-PPC64-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
301 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
302 MACHO-PPC64-NEXT: Address: 0x64
303 MACHO-PPC64-NEXT: Size: 0x8
304 MACHO-PPC64-NEXT: Offset: 708
305 MACHO-PPC64-NEXT: Alignment: 2
306 MACHO-PPC64-NEXT: RelocationOffset: 0x0
307 MACHO-PPC64-NEXT: RelocationCount: 0
308 MACHO-PPC64-NEXT: Type: 0x6
309 MACHO-PPC64-NEXT: Attributes [ (0x0)
310 MACHO-PPC64-NEXT: ]
311 MACHO-PPC64-NEXT: Reserved1: 0x1
312 MACHO-PPC64-NEXT: Reserved2: 0x0
313 MACHO-PPC64-NEXT: }
314 MACHO-PPC64-NEXT: Section {
315 MACHO-PPC64-NEXT: Index: 4
316 MACHO-PPC64-NEXT: Name: __la_symbol_ptr (5F 5F 6C 61 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
317 MACHO-PPC64-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
318 MACHO-PPC64-NEXT: Address: 0x6C
319 MACHO-PPC64-NEXT: Size: 0x8
320 MACHO-PPC64-NEXT: Offset: 716
321 MACHO-PPC64-NEXT: Alignment: 2
322 MACHO-PPC64-NEXT: RelocationOffset: 0x31C
323 MACHO-PPC64-NEXT: RelocationCount: 1
324 MACHO-PPC64-NEXT: Type: 0x7
325 MACHO-PPC64-NEXT: Attributes [ (0x0)
326 MACHO-PPC64-NEXT: ]
327 MACHO-PPC64-NEXT: Reserved1: 0x2
328 MACHO-PPC64-NEXT: Reserved2: 0x0
329 MACHO-PPC64-NEXT: }
330 MACHO-PPC64-NEXT: ]
2626 #include "llvm/MC/MCRegisterInfo.h"
2727 #include "llvm/MC/MCSubtargetInfo.h"
2828 #include "llvm/Object/MachO.h"
29 #include "llvm/Support/Casting.h"
2930 #include "llvm/Support/CommandLine.h"
3031 #include "llvm/Support/Debug.h"
3132 #include "llvm/Support/Format.h"
182183 Out << "}\n";
183184 }
184185
185 static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header,
186 MachOObjectFileBase *MachOObj,
187 std::vector &Sections,
188 std::vector &Symbols,
189 SmallVectorImpl &FoundFns) {
186 template
187 static void
188 getSectionsAndSymbols(const typename MachOObjectFileMiddle::Header *Header,
189 const MachOObjectFileMiddle *MachOObj,
190 std::vector &Sections,
191 std::vector &Symbols,
192 SmallVectorImpl &FoundFns) {
193 typedef MachOObjectFileMiddle ObjType;
190194 error_code ec;
191195 for (symbol_iterator SI = MachOObj->begin_symbols(),
192196 SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
201205 }
202206
203207 for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {
204 const MachOObjectFileBase::LoadCommand *Command =
208 const typename ObjType::LoadCommand *Command =
205209 MachOObj->getLoadCommandInfo(i);
206210 if (Command->Type == macho::LCT_FunctionStarts) {
207211 // We found a function starts segment, parse the addresses for later
208212 // consumption.
209 const MachOObjectFileBase::LinkeditDataLoadCommand *LLC =
210 reinterpret_cast(Command);
213 const typename ObjType::LinkeditDataLoadCommand *LLC =
214 reinterpret_cast(Command);
211215
212216 MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
213217 }
214218 }
215219 }
220
221 template
222 static void DisassembleInputMachO2(StringRef Filename,
223 MachOObjectFileMiddle *MachOOF);
216224
217225 void llvm::DisassembleInputMachO(StringRef Filename) {
218226 OwningPtr Buff;
225233 OwningPtr MachOOF(static_cast(
226234 ObjectFile::createMachOObjectFile(Buff.take())));
227235
228 const Target *TheTarget = GetTarget(MachOOF.get());
236 if (MachOObjectFileLE *O = dyn_cast(MachOOF.get())) {
237 DisassembleInputMachO2(Filename, O);
238 return;
239 }
240 MachOObjectFileBE *O = cast(MachOOF.get());
241 DisassembleInputMachO2(Filename, O);
242 }
243
244 template
245 static void DisassembleInputMachO2(StringRef Filename,
246 MachOObjectFileMiddle *MachOOF) {
247 const Target *TheTarget = GetTarget(MachOOF);
229248 if (!TheTarget) {
230249 // GetTarget prints out stuff.
231250 return;
253272
254273 outs() << '\n' << Filename << ":\n\n";
255274
256 const MachOObjectFileBase::Header *Header = MachOOF->getHeader();
275 const typename MachOObjectFileMiddle::Header *Header =
276 MachOOF->getHeader();
257277
258278 std::vector Sections;
259279 std::vector Symbols;
260280 SmallVector FoundFns;
261281
262 getSectionsAndSymbols(Header, MachOOF.get(), Sections, Symbols, FoundFns);
282 getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns);
263283
264284 // Make a copy of the unsorted symbol list. FIXME: duplication
265285 std::vector UnsortedSymbols(Symbols);
273293 #endif
274294
275295 OwningPtr diContext;
276 ObjectFile *DbgObj = MachOOF.get();
296 ObjectFile *DbgObj = MachOOF;
277297 // Try to find debug info and set up the DIContext for it.
278298 if (UseDbg) {
279299 // A separate DSym file path was specified, parse it as a macho file,
562582 Relocs[j].second.getName(SymName);
563583
564584 outs() << "\t# " << SymName << ' ';
565 DumpAddress(Addr, Sections, MachOOF.get(), outs());
585 DumpAddress(Addr, Sections, MachOOF, outs());
566586 }
567587
568588 // If this instructions contains an address, see if we can evaluate
571591 Inst.Address,
572592 Inst.Size);
573593 if (targ != -1ULL)
574 DumpAddress(targ, Sections, MachOOF.get(), outs());
594 DumpAddress(targ, Sections, MachOOF, outs());
575595
576596 // Print debug info.
577597 if (diContext) {
190190 return a_addr < b_addr;
191191 }
192192
193 StringRef
194 getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) {
195 if (const MachOObjectFileLE *O = dyn_cast(MachO))
196 return O->getSectionFinalSegmentName(DR);
197 const MachOObjectFileBE *O = dyn_cast(MachO);
198 return O->getSectionFinalSegmentName(DR);
199 }
200
193201 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
194202 const Target *TheTarget = getTarget(Obj);
195203 // getTarget() will have already issued a diagnostic if necessary, so
254262 std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
255263
256264 StringRef SegmentName = "";
257 if (const MachOObjectFileBase *MachO = dyn_cast(Obj)) {
265 if (const MachOObjectFileBase *MachO =
266 dyn_cast(Obj)) {
258267 DataRefImpl DR = i->getRawDataRefImpl();
259 SegmentName = MachO->getSectionFinalSegmentName(DR);
268 SegmentName = getSectionFinalSegmentName(MachO, DR);
260269 }
261270 StringRef name;
262271 if (error(i->getName(name))) break;
590599 else if (Section == o->end_sections())
591600 outs() << "*UND*";
592601 else {
593 if (const MachOObjectFileBase *MachO = dyn_cast(o)) {
602 if (const MachOObjectFileBase *MachO =
603 dyn_cast(o)) {
594604 DataRefImpl DR = Section->getRawDataRefImpl();
595 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
605 StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);
596606 outs() << SegmentName << ",";
597607 }
598608 StringRef SectionName;
2626
2727 class MachODumper : public ObjDumper {
2828 public:
29 MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer)
29 MachODumper(const 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::MachOObjectFileBase *Obj;
45 template
46 void printRelocation(const MachOObjectFileMiddle *Obj,
47 section_iterator SecI, relocation_iterator RelI);
48
49 template
50 void printSections(const MachOObjectFileMiddle *Obj);
51
52 const MachOObjectFileBase *Obj;
4653 };
4754
4855 } // namespace
156163 };
157164 }
158165
166 template
167 static void getSection(const MachOObjectFile *Obj,
168 DataRefImpl DRI,
169 MachOSection &Section) {
170 const typename MachOObjectFile::Section *Sect = Obj->getSection(DRI);
171 Section.Address = Sect->Address;
172 Section.Size = Sect->Size;
173 Section.Offset = Sect->Offset;
174 Section.Alignment = Sect->Align;
175 Section.RelocationTableOffset = Sect->RelocationTableOffset;
176 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
177 Section.Flags = Sect->Flags;
178 Section.Reserved1 = Sect->Reserved1;
179 Section.Reserved2 = Sect->Reserved2;
180 }
181
159182 static void getSection(const MachOObjectFileBase *Obj,
160183 DataRefImpl DRI,
161184 MachOSection &Section) {
162 if (const MachOObjectFile64Le *O = dyn_cast(Obj)) {
163 const MachOObjectFile64Le::Section *Sect = O->getSection(DRI);
164
165 Section.Address = Sect->Address;
166 Section.Size = Sect->Size;
167 Section.Offset = Sect->Offset;
168 Section.Alignment = Sect->Align;
169 Section.RelocationTableOffset = Sect->RelocationTableOffset;
170 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
171 Section.Flags = Sect->Flags;
172 Section.Reserved1 = Sect->Reserved1;
173 Section.Reserved2 = Sect->Reserved2;
174 } else {
175 const MachOObjectFile32Le *O2 = cast(Obj);
176 const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI);
177
178 Section.Address = Sect->Address;
179 Section.Size = Sect->Size;
180 Section.Offset = Sect->Offset;
181 Section.Alignment = Sect->Align;
182 Section.RelocationTableOffset = Sect->RelocationTableOffset;
183 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
184 Section.Flags = Sect->Flags;
185 Section.Reserved1 = Sect->Reserved1;
186 Section.Reserved2 = Sect->Reserved2;
187 }
185 if (const MachOObjectFileLE32 *O = dyn_cast(Obj))
186 return getSection(O, DRI, Section);
187 if (const MachOObjectFileLE64 *O = dyn_cast(Obj))
188 return getSection(O, DRI, Section);
189 if (const MachOObjectFileBE32 *O = dyn_cast(Obj))
190 return getSection(O, DRI, Section);
191 const MachOObjectFileBE64 *O = cast(Obj);
192 getSection(O, DRI, Section);
193 }
194
195 template
196 static void getSymbol(const MachOObjectFile *Obj,
197 DataRefImpl DRI,
198 MachOSymbol &Symbol) {
199 const typename MachOObjectFile::SymbolTableEntry *Entry =
200 Obj->getSymbolTableEntry(DRI);
201 Symbol.StringIndex = Entry->StringIndex;
202 Symbol.Type = Entry->Type;
203 Symbol.SectionIndex = Entry->SectionIndex;
204 Symbol.Flags = Entry->Flags;
205 Symbol.Value = Entry->Value;
188206 }
189207
190208 static void getSymbol(const MachOObjectFileBase *Obj,
191209 DataRefImpl DRI,
192210 MachOSymbol &Symbol) {
193 if (const MachOObjectFile64Le *O = dyn_cast(Obj)) {
194 const MachOObjectFile64Le::SymbolTableEntry *Entry =
195 O->getSymbolTableEntry(DRI);
196 Symbol.StringIndex = Entry->StringIndex;
197 Symbol.Type = Entry->Type;
198 Symbol.SectionIndex = Entry->SectionIndex;
199 Symbol.Flags = Entry->Flags;
200 Symbol.Value = Entry->Value;
201 } else {
202 const MachOObjectFile32Le *O2 = cast(Obj);
203 const MachOObjectFile32Le::SymbolTableEntry *Entry =
204 O2->getSymbolTableEntry(DRI);
205 Symbol.StringIndex = Entry->StringIndex;
206 Symbol.Type = Entry->Type;
207 Symbol.SectionIndex = Entry->SectionIndex;
208 Symbol.Flags = Entry->Flags;
209 Symbol.Value = Entry->Value;
210 }
211 if (const MachOObjectFileLE32 *O = dyn_cast(Obj))
212 return getSymbol(O, DRI, Symbol);
213 if (const MachOObjectFileLE64 *O = dyn_cast(Obj))
214 return getSymbol(O, DRI, Symbol);
215 if (const MachOObjectFileBE32 *O = dyn_cast(Obj))
216 return getSymbol(O, DRI, Symbol);
217 const MachOObjectFileBE64 *O = cast(Obj);
218 getSymbol(O, DRI, Symbol);
211219 }
212220
213221 void MachODumper::printFileHeaders() {
215223 }
216224
217225 void MachODumper::printSections() {
226 if (const MachOObjectFileLE *O = dyn_cast(Obj))
227 return printSections(O);
228 const MachOObjectFileBE *O = cast(Obj);
229 return printSections(O);
230 }
231
232 template
233 void MachODumper::printSections(const MachOObjectFileMiddle *Obj) {
218234 ListScope Group(W, "Sections");
219235
220236 int SectionIndex = -1;
327343
328344 void MachODumper::printRelocation(section_iterator SecI,
329345 relocation_iterator RelI) {
346 if (const MachOObjectFileLE *O = dyn_cast(Obj))
347 return printRelocation(O, SecI, RelI);
348 const MachOObjectFileBE *O = cast(Obj);
349 return printRelocation(O, SecI, RelI);
350 }
351
352 template
353 void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj,
354 section_iterator SecI,
355 relocation_iterator RelI) {
330356 uint64_t Offset;
331357 SmallString<32> RelocName;
332358 StringRef SymbolName;
337363 if (error(Symbol.getName(SymbolName))) return;
338364
339365 DataRefImpl DR = RelI->getRawDataRefImpl();
340 const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR);
341 bool IsScattered = Obj->isScattered(RE);
366 const typename MachOObjectFileMiddle::RelocationEntry *RE =
367 Obj->getRelocation(DR);
368 bool IsScattered = Obj->isRelocationScattered(RE);
342369
343370 if (opts::ExpandRelocs) {
344371 DictScope Group(W, "Relocation");
345372 W.printHex("Offset", Offset);
346 W.printNumber("PCRel", Obj->isPCRel(RE));
347 W.printNumber("Length", Obj->getLength(RE));
373 W.printNumber("PCRel", Obj->isRelocationPCRel(RE));
374 W.printNumber("Length", Obj->getRelocationLength(RE));
348375 if (IsScattered)
349376 W.printString("Extern", StringRef("N/A"));
350377 else
355382 } else {
356383 raw_ostream& OS = W.startLine();
357384 OS << W.hex(Offset)
358 << " " << Obj->isPCRel(RE)
359 << " " << Obj->getLength(RE);
385 << " " << Obj->isRelocationPCRel(RE)
386 << " " << Obj->getRelocationLength(RE);
360387 if (IsScattered)
361388 OS << " n/a";
362389 else
398425 StringRef SectionName;
399426 section_iterator SecI(Obj->end_sections());
400427 if (error(SymI->getSection(SecI)) ||
428 SecI == Obj->end_sections() ||
401429 error(SecI->getName(SectionName)))
402430 SectionName = "";
403431