brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · f0832db Raw
196 lines · cpp
1//===-- ObjectFilePDB.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "ObjectFilePDB.h"10#include "lldb/Core/Module.h"11#include "lldb/Core/ModuleSpec.h"12#include "lldb/Core/PluginManager.h"13#include "lldb/Core/Section.h"14#include "lldb/Utility/StreamString.h"15#include "llvm/BinaryFormat/Magic.h"16#include "llvm/DebugInfo/PDB/Native/DbiStream.h"17#include "llvm/DebugInfo/PDB/Native/InfoStream.h"18#include "llvm/DebugInfo/PDB/Native/NativeSession.h"19#include "llvm/DebugInfo/PDB/Native/PDBFile.h"20#include "llvm/DebugInfo/PDB/PDB.h"21#include "llvm/Support/BinaryByteStream.h"22 23using namespace lldb;24using namespace lldb_private;25using namespace llvm::pdb;26using namespace llvm::codeview;27 28LLDB_PLUGIN_DEFINE(ObjectFilePDB)29 30static UUID GetPDBUUID(InfoStream &IS, DbiStream &DS) {31  UUID::CvRecordPdb70 debug_info;32  memcpy(&debug_info.Uuid, IS.getGuid().Guid, sizeof(debug_info.Uuid));33  debug_info.Age = DS.getAge();34  return UUID(debug_info);35}36 37char ObjectFilePDB::ID;38 39void ObjectFilePDB::Initialize() {40  PluginManager::RegisterPlugin(GetPluginNameStatic(),41                                GetPluginDescriptionStatic(), CreateInstance,42                                CreateMemoryInstance, GetModuleSpecifications);43}44 45void ObjectFilePDB::Terminate() {46  PluginManager::UnregisterPlugin(CreateInstance);47}48 49ArchSpec ObjectFilePDB::GetArchitecture() {50  auto dbi_stream = m_file_up->getPDBDbiStream();51  if (!dbi_stream) {52    llvm::consumeError(dbi_stream.takeError());53    return ArchSpec();54  }55 56  PDB_Machine machine = dbi_stream->getMachineType();57  switch (machine) {58  default:59    break;60  case PDB_Machine::Amd64:61  case PDB_Machine::x86:62  case PDB_Machine::PowerPC:63  case PDB_Machine::PowerPCFP:64  case PDB_Machine::Arm:65  case PDB_Machine::ArmNT:66  case PDB_Machine::Thumb:67  case PDB_Machine::Arm64:68    ArchSpec arch;69    arch.SetArchitecture(eArchTypeCOFF, static_cast<int>(machine),70                         LLDB_INVALID_CPUTYPE);71    return arch;72  }73  return ArchSpec();74}75 76bool ObjectFilePDB::initPDBFile() {77  m_file_up = loadPDBFile(m_file.GetPath(), m_allocator);78  if (!m_file_up)79    return false;80  auto info_stream = m_file_up->getPDBInfoStream();81  if (!info_stream) {82    llvm::consumeError(info_stream.takeError());83    return false;84  }85  auto dbi_stream = m_file_up->getPDBDbiStream();86  if (!dbi_stream) {87    llvm::consumeError(dbi_stream.takeError());88    return false;89  }90  m_uuid = GetPDBUUID(*info_stream, *dbi_stream);91  return true;92}93 94ObjectFile *95ObjectFilePDB::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp,96                              offset_t data_offset, const FileSpec *file,97                              offset_t file_offset, offset_t length) {98  auto objfile_up = std::make_unique<ObjectFilePDB>(99      module_sp, data_sp, data_offset, file, file_offset, length);100  if (!objfile_up->initPDBFile())101    return nullptr;102  return objfile_up.release();103}104 105ObjectFile *ObjectFilePDB::CreateMemoryInstance(const ModuleSP &module_sp,106                                                WritableDataBufferSP data_sp,107                                                const ProcessSP &process_sp,108                                                addr_t header_addr) {109  return nullptr;110}111 112size_t ObjectFilePDB::GetModuleSpecifications(113    const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,114    offset_t file_offset, offset_t length, ModuleSpecList &specs) {115  const size_t initial_count = specs.GetSize();116  ModuleSpec module_spec(file);117  llvm::BumpPtrAllocator allocator;118  std::unique_ptr<PDBFile> pdb_file = loadPDBFile(file.GetPath(), allocator);119  if (!pdb_file)120    return initial_count;121 122  auto info_stream = pdb_file->getPDBInfoStream();123  if (!info_stream) {124    llvm::consumeError(info_stream.takeError());125    return initial_count;126  }127  auto dbi_stream = pdb_file->getPDBDbiStream();128  if (!dbi_stream) {129    llvm::consumeError(dbi_stream.takeError());130    return initial_count;131  }132 133  lldb_private::UUID &uuid = module_spec.GetUUID();134  uuid = GetPDBUUID(*info_stream, *dbi_stream);135 136  ArchSpec &module_arch = module_spec.GetArchitecture();137  switch (dbi_stream->getMachineType()) {138  case PDB_Machine::Amd64:139    module_arch.SetTriple("x86_64-pc-windows");140    specs.Append(module_spec);141    break;142  case PDB_Machine::x86:143    module_arch.SetTriple("i386-pc-windows");144    specs.Append(module_spec);145    break;146  case PDB_Machine::ArmNT:147    module_arch.SetTriple("armv7-pc-windows");148    specs.Append(module_spec);149    break;150  case PDB_Machine::Arm64:151    module_arch.SetTriple("aarch64-pc-windows");152    specs.Append(module_spec);153    break;154  default:155    break;156  }157 158  return specs.GetSize() - initial_count;159}160 161ObjectFilePDB::ObjectFilePDB(const ModuleSP &module_sp, DataBufferSP &data_sp,162                             offset_t data_offset, const FileSpec *file,163                             offset_t offset, offset_t length)164    : ObjectFile(module_sp, file, offset, length, data_sp, data_offset) {}165 166std::unique_ptr<PDBFile>167ObjectFilePDB::loadPDBFile(std::string PdbPath,168                           llvm::BumpPtrAllocator &Allocator) {169  llvm::file_magic magic;170  auto ec = llvm::identify_magic(PdbPath, magic);171  if (ec || magic != llvm::file_magic::pdb)172    return nullptr;173  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =174      llvm::MemoryBuffer::getFile(PdbPath, /*IsText=*/false,175                                  /*RequiresNullTerminator=*/false);176  if (!ErrorOrBuffer)177    return nullptr;178  std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);179 180  llvm::StringRef Path = Buffer->getBufferIdentifier();181  auto Stream = std::make_unique<llvm::MemoryBufferByteStream>(182      std::move(Buffer), llvm::endianness::little);183 184  auto File = std::make_unique<PDBFile>(Path, std::move(Stream), Allocator);185  if (auto EC = File->parseFileHeaders()) {186    llvm::consumeError(std::move(EC));187    return nullptr;188  }189  if (auto EC = File->parseStreamData()) {190    llvm::consumeError(std::move(EC));191    return nullptr;192  }193 194  return File;195}196