26#define DEBUG_TYPE "ReaderHandler" 
   29  if (
Error Err = createReaders())
 
   31  if (
Error Err = printReaders())
 
   33  if (
Error Err = compareReaders())
 
 
   42  auto CreateOneReader = [&]() -> std::unique_ptr<LVReader> {
 
   47        return std::make_unique<LVCodeViewReader>(
Filename, FileFormatName,
 
   51        return std::make_unique<LVDWARFReader>(
Filename, FileFormatName, Obj,
 
   56      return std::make_unique<LVCodeViewReader>(
Filename, FileFormatName, 
Pdb,
 
   62  std::unique_ptr<LVReader> ReaderObj = CreateOneReader();
 
   65                             "unable to create reader for: '%s'",
 
   68  LVReader *Reader = ReaderObj.get();
 
   69  Readers.emplace_back(std::move(ReaderObj));
 
   76  for (
const Archive::Child &Child : Arch.
children(Err)) {
 
   77    Expected<MemoryBufferRef> BuffOrErr = Child.getMemoryBufferRef();
 
   81    Expected<StringRef> NameOrErr = Child.getName();
 
   86    if (
Error Err = handleBuffer(Readers, 
Name, BuffOrErr.
get()))
 
  103  std::unique_ptr<IPDBSession> Session;
 
  117  if (ConvertedPath == 
Path)
 
  118    return std::string(ExePath);
 
 
  133    return std::string(ObjPath);
 
 
  140                                    MemoryBufferRef Buffer, StringRef ExePath) {
 
  145    if (!ExePath.
empty())
 
  152    std::vector<StringRef> ExecutableExtensions = {
"exe", 
"dll"};
 
  153    for (StringRef Extension : ExecutableExtensions) {
 
  155      if (ExecutableImage.empty())
 
  165    std::vector<StringRef> ObjectExtensions = {
"o", 
"obj", 
"lib"};
 
  166    for (StringRef Extension : ObjectExtensions) {
 
  168      if (ObjectImage.empty())
 
  170      if (
Error Err = handleFile(Readers, ObjectImage)) {
 
  186          "Binary object format in '%s' does not have debug info.",
 
  190    return handleFile(Readers, PdbPath.
get(), 
Filename);
 
  193  Expected<std::unique_ptr<Binary>> BinOrErr = 
createBinary(Buffer);
 
  196                             "Binary object format in '%s' is not supported.",
 
  199  return handleObject(Readers, 
Filename, *BinOrErr.
get());
 
  205  std::string ConvertedPath =
 
  207  ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
 
  211                             "File '%s' does not exist.",
 
  212                             ConvertedPath.c_str());
 
  214  std::unique_ptr<MemoryBuffer> Buffer = std::move(BuffOrErr.
get());
 
  215  return handleBuffer(Readers, ConvertedPath, *Buffer, ExePath);
 
  219                                  MachOUniversalBinary &Mach) {
 
  220  for (
const MachOUniversalBinary::ObjectForArch &ObjForArch : Mach.
objects()) {
 
  221    std::string ObjName = (Twine(
Filename) + Twine(
"(") +
 
  222                           Twine(ObjForArch.getArchFlagName()) + Twine(
")"))
 
  224    if (Expected<std::unique_ptr<MachOObjectFile>> MachOOrErr =
 
  225            ObjForArch.getAsObjectFile()) {
 
  226      MachOObjectFile &Obj = **MachOOrErr;
 
  234    if (Expected<std::unique_ptr<Archive>> ArchiveOrErr =
 
  235            ObjForArch.getAsArchive()) {
 
  236      if (
Error Err = handleArchive(Readers, ObjName, *ArchiveOrErr.get()))
 
  248    return createReader(
Filename, Readers, Input,
 
  252    return handleMach(Readers, 
Filename, *Fat);
 
  255    return handleArchive(Readers, 
Filename, *Arch);
 
  258                           "Binary object format in '%s' is not supported.",
 
  263                                    StringRef Buffer, StringRef ExePath) {
 
  264  std::unique_ptr<IPDBSession> Session;
 
  269  std::unique_ptr<NativeSession> PdbSession;
 
  270  PdbSession.reset(
static_cast<NativeSession *
>(Session.release()));
 
  271  PdbOrObj Input = &PdbSession->getPDBFile();
 
  272  StringRef FileFormatName;
 
  275    FileFormatName = Buffer.
substr(0, Pos - 1);
 
  276  return createReader(
Filename, Readers, Input, FileFormatName, ExePath);
 
  279Error LVReaderHandler::createReaders() {
 
  281  for (std::string &Object : Objects) {
 
  283    if (
Error Err = createReader(Object, Readers))
 
  285    TheReaders.insert(TheReaders.end(),
 
  286                      std::make_move_iterator(Readers.begin()),
 
  287                      std::make_move_iterator(Readers.end()));
 
  293Error LVReaderHandler::printReaders() {
 
  295  if (
options().getPrintExecute())
 
  296    for (
const std::unique_ptr<LVReader> &Reader : TheReaders)
 
  303Error LVReaderHandler::compareReaders() {
 
  305  size_t ReadersCount = TheReaders.size();
 
  306  if (
options().getCompareExecute() && ReadersCount >= 2) {
 
  308    size_t ViewPairs = ReadersCount / 2;
 
  310    for (
size_t Pair = 0, Index = 0; Pair < ViewPairs; ++Pair) {
 
  311      if (
Error Err = 
Compare.execute(TheReaders[Index].get(),
 
  312                                      TheReaders[Index + 1].get()))
 
static std::string searchForObj(const StringRef Path, const StringRef Extension)
 
static std::string searchForExe(const StringRef Path, const StringRef Extension)
 
Represents either an error or a value T.
 
std::error_code getError() const
 
Lightweight error class with error context and mandatory checking.
 
static ErrorSuccess success()
Create a success value.
 
Tagged union holding either a T or a Error.
 
Error takeError()
Take ownership of the stored error.
 
reference get()
Returns a reference to the stored T value.
 
StringRef getBuffer() const
 
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
 
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
 
StringRef - Represent a constant reference to a string, i.e.
 
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
 
constexpr bool empty() const
empty - Check if the string is empty.
 
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
 
LLVM_ABI void print(raw_ostream &OS) const
 
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
 
StringRef getFileFormatName() const override
 
iterator_range< object_iterator > objects() const
 
static Expected< std::string > searchForPdb(const PdbSearchOptions &Opts)
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
std::vector< std::unique_ptr< LVReader > > LVReaders
 
PointerUnion< object::ObjectFile *, pdb::PDBFile * > PdbOrObj
 
LLVM_ABI Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
 
LLVM_ABI Error loadDataForEXE(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)
 
LLVM_ABI Error loadDataForPDB(PDB_ReaderType Type, StringRef Path, std::unique_ptr< IPDBSession > &Session)
 
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
 
LLVM_ABI void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
 
LLVM_ABI std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
 
This is an optimization pass for GlobalISel generic memory operations.
 
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
LLVM_ABI std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
@ pdb
Windows PDB debug info file.
 
@ pecoff_executable
PECOFF executable file.