@@ -425,7 +425,13 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
425
425
ArrayRef<Elf_Word> getShndxTable (const Elf_Shdr *Symtab) const ;
426
426
427
427
void printSFrameHeader (const SFrameParser<ELFT::Endianness> &Parser);
428
- void printSFrameFDEs (const SFrameParser<ELFT::Endianness> &Parser);
428
+ void printSFrameFDEs (const SFrameParser<ELFT::Endianness> &Parser,
429
+ ArrayRef<Relocation<ELFT>> Relocations,
430
+ const Elf_Shdr *RelocSymTab);
431
+ uint64_t getAndPrintSFrameFDEStartAddress (
432
+ const SFrameParser<ELFT::Endianness> &Parser,
433
+ const typename SFrameParser<ELFT::Endianness>::FDERange::iterator FDE,
434
+ ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab);
429
435
430
436
private:
431
437
mutable SmallVector<std::optional<VersionEntry>, 0 > VersionMap;
@@ -6479,15 +6485,16 @@ void ELFDumper<ELFT>::printSFrameHeader(
6479
6485
if (Expected<ArrayRef<uint8_t >> Aux = Parser.getAuxHeader ())
6480
6486
W.printHexList (" Auxiliary header" , *Aux);
6481
6487
else
6482
- reportWarning (Aux.takeError (), FileName );
6488
+ reportUniqueWarning (Aux.takeError ());
6483
6489
}
6484
6490
6485
6491
template <typename ELFT>
6486
6492
void ELFDumper<ELFT>::printSFrameFDEs(
6487
- const SFrameParser<ELFT::Endianness> &Parser) {
6493
+ const SFrameParser<ELFT::Endianness> &Parser,
6494
+ ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab) {
6488
6495
typename SFrameParser<ELFT::Endianness>::FDERange FDEs;
6489
6496
if (Error Err = Parser.fdes ().moveInto (FDEs)) {
6490
- reportWarning (std::move (Err), FileName );
6497
+ reportUniqueWarning (std::move (Err));
6491
6498
return ;
6492
6499
}
6493
6500
@@ -6497,8 +6504,8 @@ void ELFDumper<ELFT>::printSFrameFDEs(
6497
6504
W,
6498
6505
formatv (" FuncDescEntry [{0}]" , std::distance (FDEs.begin (), It)).str ());
6499
6506
6500
- uint64_t FDEStartAddress = Parser. getAbsoluteStartAddress (It);
6501
- W. printHex ( " PC " , FDEStartAddress );
6507
+ uint64_t FDEStartAddress =
6508
+ getAndPrintSFrameFDEStartAddress (Parser, It, Relocations, RelocSymTab );
6502
6509
W.printHex (" Size" , It->Size );
6503
6510
W.printHex (" Start FRE Offset" , It->StartFREOff );
6504
6511
W.printNumber (" Num FREs" , It->NumFREs );
@@ -6553,13 +6560,49 @@ void ELFDumper<ELFT>::printSFrameFDEs(
6553
6560
W.printList (" Extra Offsets" , Offs);
6554
6561
}
6555
6562
if (Err)
6556
- reportWarning (std::move (Err), FileName);
6563
+ reportUniqueWarning (std::move (Err));
6564
+ }
6565
+ }
6566
+
6567
+ template <typename ELFT>
6568
+ uint64_t ELFDumper<ELFT>::getAndPrintSFrameFDEStartAddress(
6569
+ const SFrameParser<ELFT::Endianness> &Parser,
6570
+ const typename SFrameParser<ELFT::Endianness>::FDERange::iterator FDE,
6571
+ ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab) {
6572
+ uint64_t Address = Parser.getAbsoluteStartAddress (FDE);
6573
+ uint64_t Offset = Parser.offsetOf (FDE);
6574
+
6575
+ auto Reloc = llvm::lower_bound (
6576
+ Relocations, Offset, [](auto R, uint64_t O) { return R.Offset < O; });
6577
+ if (Reloc == Relocations.end () || Reloc->Offset != Offset) {
6578
+ W.printHex (" PC" , Address);
6579
+ } else if (std::next (Reloc) != Relocations.end () &&
6580
+ std::next (Reloc)->Offset == Offset) {
6581
+ reportUniqueWarning (
6582
+ formatv (" more than one relocation at offset {0:x+}" , Offset));
6583
+ W.printHex (" PC" , Address);
6584
+ } else if (Expected<RelSymbol<ELFT>> RelSym =
6585
+ getRelocationTarget (*Reloc, RelocSymTab);
6586
+ !RelSym) {
6587
+ reportUniqueWarning (RelSym.takeError ());
6588
+ W.printHex (" PC" , Address);
6589
+ } else {
6590
+ // Exactly one relocation at the given offset. Print it.
6591
+ DictScope PCScope (W, " PC" );
6592
+ SmallString<32 > RelocName;
6593
+ Obj.getRelocationTypeName (Reloc->Type , RelocName);
6594
+ W.printString (" Relocation" , RelocName);
6595
+ W.printString (" Symbol Name" , RelSym->Name );
6596
+ Address = FDE->StartAddress + Reloc->Addend .value_or (0 );
6597
+ W.printHex (" Start Address" , Address);
6557
6598
}
6599
+ return Address;
6558
6600
}
6559
6601
6560
6602
template <typename ELFT>
6561
6603
void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
6562
6604
constexpr endianness E = ELFT::Endianness;
6605
+
6563
6606
for (object::SectionRef Section :
6564
6607
getSectionRefsByNameOrIndex (ObjF, Sections)) {
6565
6608
// Validity of sections names checked in getSectionRefsByNameOrIndex.
@@ -6570,21 +6613,42 @@ void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
6570
6613
6571
6614
StringRef SectionContent;
6572
6615
if (Error Err = Section.getContents ().moveInto (SectionContent)) {
6573
- reportWarning (std::move (Err), FileName );
6616
+ reportUniqueWarning (std::move (Err));
6574
6617
continue ;
6575
6618
}
6576
6619
6577
6620
Expected<object::SFrameParser<E>> Parser = object::SFrameParser<E>::create (
6578
6621
arrayRefFromStringRef (SectionContent), Section.getAddress ());
6579
6622
if (!Parser) {
6580
- reportWarning (createError (" invalid sframe section: " +
6581
- toString (Parser.takeError ())),
6582
- FileName);
6623
+ reportUniqueWarning (" invalid sframe section: " +
6624
+ toString (Parser.takeError ()));
6583
6625
continue ;
6584
6626
}
6585
6627
6628
+ const Elf_Shdr *ELFSection = ObjF.getSection (Section.getRawDataRefImpl ());
6629
+ MapVector<const Elf_Shdr *, const Elf_Shdr *> RelocationMap;
6630
+ if (Error Err = Obj.getSectionAndRelocations (
6631
+ [&](const Elf_Shdr &S) { return &S == ELFSection; })
6632
+ .moveInto (RelocationMap)) {
6633
+ reportUniqueWarning (std::move (Err));
6634
+ }
6635
+
6636
+ std::vector<Relocation<ELFT>> Relocations;
6637
+ const Elf_Shdr *RelocSymTab = nullptr ;
6638
+ if (const Elf_Shdr *RelocSection = RelocationMap.lookup (ELFSection)) {
6639
+ forEachRelocationDo (*RelocSection,
6640
+ [&](const Relocation<ELFT> &R, unsigned Ndx,
6641
+ const Elf_Shdr &Sec, const Elf_Shdr *SymTab) {
6642
+ RelocSymTab = SymTab;
6643
+ Relocations.push_back (R);
6644
+ });
6645
+ llvm::stable_sort (Relocations, [](const auto &LHS, const auto &RHS) {
6646
+ return LHS.Offset < RHS.Offset ;
6647
+ });
6648
+ }
6649
+
6586
6650
printSFrameHeader (*Parser);
6587
- printSFrameFDEs (*Parser);
6651
+ printSFrameFDEs (*Parser, Relocations, RelocSymTab );
6588
6652
}
6589
6653
}
6590
6654
0 commit comments