llvm.org GIT mirror llvm / 4edf092
Print more information about relocations. With this patch llvm-readobj now prints if a relocation is pcrel, its length, if it is extern and if it is scattered. It also refactors the code a bit to use bit fields instead of shifts and masks all over the place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179294 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
5 changed file(s) with 125 addition(s) and 91 deletion(s). Raw diff Collapse all Expand all
114114 template
115115 struct RelocationEntry {
116116 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
117 MachOInt32 Word0;
118 MachOInt32 Word1;
117 MachOInt32 Address;
118 unsigned SymbolNum : 24;
119 unsigned PCRel : 1;
120 unsigned Length : 2;
121 unsigned External : 1;
122 unsigned Type : 4;
123 };
124
125 template
126 struct ScatteredRelocationEntry {
127 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
128 unsigned Address : 24;
129 unsigned Type : 4;
130 unsigned Length : 2;
131 unsigned PCRel : 1;
132 unsigned Scattered : 1;
133 MachOInt32 Value;
119134 };
120135
121136 template
205220 SymbolTableEntryBase;
206221 typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand;
207222 typedef MachOFormat::RelocationEntry RelocationEntry;
223 typedef MachOFormat::ScatteredRelocationEntry
224 ScatteredRelocationEntry;
208225 typedef MachOFormat::SectionBase SectionBase;
209226 typedef MachOFormat::LoadCommand LoadCommand;
210227 typedef MachOFormat::Header Header;
242259 const Header *getHeader() const;
243260 unsigned getHeaderSize() const;
244261 StringRef getData(size_t Offset, size_t Size) const;
262 const RelocationEntry *getRelocation(DataRefImpl Rel) const;
263 bool isScattered(const RelocationEntry *RE) const;
264 bool isPCRel(const RelocationEntry *RE) const;
265 unsigned getLength(const RelocationEntry *RE) const;
266 unsigned getType(const RelocationEntry *RE) const;
245267
246268 static inline bool classof(const Binary *v) {
247269 return v->isMachO();
478500 const Section *Sect = getSection(Sections[Rel.d.b]);
479501 uint64_t SectAddress = Sect->Address;
480502 const RelocationEntry *RE = getRelocation(Rel);
481 unsigned Arch = getArch();
482 bool isScattered = (Arch != Triple::x86_64) &&
483 (RE->Word0 & macho::RF_Scattered);
484503
485504 uint64_t RelAddr;
486 if (isScattered)
487 RelAddr = RE->Word0 & 0xFFFFFF;
505 if (isScattered(RE))
506 RelAddr = RE->Address & 0xFFFFFF;
488507 else
489 RelAddr = RE->Word0;
508 RelAddr = RE->Address;
490509
491510 Res = SectAddress + RelAddr;
492511 return object_error::success;
497516 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
498517 uint64_t &Res) const {
499518 const RelocationEntry *RE = getRelocation(Rel);
500
501 unsigned Arch = getArch();
502 bool isScattered = (Arch != Triple::x86_64) &&
503 (RE->Word0 & macho::RF_Scattered);
504 if (isScattered)
505 Res = RE->Word0 & 0xFFFFFF;
519 if (isScattered(RE))
520 Res = RE->Address & 0xFFFFFF;
506521 else
507 Res = RE->Word0;
522 Res = RE->Address;
508523 return object_error::success;
509524 }
510525
513528 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
514529 SymbolRef &Res) const {
515530 const RelocationEntry *RE = getRelocation(Rel);
516 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
517 bool isExtern = (RE->Word1 >> 27) & 1;
531 uint32_t SymbolIdx = RE->SymbolNum;
532 bool isExtern = RE->External;
518533
519534 DataRefImpl Sym;
520535 moveToNextSymbol(Sym);
534549 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
535550 uint64_t &Res) const {
536551 const RelocationEntry *RE = getRelocation(Rel);
537 Res = RE->Word0;
538 Res <<= 32;
539 Res |= RE->Word1;
552 Res = getType(RE);
540553 return object_error::success;
541554 }
542555
549562 const RelocationEntry *RE = getRelocation(Rel);
550563
551564 unsigned Arch = getArch();
552 bool isScattered = (Arch != Triple::x86_64) &&
553 (RE->Word0 & macho::RF_Scattered);
554
555 unsigned r_type;
556 if (isScattered)
557 r_type = (RE->Word0 >> 24) & 0xF;
558 else
559 r_type = (RE->Word1 >> 28) & 0xF;
565
566 unsigned r_type = getType(RE);
560567
561568 switch (Arch) {
562569 case Triple::x86: {
649656 const RelocationEntry *RE = getRelocation(Rel);
650657
651658 unsigned Arch = getArch();
652 bool isScattered = (Arch != Triple::x86_64) &&
653 (RE->Word0 & macho::RF_Scattered);
659 bool IsScattered = isScattered(RE);
654660
655661 std::string fmtbuf;
656662 raw_string_ostream fmt(fmtbuf);
657663
658 unsigned Type;
659 if (isScattered)
660 Type = (RE->Word0 >> 24) & 0xF;
661 else
662 Type = (RE->Word1 >> 28) & 0xF;
663
664 bool isPCRel;
665 if (isScattered)
666 isPCRel = ((RE->Word0 >> 30) & 1);
667 else
668 isPCRel = ((RE->Word1 >> 24) & 1);
664 unsigned Type = getType(RE);
665 bool IsPCRel = isPCRel(RE);
669666
670667 // Determine any addends that should be displayed with the relocation.
671668 // These require decoding the relocation type, which is triple-specific.
672669
673670 // X86_64 has entirely custom relocation types.
674671 if (Arch == Triple::x86_64) {
675 bool isPCRel = ((RE->Word1 >> 24) & 1);
672 bool isPCRel = RE->PCRel;
676673
677674 switch (Type) {
678675 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
690687 // X86_64_SUBTRACTOR must be followed by a relocation of type
691688 // X86_64_RELOC_UNSIGNED.
692689 // NOTE: Scattered relocations don't exist on x86_64.
693 unsigned RType = (RENext->Word1 >> 28) & 0xF;
690 unsigned RType = RENext->Type;
694691 if (RType != 0)
695692 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
696693 "X86_64_RELOC_SUBTRACTOR.");
737734 // X86 sect diff's must be followed by a relocation of type
738735 // GENERIC_RELOC_PAIR.
739736 bool isNextScattered = (Arch != Triple::x86_64) &&
740 (RENext->Word0 & macho::RF_Scattered);
737 (RENext->Address & macho::RF_Scattered);
741738 unsigned RType;
742739 if (isNextScattered)
743 RType = (RENext->Word0 >> 24) & 0xF;
740 RType = (RENext->Address >> 24) & 0xF;
744741 else
745 RType = (RENext->Word1 >> 28) & 0xF;
742 RType = RENext->Type;
746743 if (RType != 1)
747744 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
748745 "GENERIC_RELOC_SECTDIFF.");
766763 // X86 sect diff's must be followed by a relocation of type
767764 // GENERIC_RELOC_PAIR.
768765 bool isNextScattered = (Arch != Triple::x86_64) &&
769 (RENext->Word0 & macho::RF_Scattered);
766 (RENext->Address & macho::RF_Scattered);
770767 unsigned RType;
771768 if (isNextScattered)
772 RType = (RENext->Word0 >> 24) & 0xF;
769 RType = (RENext->Address >> 24) & 0xF;
773770 else
774 RType = (RENext->Word1 >> 28) & 0xF;
771 RType = RENext->Type;
775772 if (RType != 1)
776773 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
777774 "GENERIC_RELOC_LOCAL_SECTDIFF.");
784781 case macho::RIT_Generic_TLV: {
785782 printRelocationTargetName(RE, fmt);
786783 fmt << "@TLV";
787 if (isPCRel) fmt << "P";
784 if (IsPCRel) fmt << "P";
788785 break;
789786 }
790787 default:
797794 // Half relocations steal a bit from the length field to encode
798795 // whether this is an upper16 or a lower16 relocation.
799796 bool isUpper;
800 if (isScattered)
801 isUpper = (RE->Word0 >> 28) & 1;
797 if (IsScattered)
798 isUpper = (RE->Address >> 28) & 1;
802799 else
803 isUpper = (RE->Word1 >> 25) & 1;
800 isUpper = (RE->Length >> 1) & 1;
804801
805802 if (isUpper)
806803 fmt << ":upper16:(";
815812 // ARM half relocs must be followed by a relocation of type
816813 // ARM_RELOC_PAIR.
817814 bool isNextScattered = (Arch != Triple::x86_64) &&
818 (RENext->Word0 & macho::RF_Scattered);
815 (RENext->Address & macho::RF_Scattered);
819816 unsigned RType;
820817 if (isNextScattered)
821 RType = (RENext->Word0 >> 24) & 0xF;
818 RType = (RENext->Address >> 24) & 0xF;
822819 else
823 RType = (RENext->Word1 >> 28) & 0xF;
820 RType = RENext->Type;
824821
825822 if (RType != 1)
826823 report_fatal_error("Expected ARM_RELOC_PAIR after "
859856 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
860857 bool &Result) const {
861858 const RelocationEntry *RE = getRelocation(Rel);
862
863859 unsigned Arch = getArch();
864 bool isScattered = (Arch != Triple::x86_64) &&
865 (RE->Word0 & macho::RF_Scattered);
866 unsigned Type;
867 if (isScattered)
868 Type = (RE->Word0 >> 24) & 0xF;
869 else
870 Type = (RE->Word1 >> 28) & 0xF;
860 unsigned Type = getType(RE);
871861
872862 Result = false;
873863
883873 RelPrev.d.a--;
884874 const RelocationEntry *REPrev = getRelocation(RelPrev);
885875
886 unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
876 unsigned PrevType = REPrev->Type;
887877
888878 if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
889879 }
7979 return ObjectFile::getData().substr(Offset, Size);
8080 }
8181
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->PCRel;
100 }
101 return RE->PCRel;
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->Length;
109 }
110 return RE->Length;
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->Type;
118 }
119 return RE->Type;
120 }
121
82122 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
83123 StringRef Magic = Buffer->getBuffer().slice(0, 4);
84124 error_code ec;
434474 void
435475 MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
436476 raw_string_ostream &fmt) const {
437 unsigned Arch = getArch();
438 bool isScattered = (Arch != Triple::x86_64) &&
439 (RE->Word0 & macho::RF_Scattered);
440
441477 // Target of a scattered relocation is an address. In the interest of
442478 // generating pretty output, scan through the symbol table looking for a
443479 // symbol that aligns with that address. If we find one, print it.
444480 // Otherwise, we just print the hex address of the target.
445 if (isScattered) {
446 uint32_t Val = RE->Word1;
481 if (isScattered(RE)) {
482 uint32_t Val = RE->SymbolNum;
447483
448484 error_code ec;
449485 for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
485521 }
486522
487523 StringRef S;
488 bool isExtern = (RE->Word1 >> 27) & 1;
489 uint32_t Val = RE->Word1 & 0xFFFFFF;
524 bool isExtern = RE->External;
525 uint32_t Val = RE->Address;
490526
491527 if (isExtern) {
492528 symbol_iterator SI = begin_symbols();
2525
2626 MACHO-I386: Relocations [
2727 MACHO-I386-NEXT: Section __text {
28 MACHO-I386-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
29 MACHO-I386-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
30 MACHO-I386-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
31 MACHO-I386-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
28 MACHO-I386-NEXT: 0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction
29 MACHO-I386-NEXT: 0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts
30 MACHO-I386-NEXT: 0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main
31 MACHO-I386-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main
3232 MACHO-I386-NEXT: }
3333 MACHO-I386-NEXT: ]
3434
3535 MACHO-X86-64: Relocations [
3636 MACHO-X86-64-NEXT: Section __text {
37 MACHO-X86-64-NEXT: 0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0
38 MACHO-X86-64-NEXT: 0x9 X86_64_RELOC_BRANCH _puts 0x0
39 MACHO-X86-64-NEXT: 0x4 X86_64_RELOC_SIGNED L_.str 0x0
37 MACHO-X86-64-NEXT: 0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction
38 MACHO-X86-64-NEXT: 0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts
39 MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
4040 MACHO-X86-64-NEXT: }
4141 MACHO-X86-64-NEXT:]
152152 MACHO-I386-NEXT: Reserved1: 0x0
153153 MACHO-I386-NEXT: Reserved2: 0x0
154154 MACHO-I386-NEXT: Relocations [
155 MACHO-I386-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
156 MACHO-I386-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
157 MACHO-I386-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
158 MACHO-I386-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
155 MACHO-I386-NEXT: 0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction
156 MACHO-I386-NEXT: 0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts
157 MACHO-I386-NEXT: 0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main
158 MACHO-I386-NEXT: 0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main
159159 MACHO-I386-NEXT: ]
160160 MACHO-I386-NEXT: Symbols [
161161 MACHO-I386-NEXT: Symbol {
195195 MACHO-X86-64-NEXT: Reserved1: 0x0
196196 MACHO-X86-64-NEXT: Reserved2: 0x0
197197 MACHO-X86-64-NEXT: Relocations [
198 MACHO-X86-64-NEXT: 0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0
199 MACHO-X86-64-NEXT: 0x9 X86_64_RELOC_BRANCH _puts 0x0
200 MACHO-X86-64-NEXT: 0x4 X86_64_RELOC_SIGNED L_.str 0x0
198 MACHO-X86-64-NEXT: 0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction
199 MACHO-X86-64-NEXT: 0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts
200 MACHO-X86-64-NEXT: 0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
201201 MACHO-X86-64-NEXT: ]
202202 MACHO-X86-64-NEXT: Symbols [
203203 MACHO-X86-64-NEXT: Symbol {
329329 relocation_iterator RelI) {
330330 uint64_t Offset;
331331 SmallString<32> RelocName;
332 int64_t Info;
333332 StringRef SymbolName;
334333 SymbolRef Symbol;
335334 if (error(RelI->getOffset(Offset))) return;
336335 if (error(RelI->getTypeName(RelocName))) return;
337 if (error(RelI->getAdditionalInfo(Info))) return;
338336 if (error(RelI->getSymbol(Symbol))) return;
339337 if (error(Symbol.getName(SymbolName))) return;
340338
339 DataRefImpl DR = RelI->getRawDataRefImpl();
340 const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR);
341 bool IsScattered = Obj->isScattered(RE);
342
341343 raw_ostream& OS = W.startLine();
342344 OS << W.hex(Offset)
343 << " " << RelocName
345 << " " << Obj->isPCRel(RE)
346 << " " << Obj->getLength(RE);
347 if (IsScattered)
348 OS << " n/a";
349 else
350 OS << " " << RE->External;
351 OS << " " << RelocName
352 << " " << IsScattered
344353 << " " << (SymbolName.size() > 0 ? SymbolName : "-")
345 << " " << W.hex(Info)
346354 << "\n";
347355 }
348356