diff options
Diffstat (limited to 'contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp | 67 | 
1 files changed, 61 insertions, 6 deletions
diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp index e64b8f157180..380baae2eeb4 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp @@ -7,6 +7,7 @@  //===----------------------------------------------------------------------===//  #include "Win64EHDumper.h" +#include "Error.h"  #include "llvm-readobj.h"  #include "llvm/Object/COFF.h"  #include "llvm/Support/ErrorHandling.h" @@ -111,6 +112,20 @@ static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {    }  } +static std::error_code getSymbol(const COFFObjectFile &COFF, uint64_t VA, +                                 object::SymbolRef &Sym) { +  for (const auto &Symbol : COFF.symbols()) { +    Expected<uint64_t> Address = Symbol.getAddress(); +    if (!Address) +      return errorToErrorCode(Address.takeError()); +    if (*Address == VA) { +      Sym = Symbol; +      return readobj_error::success; +    } +  } +  return readobj_error::unknown_symbol; +} +  static std::string formatSymbol(const Dumper::Context &Ctx,                                  const coff_section *Section, uint64_t Offset,                                  uint32_t Displacement) { @@ -131,9 +146,22 @@ static std::string formatSymbol(const Dumper::Context &Ctx,        // TODO: Actually report errors helpfully.        consumeError(Name.takeError());      } +  } else if (!getSymbol(Ctx.COFF, Ctx.COFF.getImageBase() + Displacement, +                        Symbol)) { +    Expected<StringRef> Name = Symbol.getName(); +    if (Name) { +      OS << *Name; +      OS << format(" (0x%" PRIX64 ")", Ctx.COFF.getImageBase() + Displacement); +      return OS.str(); +    } else { +      consumeError(Name.takeError()); +    }    } -  OS << format(" (0x%" PRIX64 ")", Offset); +  if (Displacement > 0) +    OS << format("(0x%" PRIX64 ")", Ctx.COFF.getImageBase() + Displacement); +  else +    OS << format("(0x%" PRIX64 ")", Offset);    return OS.str();  } @@ -159,6 +187,18 @@ static std::error_code resolveRelocation(const Dumper::Context &Ctx,    return std::error_code();  } +static const object::coff_section * +getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) { +  for (const auto &Section : COFF.sections()) { +    uint64_t Address = Section.getAddress(); +    uint64_t Size = Section.getSize(); + +    if (VA >= Address && (VA - Address) <= Size) +      return COFF.getCOFFSection(Section); +  } +  return nullptr; +} +  namespace llvm {  namespace Win64EH {  void Dumper::printRuntimeFunctionEntry(const Context &Ctx, @@ -284,16 +324,26 @@ void Dumper::printRuntimeFunction(const Context &Ctx,    DictScope RFS(SW, "RuntimeFunction");    printRuntimeFunctionEntry(Ctx, Section, SectionOffset, RF); -  const coff_section *XData; +  const coff_section *XData = nullptr;    uint64_t Offset;    resolveRelocation(Ctx, Section, SectionOffset + 8, XData, Offset); +  Offset = Offset + RF.UnwindInfoOffset; + +  if (!XData) { +    uint64_t Address = Ctx.COFF.getImageBase() + RF.UnwindInfoOffset; +    XData = getSectionContaining(Ctx.COFF, Address); +    if (!XData) +      return; +    Offset = RF.UnwindInfoOffset - XData->VirtualAddress; +  }    ArrayRef<uint8_t> Contents; -  error(Ctx.COFF.getSectionContents(XData, Contents)); +  if (Error E = Ctx.COFF.getSectionContents(XData, Contents)) +    reportError(std::move(E), Ctx.COFF.getFileName()); +    if (Contents.empty())      return; -  Offset = Offset + RF.UnwindInfoOffset;    if (Offset > Contents.size())      return; @@ -304,14 +354,19 @@ void Dumper::printRuntimeFunction(const Context &Ctx,  void Dumper::printData(const Context &Ctx) {    for (const auto &Section : Ctx.COFF.sections()) {      StringRef Name; -    Section.getName(Name); +    if (Expected<StringRef> NameOrErr = Section.getName()) +      Name = *NameOrErr; +    else +      consumeError(NameOrErr.takeError());      if (Name != ".pdata" && !Name.startswith(".pdata$"))        continue;      const coff_section *PData = Ctx.COFF.getCOFFSection(Section);      ArrayRef<uint8_t> Contents; -    error(Ctx.COFF.getSectionContents(PData, Contents)); + +    if (Error E = Ctx.COFF.getSectionContents(PData, Contents)) +      reportError(std::move(E), Ctx.COFF.getFileName());      if (Contents.empty())        continue;  | 
