llvm.org GIT mirror llvm / e292347
Add 179294 back, but don't use bit fields so that it works on big endian hosts. Original message: 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@179345 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
5 changed file(s) with 152 addition(s) and 91 deletion(s). Raw diff Collapse all Expand all
111111 MachOInt32 Reserved3;
112112 };
113113
114 struct MachOInt24 {
115 uint8_t bytes[3];
116 operator uint32_t() const {
117 return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];
118 }
119 };
120
114121 template
115122 struct RelocationEntry {
116123 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
117 MachOInt32 Word0;
118 MachOInt32 Word1;
124 MachOInt32 Address;
125 MachOInt24 SymbolNum;
126 uint8_t Bits;
127
128 unsigned getPCRel() const {
129 return Bits & 0x1;
130 }
131 unsigned getLength() const {
132 return (Bits >> 1) & 0x3;
133 }
134 unsigned getExternal() const {
135 return (Bits >> 3) & 0x1;
136 }
137 unsigned getType() const {
138 return Bits >> 4;
139 }
140 };
141
142 template
143 struct ScatteredRelocationEntry {
144 LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
145 MachOInt24 Address;
146 uint8_t Bits;
147 MachOInt32 Value;
148
149 unsigned getType() const {
150 return Bits & 0xf;
151 }
152 unsigned getLength() const {
153 return (Bits >> 4) & 0x3;
154 }
155 unsigned getPCRel() const {
156 return (Bits >> 6) & 0x1;
157 }
158 unsigned getScattered() const {
159 return Bits >> 7;
160 }
119161 };
120162
121163 template
205247 SymbolTableEntryBase;
206248 typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand;
207249 typedef MachOFormat::RelocationEntry RelocationEntry;
250 typedef MachOFormat::ScatteredRelocationEntry
251 ScatteredRelocationEntry;
208252 typedef MachOFormat::SectionBase SectionBase;
209253 typedef MachOFormat::LoadCommand LoadCommand;
210254 typedef MachOFormat::Header Header;
242286 const Header *getHeader() const;
243287 unsigned getHeaderSize() const;
244288 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;
245294
246295 static inline bool classof(const Binary *v) {
247296 return v->isMachO();
478527 const Section *Sect = getSection(Sections[Rel.d.b]);
479528 uint64_t SectAddress = Sect->Address;
480529 const RelocationEntry *RE = getRelocation(Rel);
481 unsigned Arch = getArch();
482 bool isScattered = (Arch != Triple::x86_64) &&
483 (RE->Word0 & macho::RF_Scattered);
484530
485531 uint64_t RelAddr;
486 if (isScattered)
487 RelAddr = RE->Word0 & 0xFFFFFF;
532 if (isScattered(RE))
533 RelAddr = RE->Address & 0xFFFFFF;
488534 else
489 RelAddr = RE->Word0;
535 RelAddr = RE->Address;
490536
491537 Res = SectAddress + RelAddr;
492538 return object_error::success;
497543 MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
498544 uint64_t &Res) const {
499545 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;
546 if (isScattered(RE))
547 Res = RE->Address & 0xFFFFFF;
506548 else
507 Res = RE->Word0;
549 Res = RE->Address;
508550 return object_error::success;
509551 }
510552
513555 MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
514556 SymbolRef &Res) const {
515557 const RelocationEntry *RE = getRelocation(Rel);
516 uint32_t SymbolIdx = RE->Word1 & 0xffffff;
517 bool isExtern = (RE->Word1 >> 27) & 1;
558 uint32_t SymbolIdx = RE->SymbolNum;
559 bool isExtern = RE->getExternal();
518560
519561 DataRefImpl Sym;
520562 moveToNextSymbol(Sym);
534576 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
535577 uint64_t &Res) const {
536578 const RelocationEntry *RE = getRelocation(Rel);
537 Res = RE->Word0;
538 Res <<= 32;
539 Res |= RE->Word1;
579 Res = getType(RE);
540580 return object_error::success;
541581 }
542582
549589 const RelocationEntry *RE = getRelocation(Rel);
550590
551591 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;
592
593 unsigned r_type = getType(RE);
560594
561595 switch (Arch) {
562596 case Triple::x86: {
649683 const RelocationEntry *RE = getRelocation(Rel);
650684
651685 unsigned Arch = getArch();
652 bool isScattered = (Arch != Triple::x86_64) &&
653 (RE->Word0 & macho::RF_Scattered);
686 bool IsScattered = isScattered(RE);
654687
655688 std::string fmtbuf;
656689 raw_string_ostream fmt(fmtbuf);
657690
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);
691 unsigned Type = getType(RE);
692 bool IsPCRel = isPCRel(RE);
669693
670694 // Determine any addends that should be displayed with the relocation.
671695 // These require decoding the relocation type, which is triple-specific.
672696
673697 // X86_64 has entirely custom relocation types.
674698 if (Arch == Triple::x86_64) {
675 bool isPCRel = ((RE->Word1 >> 24) & 1);
699 bool isPCRel = RE->getPCRel();
676700
677701 switch (Type) {
678702 case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
690714 // X86_64_SUBTRACTOR must be followed by a relocation of type
691715 // X86_64_RELOC_UNSIGNED.
692716 // NOTE: Scattered relocations don't exist on x86_64.
693 unsigned RType = (RENext->Word1 >> 28) & 0xF;
717 unsigned RType = RENext->getType();
694718 if (RType != 0)
695719 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
696720 "X86_64_RELOC_SUBTRACTOR.");
737761 // X86 sect diff's must be followed by a relocation of type
738762 // GENERIC_RELOC_PAIR.
739763 bool isNextScattered = (Arch != Triple::x86_64) &&
740 (RENext->Word0 & macho::RF_Scattered);
764 (RENext->Address & macho::RF_Scattered);
741765 unsigned RType;
742766 if (isNextScattered)
743 RType = (RENext->Word0 >> 24) & 0xF;
767 RType = (RENext->Address >> 24) & 0xF;
744768 else
745 RType = (RENext->Word1 >> 28) & 0xF;
769 RType = RENext->getType();
746770 if (RType != 1)
747771 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
748772 "GENERIC_RELOC_SECTDIFF.");
766790 // X86 sect diff's must be followed by a relocation of type
767791 // GENERIC_RELOC_PAIR.
768792 bool isNextScattered = (Arch != Triple::x86_64) &&
769 (RENext->Word0 & macho::RF_Scattered);
793 (RENext->Address & macho::RF_Scattered);
770794 unsigned RType;
771795 if (isNextScattered)
772 RType = (RENext->Word0 >> 24) & 0xF;
796 RType = (RENext->Address >> 24) & 0xF;
773797 else
774 RType = (RENext->Word1 >> 28) & 0xF;
798 RType = RENext->getType();
775799 if (RType != 1)
776800 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
777801 "GENERIC_RELOC_LOCAL_SECTDIFF.");
784808 case macho::RIT_Generic_TLV: {
785809 printRelocationTargetName(RE, fmt);
786810 fmt << "@TLV";
787 if (isPCRel) fmt << "P";
811 if (IsPCRel) fmt << "P";
788812 break;
789813 }
790814 default:
797821 // Half relocations steal a bit from the length field to encode
798822 // whether this is an upper16 or a lower16 relocation.
799823 bool isUpper;
800 if (isScattered)
801 isUpper = (RE->Word0 >> 28) & 1;
824 if (IsScattered)
825 isUpper = (RE->Address >> 28) & 1;
802826 else
803 isUpper = (RE->Word1 >> 25) & 1;
827 isUpper = (RE->getLength() >> 1) & 1;
804828
805829 if (isUpper)
806830 fmt << ":upper16:(";
815839 // ARM half relocs must be followed by a relocation of type
816840 // ARM_RELOC_PAIR.
817841 bool isNextScattered = (Arch != Triple::x86_64) &&
818 (RENext->Word0 & macho::RF_Scattered);
842 (RENext->Address & macho::RF_Scattered);
819843 unsigned RType;
820844 if (isNextScattered)
821 RType = (RENext->Word0 >> 24) & 0xF;
845 RType = (RENext->Address >> 24) & 0xF;
822846 else
823 RType = (RENext->Word1 >> 28) & 0xF;
847 RType = RENext->getType();
824848
825849 if (RType != 1)
826850 report_fatal_error("Expected ARM_RELOC_PAIR after "
859883 MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
860884 bool &Result) const {
861885 const RelocationEntry *RE = getRelocation(Rel);
862
863886 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;
887 unsigned Type = getType(RE);
871888
872889 Result = false;
873890
883900 RelPrev.d.a--;
884901 const RelocationEntry *REPrev = getRelocation(RelPrev);
885902
886 unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
903 unsigned PrevType = REPrev->getType();
887904
888905 if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
889906 }
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->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();
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->getExternal();
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->getExternal();
351 OS << " " << RelocName
352 << " " << IsScattered
344353 << " " << (SymbolName.size() > 0 ? SymbolName : "-")
345 << " " << W.hex(Info)
346354 << "\n";
347355 }
348356