mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	This patch adds the --load-address command line option to llvm-pdbdump, which dumps all addresses assuming the module has loaded at the specified address. Additionally, this patch adds an option to llvm-pdbdump to support dumping of public symbols (i.e. symbols with external linkage). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236342 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			206 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/ADT/STLExtras.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
 | |
| #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
 | |
| #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
 | |
| #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
 | |
| #include "llvm/Support/ConvertUTF.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| namespace {}
 | |
| 
 | |
| DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
 | |
| 
 | |
| PDB_ErrorCode DIASession::createFromPdb(StringRef Path,
 | |
|                                         std::unique_ptr<IPDBSession> &Session) {
 | |
|   CComPtr<IDiaDataSource> DiaDataSource;
 | |
|   CComPtr<IDiaSession> DiaSession;
 | |
| 
 | |
|   // We assume that CoInitializeEx has already been called by the executable.
 | |
|   HRESULT Result = ::CoCreateInstance(
 | |
|       CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
 | |
|       reinterpret_cast<LPVOID *>(&DiaDataSource));
 | |
|   if (FAILED(Result))
 | |
|     return PDB_ErrorCode::NoPdbImpl;
 | |
| 
 | |
|   llvm::SmallVector<UTF16, 128> Path16;
 | |
|   if (!llvm::convertUTF8ToUTF16String(Path, Path16))
 | |
|     return PDB_ErrorCode::InvalidPath;
 | |
| 
 | |
|   const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
 | |
|   if (FAILED(Result = DiaDataSource->loadDataFromPdb(Path16Str))) {
 | |
|     if (Result == E_PDB_NOT_FOUND)
 | |
|       return PDB_ErrorCode::InvalidPath;
 | |
|     else if (Result == E_PDB_FORMAT)
 | |
|       return PDB_ErrorCode::InvalidFileFormat;
 | |
|     else if (Result == E_INVALIDARG)
 | |
|       return PDB_ErrorCode::InvalidParameter;
 | |
|     else if (Result == E_UNEXPECTED)
 | |
|       return PDB_ErrorCode::AlreadyLoaded;
 | |
|     else
 | |
|       return PDB_ErrorCode::UnknownError;
 | |
|   }
 | |
| 
 | |
|   if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
 | |
|     if (Result == E_OUTOFMEMORY)
 | |
|       return PDB_ErrorCode::NoMemory;
 | |
|     else
 | |
|       return PDB_ErrorCode::UnknownError;
 | |
|   }
 | |
| 
 | |
|   Session.reset(new DIASession(DiaSession));
 | |
|   return PDB_ErrorCode::Success;
 | |
| }
 | |
| 
 | |
| PDB_ErrorCode DIASession::createFromExe(StringRef Path,
 | |
|                                         std::unique_ptr<IPDBSession> &Session) {
 | |
|   CComPtr<IDiaDataSource> DiaDataSource;
 | |
|   CComPtr<IDiaSession> DiaSession;
 | |
| 
 | |
|   // We assume that CoInitializeEx has already been called by the executable.
 | |
|   HRESULT Result = ::CoCreateInstance(
 | |
|       CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource,
 | |
|       reinterpret_cast<LPVOID *>(&DiaDataSource));
 | |
|   if (FAILED(Result))
 | |
|     return PDB_ErrorCode::NoPdbImpl;
 | |
| 
 | |
|   llvm::SmallVector<UTF16, 128> Path16;
 | |
|   if (!llvm::convertUTF8ToUTF16String(Path, Path16))
 | |
|     return PDB_ErrorCode::InvalidPath;
 | |
| 
 | |
|   const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data());
 | |
|   if (FAILED(Result =
 | |
|                  DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) {
 | |
|     if (Result == E_PDB_NOT_FOUND)
 | |
|       return PDB_ErrorCode::InvalidPath;
 | |
|     else if (Result == E_PDB_FORMAT)
 | |
|       return PDB_ErrorCode::InvalidFileFormat;
 | |
|     else if (Result == E_PDB_INVALID_SIG || Result == E_PDB_INVALID_AGE)
 | |
|       return PDB_ErrorCode::DebugInfoMismatch;
 | |
|     else if (Result == E_INVALIDARG)
 | |
|       return PDB_ErrorCode::InvalidParameter;
 | |
|     else if (Result == E_UNEXPECTED)
 | |
|       return PDB_ErrorCode::AlreadyLoaded;
 | |
|     else
 | |
|       return PDB_ErrorCode::UnknownError;
 | |
|   }
 | |
| 
 | |
|   if (FAILED(Result = DiaDataSource->openSession(&DiaSession))) {
 | |
|     if (Result == E_OUTOFMEMORY)
 | |
|       return PDB_ErrorCode::NoMemory;
 | |
|     else
 | |
|       return PDB_ErrorCode::UnknownError;
 | |
|   }
 | |
| 
 | |
|   Session.reset(new DIASession(DiaSession));
 | |
|   return PDB_ErrorCode::Success;
 | |
| }
 | |
