@@ -425,7 +425,13 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
425425 ArrayRef<Elf_Word> getShndxTable (const Elf_Shdr *Symtab) const ;
426426
427427 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);
429435
430436private:
431437 mutable SmallVector<std::optional<VersionEntry>, 0 > VersionMap;
@@ -6479,15 +6485,16 @@ void ELFDumper<ELFT>::printSFrameHeader(
64796485 if (Expected<ArrayRef<uint8_t >> Aux = Parser.getAuxHeader ())
64806486 W.printHexList (" Auxiliary header" , *Aux);
64816487 else
6482- reportWarning (Aux.takeError (), FileName );
6488+ reportUniqueWarning (Aux.takeError ());
64836489}
64846490
64856491template <typename ELFT>
64866492void ELFDumper<ELFT>::printSFrameFDEs(
6487- const SFrameParser<ELFT::Endianness> &Parser) {
6493+ const SFrameParser<ELFT::Endianness> &Parser,
6494+ ArrayRef<Relocation<ELFT>> Relocations, const Elf_Shdr *RelocSymTab) {
64886495 typename SFrameParser<ELFT::Endianness>::FDERange FDEs;
64896496 if (Error Err = Parser.fdes ().moveInto (FDEs)) {
6490- reportWarning (std::move (Err), FileName );
6497+ reportUniqueWarning (std::move (Err));
64916498 return ;
64926499 }
64936500
@@ -6497,8 +6504,8 @@ void ELFDumper<ELFT>::printSFrameFDEs(
64976504 W,
64986505 formatv (" FuncDescEntry [{0}]" , std::distance (FDEs.begin (), It)).str ());
64996506
6500- uint64_t FDEStartAddress = Parser. getAbsoluteStartAddress (It);
6501- W. printHex ( " PC " , FDEStartAddress );
6507+ uint64_t FDEStartAddress =
6508+ getAndPrintSFrameFDEStartAddress (Parser, It, Relocations, RelocSymTab );
65026509 W.printHex (" Size" , It->Size );
65036510 W.printHex (" Start FRE Offset" , It->StartFREOff );
65046511 W.printNumber (" Num FREs" , It->NumFREs );
@@ -6553,13 +6560,49 @@ void ELFDumper<ELFT>::printSFrameFDEs(
65536560 W.printList (" Extra Offsets" , Offs);
65546561 }
65556562 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);
65576598 }
6599+ return Address;
65586600}
65596601
65606602template <typename ELFT>
65616603void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
65626604 constexpr endianness E = ELFT::Endianness;
6605+
65636606 for (object::SectionRef Section :
65646607 getSectionRefsByNameOrIndex (ObjF, Sections)) {
65656608 // Validity of sections names checked in getSectionRefsByNameOrIndex.
@@ -6570,21 +6613,42 @@ void ELFDumper<ELFT>::printSectionsAsSFrame(ArrayRef<std::string> Sections) {
65706613
65716614 StringRef SectionContent;
65726615 if (Error Err = Section.getContents ().moveInto (SectionContent)) {
6573- reportWarning (std::move (Err), FileName );
6616+ reportUniqueWarning (std::move (Err));
65746617 continue ;
65756618 }
65766619
65776620 Expected<object::SFrameParser<E>> Parser = object::SFrameParser<E>::create (
65786621 arrayRefFromStringRef (SectionContent), Section.getAddress ());
65796622 if (!Parser) {
6580- reportWarning (createError (" invalid sframe section: " +
6581- toString (Parser.takeError ())),
6582- FileName);
6623+ reportUniqueWarning (" invalid sframe section: " +
6624+ toString (Parser.takeError ()));
65836625 continue ;
65846626 }
65856627
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+
65866650 printSFrameHeader (*Parser);
6587- printSFrameFDEs (*Parser);
6651+ printSFrameFDEs (*Parser, Relocations, RelocSymTab );
65886652 }
65896653}
65906654
0 commit comments