@@ -281,56 +281,7 @@ static StringRef ToolName;
281
281
282
282
typedef std::vector<std::tuple<uint64_t , StringRef, uint8_t >> SectionSymbolsTy;
283
283
284
- namespace {
285
- typedef std::function<bool (llvm::object::SectionRef const &)> FilterPredicate;
286
-
287
- class SectionFilterIterator {
288
- public:
289
- SectionFilterIterator (FilterPredicate P,
290
- llvm::object::section_iterator const &I,
291
- llvm::object::section_iterator const &E)
292
- : Predicate(std::move(P)), Iterator(I), End(E) {
293
- ScanPredicate ();
294
- }
295
- const llvm::object::SectionRef &operator *() const { return *Iterator; }
296
- SectionFilterIterator &operator ++() {
297
- ++Iterator;
298
- ScanPredicate ();
299
- return *this ;
300
- }
301
- bool operator !=(SectionFilterIterator const &Other) const {
302
- return Iterator != Other.Iterator ;
303
- }
304
-
305
- private:
306
- void ScanPredicate () {
307
- while (Iterator != End && !Predicate (*Iterator)) {
308
- ++Iterator;
309
- }
310
- }
311
- FilterPredicate Predicate;
312
- llvm::object::section_iterator Iterator;
313
- llvm::object::section_iterator End;
314
- };
315
-
316
- class SectionFilter {
317
- public:
318
- SectionFilter (FilterPredicate P, llvm::object::ObjectFile const &O)
319
- : Predicate(std::move(P)), Object(O) {}
320
- SectionFilterIterator begin () {
321
- return SectionFilterIterator (Predicate, Object.section_begin (),
322
- Object.section_end ());
323
- }
324
- SectionFilterIterator end () {
325
- return SectionFilterIterator (Predicate, Object.section_end (),
326
- Object.section_end ());
327
- }
328
-
329
- private:
330
- FilterPredicate Predicate;
331
- llvm::object::ObjectFile const &Object;
332
- };
333
- SectionFilter ToolSectionFilter (llvm::object::ObjectFile const &O) {
284
+ SectionFilter llvm::ToolSectionFilter (llvm::object::ObjectFile const &O) {
334
285
return SectionFilter (
335
286
[](llvm::object::SectionRef const &S) {
336
287
if (FilterSections.empty ())
@@ -343,7 +294,6 @@ SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) {
343
294
},
344
295
O);
345
296
}
346
- }
347
297
348
298
void llvm::error (std::error_code EC) {
349
299
if (!EC)
@@ -464,388 +414,17 @@ bool llvm::isRelocAddressLess(RelocationRef A, RelocationRef B) {
464
414
return A.getOffset () < B.getOffset ();
465
415
}
466
416
467
- template <class ELFT >
468
- static std::error_code getRelocationValueString (const ELFObjectFile<ELFT> *Obj,
469
- const RelocationRef &RelRef,
470
- SmallVectorImpl<char > &Result) {
471
- typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
472
- typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
473
- typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
474
-
475
- const ELFFile<ELFT> &EF = *Obj->getELFFile ();
476
- DataRefImpl Rel = RelRef.getRawDataRefImpl ();
477
- auto SecOrErr = EF.getSection (Rel.d .a );
478
- if (!SecOrErr)
479
- return errorToErrorCode (SecOrErr.takeError ());
480
-
481
- int64_t Addend = 0 ;
482
- // If there is no Symbol associated with the relocation, we set the undef
483
- // boolean value to 'true'. This will prevent us from calling functions that
484
- // requires the relocation to be associated with a symbol.
485
- //
486
- // In SHT_REL case we would need to read the addend from section data.
487
- // GNU objdump does not do that and we just follow for simplicity.
488
- bool Undef = false ;
489
- if ((*SecOrErr)->sh_type == ELF::SHT_RELA) {
490
- const Elf_Rela *ERela = Obj->getRela (Rel);
491
- Addend = ERela->r_addend ;
492
- Undef = ERela->getSymbol (false ) == 0 ;
493
- } else if ((*SecOrErr)->sh_type != ELF::SHT_REL) {
494
- return object_error::parse_failed;
495
- }
496
-
497
- // Default scheme is to print Target, as well as "+ <addend>" for nonzero
498
- // addend. Should be acceptable for all normal purposes.
499
- std::string FmtBuf;
500
- raw_string_ostream Fmt (FmtBuf);
501
-
502
- if (!Undef) {
503
- symbol_iterator SI = RelRef.getSymbol ();
504
- const Elf_Sym *Sym = Obj->getSymbol (SI->getRawDataRefImpl ());
505
- if (Sym->getType () == ELF::STT_SECTION) {
506
- Expected<section_iterator> SymSI = SI->getSection ();
507
- if (!SymSI)
508
- return errorToErrorCode (SymSI.takeError ());
509
- const Elf_Shdr *SymSec = Obj->getSection ((*SymSI)->getRawDataRefImpl ());
510
- auto SecName = EF.getSectionName (SymSec);
511
- if (!SecName)
512
- return errorToErrorCode (SecName.takeError ());
513
- Fmt << *SecName;
514
- } else {
515
- Expected<StringRef> SymName = SI->getName ();
516
- if (!SymName)
517
- return errorToErrorCode (SymName.takeError ());
518
- if (Demangle)
519
- Fmt << demangle (*SymName);
520
- else
521
- Fmt << *SymName;
522
- }
523
- } else {
524
- Fmt << " *ABS*" ;
525
- }
526
-
527
- if (Addend != 0 )
528
- Fmt << (Addend < 0 ? " " : " +" ) << Addend;
529
- Fmt.flush ();
530
- Result.append (FmtBuf.begin (), FmtBuf.end ());
531
- return std::error_code ();
532
- }
533
-
534
- static std::error_code getRelocationValueString (const ELFObjectFileBase *Obj,
535
- const RelocationRef &Rel,
536
- SmallVectorImpl<char > &Result) {
537
- if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
538
- return getRelocationValueString (ELF32LE, Rel, Result);
539
- if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
540
- return getRelocationValueString (ELF64LE, Rel, Result);
541
- if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
542
- return getRelocationValueString (ELF32BE, Rel, Result);
543
- auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
544
- return getRelocationValueString (ELF64BE, Rel, Result);
545
- }
546
-
547
- static std::error_code getRelocationValueString (const COFFObjectFile *Obj,
548
- const RelocationRef &Rel,
549
- SmallVectorImpl<char > &Result) {
550
- symbol_iterator SymI = Rel.getSymbol ();
551
- Expected<StringRef> SymNameOrErr = SymI->getName ();
552
- if (!SymNameOrErr)
553
- return errorToErrorCode (SymNameOrErr.takeError ());
554
- StringRef SymName = *SymNameOrErr;
555
- Result.append (SymName.begin (), SymName.end ());
556
- return std::error_code ();
557
- }
558
-
559
- static void printRelocationTargetName (const MachOObjectFile *O,
560
- const MachO::any_relocation_info &RE,
561
- raw_string_ostream &Fmt) {
562
- // Target of a scattered relocation is an address. In the interest of
563
- // generating pretty output, scan through the symbol table looking for a
564
- // symbol that aligns with that address. If we find one, print it.
565
- // Otherwise, we just print the hex address of the target.
566
- if (O->isRelocationScattered (RE)) {
567
- uint32_t Val = O->getPlainRelocationSymbolNum (RE);
568
-
569
- for (const SymbolRef &Symbol : O->symbols ()) {
570
- Expected<uint64_t > Addr = Symbol.getAddress ();
571
- if (!Addr)
572
- report_error (O->getFileName (), Addr.takeError ());
573
- if (*Addr != Val)
574
- continue ;
575
- Expected<StringRef> Name = Symbol.getName ();
576
- if (!Name)
577
- report_error (O->getFileName (), Name.takeError ());
578
- Fmt << *Name;
579
- return ;
580
- }
581
-
582
- // If we couldn't find a symbol that this relocation refers to, try
583
- // to find a section beginning instead.
584
- for (const SectionRef &Section : ToolSectionFilter (*O)) {
585
- std::error_code ec;
586
-
587
- StringRef Name;
588
- uint64_t Addr = Section.getAddress ();
589
- if (Addr != Val)
590
- continue ;
591
- if ((ec = Section.getName (Name)))
592
- report_error (O->getFileName (), ec);
593
- Fmt << Name;
594
- return ;
595
- }
596
-
597
- Fmt << format (" 0x%x" , Val);
598
- return ;
599
- }
600
-
601
- StringRef S;
602
- bool isExtern = O->getPlainRelocationExternal (RE);
603
- uint64_t Val = O->getPlainRelocationSymbolNum (RE);
604
-
605
- if (O->getAnyRelocationType (RE) == MachO::ARM64_RELOC_ADDEND) {
606
- Fmt << format (" 0x%0" PRIx64, Val);
607
- return ;
608
- }
609
-
610
- if (isExtern) {
611
- symbol_iterator SI = O->symbol_begin ();
612
- advance (SI, Val);
613
- Expected<StringRef> SOrErr = SI->getName ();
614
- if (!SOrErr)
615
- report_error (O->getFileName (), SOrErr.takeError ());
616
- S = *SOrErr;
617
- } else {
618
- section_iterator SI = O->section_begin ();
619
- // Adjust for the fact that sections are 1-indexed.
620
- if (Val == 0 ) {
621
- Fmt << " 0 (?,?)" ;
622
- return ;
623
- }
624
- uint32_t I = Val - 1 ;
625
- while (I != 0 && SI != O->section_end ()) {
626
- --I;
627
- advance (SI, 1 );
628
- }
629
- if (SI == O->section_end ())
630
- Fmt << Val << " (?,?)" ;
631
- else
632
- SI->getName (S);
633
- }
634
-
635
- Fmt << S;
636
- }
637
-
638
- static std::error_code getRelocationValueString (const WasmObjectFile *Obj,
639
- const RelocationRef &RelRef,
640
- SmallVectorImpl<char > &Result) {
641
- const wasm::WasmRelocation& Rel = Obj->getWasmRelocation (RelRef);
642
- symbol_iterator SI = RelRef.getSymbol ();
643
- std::string FmtBuf;
644
- raw_string_ostream Fmt (FmtBuf);
645
- if (SI == Obj->symbol_end ()) {
646
- // Not all wasm relocations have symbols associated with them.
647
- // In particular R_WEBASSEMBLY_TYPE_INDEX_LEB.
648
- Fmt << Rel.Index ;
649
- } else {
650
- Expected<StringRef> SymNameOrErr = SI->getName ();
651
- if (!SymNameOrErr)
652
- return errorToErrorCode (SymNameOrErr.takeError ());
653
- StringRef SymName = *SymNameOrErr;
654
- Result.append (SymName.begin (), SymName.end ());
655
- }
656
- Fmt << (Rel.Addend < 0 ? " " : " +" ) << Rel.Addend ;
657
- Fmt.flush ();
658
- Result.append (FmtBuf.begin (), FmtBuf.end ());
659
- return std::error_code ();
660
- }
661
-
662
- static std::error_code getRelocationValueString (const MachOObjectFile *Obj,
663
- const RelocationRef &RelRef,
664
- SmallVectorImpl<char > &Result) {
665
- DataRefImpl Rel = RelRef.getRawDataRefImpl ();
666
- MachO::any_relocation_info RE = Obj->getRelocation (Rel);
667
-
668
- unsigned Arch = Obj->getArch ();
669
-
670
- std::string FmtBuf;
671
- raw_string_ostream Fmt (FmtBuf);
672
- unsigned Type = Obj->getAnyRelocationType (RE);
673
- bool IsPCRel = Obj->getAnyRelocationPCRel (RE);
674
-
675
- // Determine any addends that should be displayed with the relocation.
676
- // These require decoding the relocation type, which is triple-specific.
677
-
678
- // X86_64 has entirely custom relocation types.
679
- if (Arch == Triple::x86_64) {
680
- switch (Type) {
681
- case MachO::X86_64_RELOC_GOT_LOAD:
682
- case MachO::X86_64_RELOC_GOT: {
683
- printRelocationTargetName (Obj, RE, Fmt);
684
- Fmt << " @GOT" ;
685
- if (IsPCRel)
686
- Fmt << " PCREL" ;
687
- break ;
688
- }
689
- case MachO::X86_64_RELOC_SUBTRACTOR: {
690
- DataRefImpl RelNext = Rel;
691
- Obj->moveRelocationNext (RelNext);
692
- MachO::any_relocation_info RENext = Obj->getRelocation (RelNext);
693
-
694
- // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
695
- // X86_64_RELOC_UNSIGNED.
696
- // NOTE: Scattered relocations don't exist on x86_64.
697
- unsigned RType = Obj->getAnyRelocationType (RENext);
698
- if (RType != MachO::X86_64_RELOC_UNSIGNED)
699
- report_error (Obj->getFileName (), " Expected X86_64_RELOC_UNSIGNED after "
700
- " X86_64_RELOC_SUBTRACTOR." );
701
-
702
- // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
703
- // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
704
- printRelocationTargetName (Obj, RENext, Fmt);
705
- Fmt << " -" ;
706
- printRelocationTargetName (Obj, RE, Fmt);
707
- break ;
708
- }
709
- case MachO::X86_64_RELOC_TLV:
710
- printRelocationTargetName (Obj, RE, Fmt);
711
- Fmt << " @TLV" ;
712
- if (IsPCRel)
713
- Fmt << " P" ;
714
- break ;
715
- case MachO::X86_64_RELOC_SIGNED_1:
716
- printRelocationTargetName (Obj, RE, Fmt);
717
- Fmt << " -1" ;
718
- break ;
719
- case MachO::X86_64_RELOC_SIGNED_2:
720
- printRelocationTargetName (Obj, RE, Fmt);
721
- Fmt << " -2" ;
722
- break ;
723
- case MachO::X86_64_RELOC_SIGNED_4:
724
- printRelocationTargetName (Obj, RE, Fmt);
725
- Fmt << " -4" ;
726
- break ;
727
- default :
728
- printRelocationTargetName (Obj, RE, Fmt);
729
- break ;
730
- }
731
- // X86 and ARM share some relocation types in common.
732
- } else if (Arch == Triple::x86 || Arch == Triple::arm ||
733
- Arch == Triple::ppc) {
734
- // Generic relocation types...
735
- switch (Type) {
736
- case MachO::GENERIC_RELOC_PAIR: // prints no info
737
- return std::error_code ();
738
- case MachO::GENERIC_RELOC_SECTDIFF: {
739
- DataRefImpl RelNext = Rel;
740
- Obj->moveRelocationNext (RelNext);
741
- MachO::any_relocation_info RENext = Obj->getRelocation (RelNext);
742
-
743
- // X86 sect diff's must be followed by a relocation of type
744
- // GENERIC_RELOC_PAIR.
745
- unsigned RType = Obj->getAnyRelocationType (RENext);
746
-
747
- if (RType != MachO::GENERIC_RELOC_PAIR)
748
- report_error (Obj->getFileName (), " Expected GENERIC_RELOC_PAIR after "
749
- " GENERIC_RELOC_SECTDIFF." );
750
-
751
- printRelocationTargetName (Obj, RE, Fmt);
752
- Fmt << " -" ;
753
- printRelocationTargetName (Obj, RENext, Fmt);
754
- break ;
755
- }
756
- }
757
-
758
- if (Arch == Triple::x86 || Arch == Triple::ppc) {
759
- switch (Type) {
760
- case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
761
- DataRefImpl RelNext = Rel;
762
- Obj->moveRelocationNext (RelNext);
763
- MachO::any_relocation_info RENext = Obj->getRelocation (RelNext);
764
-
765
- // X86 sect diff's must be followed by a relocation of type
766
- // GENERIC_RELOC_PAIR.
767
- unsigned RType = Obj->getAnyRelocationType (RENext);
768
- if (RType != MachO::GENERIC_RELOC_PAIR)
769
- report_error (Obj->getFileName (), " Expected GENERIC_RELOC_PAIR after "
770
- " GENERIC_RELOC_LOCAL_SECTDIFF." );
771
-
772
- printRelocationTargetName (Obj, RE, Fmt);
773
- Fmt << " -" ;
774
- printRelocationTargetName (Obj, RENext, Fmt);
775
- break ;
776
- }
777
- case MachO::GENERIC_RELOC_TLV: {
778
- printRelocationTargetName (Obj, RE, Fmt);
779
- Fmt << " @TLV" ;
780
- if (IsPCRel)
781
- Fmt << " P" ;
782
- break ;
783
- }
784
- default :
785
- printRelocationTargetName (Obj, RE, Fmt);
786
- }
787
- } else { // ARM-specific relocations
788
- switch (Type) {
789
- case MachO::ARM_RELOC_HALF:
790
- case MachO::ARM_RELOC_HALF_SECTDIFF: {
791
- // Half relocations steal a bit from the length field to encode
792
- // whether this is an upper16 or a lower16 relocation.
793
- bool isUpper = (Obj->getAnyRelocationLength (RE) & 0x1 ) == 1 ;
794
-
795
- if (isUpper)
796
- Fmt << " :upper16:(" ;
797
- else
798
- Fmt << " :lower16:(" ;
799
- printRelocationTargetName (Obj, RE, Fmt);
800
-
801
- DataRefImpl RelNext = Rel;
802
- Obj->moveRelocationNext (RelNext);
803
- MachO::any_relocation_info RENext = Obj->getRelocation (RelNext);
804
-
805
- // ARM half relocs must be followed by a relocation of type
806
- // ARM_RELOC_PAIR.
807
- unsigned RType = Obj->getAnyRelocationType (RENext);
808
- if (RType != MachO::ARM_RELOC_PAIR)
809
- report_error (Obj->getFileName (), " Expected ARM_RELOC_PAIR after "
810
- " ARM_RELOC_HALF" );
811
-
812
- // NOTE: The half of the target virtual address is stashed in the
813
- // address field of the secondary relocation, but we can't reverse
814
- // engineer the constant offset from it without decoding the movw/movt
815
- // instruction to find the other half in its immediate field.
816
-
817
- // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
818
- // symbol/section pointer of the follow-on relocation.
819
- if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
820
- Fmt << " -" ;
821
- printRelocationTargetName (Obj, RENext, Fmt);
822
- }
823
-
824
- Fmt << " )" ;
825
- break ;
826
- }
827
- default : { printRelocationTargetName (Obj, RE, Fmt); }
828
- }
829
- }
830
- } else
831
- printRelocationTargetName (Obj, RE, Fmt);
832
-
833
- Fmt.flush ();
834
- Result.append (FmtBuf.begin (), FmtBuf.end ());
835
- return std::error_code ();
836
- }
837
-
838
417
static std::error_code getRelocationValueString (const RelocationRef &Rel,
839
418
SmallVectorImpl<char > &Result) {
840
419
const ObjectFile *Obj = Rel.getObject ();
841
420
if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
842
- return getRelocationValueString (ELF, Rel, Result);
421
+ return getELFRelocationValueString (ELF, Rel, Result);
843
422
if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
844
- return getRelocationValueString (COFF, Rel, Result);
423
+ return getCOFFRelocationValueString (COFF, Rel, Result);
845
424
if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
846
- return getRelocationValueString (Wasm, Rel, Result);
425
+ return getWasmRelocationValueString (Wasm, Rel, Result);
847
426
if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
848
- return getRelocationValueString (MachO, Rel, Result);
427
+ return getMachORelocationValueString (MachO, Rel, Result);
849
428
llvm_unreachable (" unknown object file format" );
850
429
}
851
430
0 commit comments