| 
 | |
| uint64_t DIASession::getLoadAddress() const {
 | |
|   uint64_t LoadAddress;
 | |
|   bool success = (S_OK == Session->get_loadAddress(&LoadAddress));
 | |
|   return (success) ? LoadAddress : 0;
 | |
| }
 | |
| 
 | |
| void DIASession::setLoadAddress(uint64_t Address) {
 | |
|   Session->put_loadAddress(Address);
 | |
| }
 | |
| 
 | |
| std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() const {
 | |
|   CComPtr<IDiaSymbol> GlobalScope;
 | |
|   if (S_OK != Session->get_globalScope(&GlobalScope))
 | |
|     return nullptr;
 | |
| 
 | |
|   auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
 | |
|   auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
 | |
|   std::unique_ptr<PDBSymbolExe> ExeSymbol(
 | |
|       static_cast<PDBSymbolExe *>(PdbSymbol.release()));
 | |
|   return ExeSymbol;
 | |
| }
 | |
| 
 | |
| std::unique_ptr<PDBSymbol> DIASession::getSymbolById(uint32_t SymbolId) const {
 | |
|   CComPtr<IDiaSymbol> LocatedSymbol;
 | |
|   if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
 | |
|     return nullptr;
 | |
| 
 | |
|   auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
 | |
|   return PDBSymbol::create(*this, std::move(RawSymbol));
 | |
| }
 | |
| 
 | |
| std::unique_ptr<PDBSymbol>
 | |
| DIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
 | |
|   enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
 | |
| 
 | |
|   CComPtr<IDiaSymbol> Symbol;
 | |
|   if (S_OK != Session->findSymbolByVA(Address, EnumVal, &Symbol)) {
 | |
|     ULONGLONG LoadAddr = 0;
 | |
|     if (S_OK != Session->get_loadAddress(&LoadAddr))
 | |
|       return nullptr;
 | |
|     DWORD RVA = static_cast<DWORD>(Address - LoadAddr);
 | |
|     if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
 | |
|       return nullptr;
 | |
|   }
 | |
|   auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
 | |
|   return PDBSymbol::create(*this, std::move(RawSymbol));
 | |
| }
 | |
| 
 | |
| std::unique_ptr<IPDBEnumLineNumbers>
 | |
| DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
 | |
|   CComPtr<IDiaEnumLineNumbers> LineNumbers;
 | |
|   if (S_OK != Session->findLinesByVA(Address, Length, &LineNumbers))
 | |
|     return nullptr;
 | |
| 
 | |
|   return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
 | |
| }
 | |
| 
 | |
| std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
 | |
|   CComPtr<IDiaEnumSourceFiles> Files;
 | |
|   if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
 | |
|     return nullptr;
 | |
| 
 | |
|   return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
 | |
| }
 | |
| 
 | |
| std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
 | |
|     const PDBSymbolCompiland &Compiland) const {
 | |
|   CComPtr<IDiaEnumSourceFiles> Files;
 | |
| 
 | |
|   const DIARawSymbol &RawSymbol =
 | |
|       static_cast<const DIARawSymbol &>(Compiland.getRawSymbol());
 | |
|   if (S_OK !=
 | |
|       Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
 | |
|     return nullptr;
 | |
| 
 | |
|   return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
 | |
| }
 | |
| 
 | |
| std::unique_ptr<IPDBSourceFile>
 | |
| DIASession::getSourceFileById(uint32_t FileId) const {
 | |
|   CComPtr<IDiaSourceFile> LocatedFile;
 | |
|   if (S_OK != Session->findFileById(FileId, &LocatedFile))
 | |
|     return nullptr;
 | |
| 
 | |
|   return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
 | |
| }
 | |
| 
 | |
| std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
 | |
|   CComPtr<IDiaEnumDebugStreams> DiaEnumerator;
 | |
|   if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
 | |
|     return nullptr;
 | |
| 
 | |
|   return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
 | |
| }
 |