Diff
checker
텍스트
텍스트
이미지
문서
Excel
폴더
Legal
Enterprise
데스크톱
요금제
로그인
데스크톱 앱 다운로드
텍스트 비교
두 텍스트 파일의 차이점을 찾아보세요
도구
기록
표시
레이아웃
나란히 보기
합쳐 보기
실시간 편집
공백 변경 숨기기
변경 없는 행 숨기기
줄바꿈 비활성화
비교 단위
스마트
구문
없음
모양 변경
처리
제외
텍스트 변환
첫 변경으로
수정
Diffchecker Desktop
가장 안전하게 Diffchecker를 사용하는 방법. 데스크톱 앱을 사용하면 비교 데이터가 외부로 전송되지 않습니다!
데스크톱 앱 받기
Untitled diff
생성일
10년 전
비교 결과 만료 없음
초기화
내보내기
공유
설명
1 삭제
행
총
삭제
글자
총
삭제
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
290 행
복사
2 추가
행
총
추가
글자
총
추가
이 기능을 계속 사용하려면 업그레이드해 주세요
Diff
checker
Pro
요금제 보기
290 행
복사
//===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===//
//===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===//
//
//
// The LLVM Compiler Infrastructure
// The LLVM Compiler Infrastructure
//
//
// This file is distributed under the University of Illinois Open Source
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// License. See LICENSE.TXT for details.
//
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
#include "llvm/DebugInfo/PDB/DIA/DIAError.h"
#include "llvm/DebugInfo/PDB/DIA/DIAError.h"
#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h"
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
#include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h"
#include "llvm/DebugInfo/PDB/DIA/DIASupport.h"
#include "llvm/DebugInfo/PDB/DIA/DIASupport.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/GenericError.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ConvertUTF.h"
using namespace llvm;
using namespace llvm;
using namespace llvm::pdb;
using namespace llvm::pdb;
namespace {
namespace {
Error ErrorFromHResult(HRESULT Result) {
Error ErrorFromHResult(HRESULT Result) {
switch (Result) {
switch (Result) {
case E_PDB_NOT_FOUND:
case E_PDB_NOT_FOUND:
return make_error<GenericError>(generic_error_code::invalid_path);
return make_error<GenericError>(generic_error_code::invalid_path);
case E_PDB_FORMAT:
case E_PDB_FORMAT:
return make_error<DIAError>(dia_error_code::invalid_file_format);
return make_error<DIAError>(dia_error_code::invalid_file_format);
case E_INVALIDARG:
case E_INVALIDARG:
return make_error<DIAError>(dia_error_code::invalid_parameter);
return make_error<DIAError>(dia_error_code::invalid_parameter);
case E_UNEXPECTED:
case E_UNEXPECTED:
return make_error<DIAError>(dia_error_code::already_loaded);
return make_error<DIAError>(dia_error_code::already_loaded);
case E_PDB_INVALID_SIG:
case E_PDB_INVALID_SIG:
case E_PDB_INVALID_AGE:
case E_PDB_INVALID_AGE:
return make_error<DIAError>(dia_error_code::debug_info_mismatch);
return make_error<DIAError>(dia_error_code::debug_info_mismatch);
default:
default:
return make_error<DIAError>(dia_error_code::unspecified);
return make_error<DIAError>(dia_error_code::unspecified);
}
}
}
}
Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) {
Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) {
if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER,
if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER,
IID_IDiaDataSource,
IID_IDiaDataSource,
reinterpret_cast<LPVOID *>(&DiaDataSource))))
reinterpret_cast<LPVOID *>(&DiaDataSource))))
return Error::success();
return Error::success();
// If the CoCreateInstance call above failed, msdia*.dll is not registered.
// If the CoCreateInstance call above failed, msdia*.dll is not registered.
// Try loading the DLL corresponding to the #included DIA SDK.
// Try loading the DLL corresponding to the #included DIA SDK.
#if !defined(_MSC_VER)
#if !defined(_MSC_VER)
return llvm::make_error<GenericError>(
return llvm::make_error<GenericError>(
"DIA is only supported when using MSVC.");
"DIA is only supported when using MSVC.");
#endif
#endif
const wchar_t *msdia_dll = nullptr;
const wchar_t *msdia_dll = nullptr;
복사
복사됨
복사
복사됨
#if _MSC_VER
=
= 1900
#if _MSC_VER
>
= 1900
&& _MSC_VER < 2000
msdia_dll = L"msdia140.dll"; // VS2015
msdia_dll = L"msdia140.dll"; // VS2015
#elif _MSC_VER == 1800
#elif _MSC_VER == 1800
msdia_dll = L"msdia120.dll"; // VS2013
msdia_dll = L"msdia120.dll"; // VS2013
#else
#else
#error "Unknown Visual Studio version."
#error "Unknown Visual Studio version."
#endif
#endif
HRESULT HR;
HRESULT HR;
if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
reinterpret_cast<LPVOID *>(&DiaDataSource))))
reinterpret_cast<LPVOID *>(&DiaDataSource))))
return ErrorFromHResult(HR);
return ErrorFromHResult(HR);
return Error::success();
return Error::success();
}
}
}
}
DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {}
Error DIASession::createFromPdb(StringRef Path,
Error DIASession::createFromPdb(StringRef Path,
std::unique_ptr<IPDBSession> &Session) {
std::unique_ptr<IPDBSession> &Session) {
CComPtr<IDiaDataSource> DiaDataSource;
CComPtr<IDiaDataSource> DiaDataSource;
CComPtr<IDiaSession> DiaSession;
CComPtr<IDiaSession> DiaSession;
// We assume that CoInitializeEx has already been called by the executable.
// We assume that CoInitializeEx has already been called by the executable.
if (auto E = LoadDIA(DiaDataSource))
if (auto E = LoadDIA(DiaDataSource))
return E;
return E;
llvm::SmallVector<UTF16, 128> Path16;
llvm::SmallVector<UTF16, 128> Path16;
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
if (!llvm::convertUTF8ToUTF16String(Path, Path16))
return make_error<GenericError>(generic_error_code::invalid_path);
return make_error<GenericError>(generic_error_code::invalid_path);
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
HRESULT HR;
HRESULT HR;
if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str)))
if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str)))
return ErrorFromHResult(HR);
return ErrorFromHResult(HR);
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR);
return ErrorFromHResult(HR);
저장된 비교 결과
원본
파일 열기
//===- 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/DebugInfo/PDB/DIA/DIASession.h" #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/DIAError.h" #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h" #include "llvm/DebugInfo/PDB/DIA/DIASupport.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/Support/ConvertUTF.h" using namespace llvm; using namespace llvm::pdb; namespace { Error ErrorFromHResult(HRESULT Result) { switch (Result) { case E_PDB_NOT_FOUND: return make_error<GenericError>(generic_error_code::invalid_path); case E_PDB_FORMAT: return make_error<DIAError>(dia_error_code::invalid_file_format); case E_INVALIDARG: return make_error<DIAError>(dia_error_code::invalid_parameter); case E_UNEXPECTED: return make_error<DIAError>(dia_error_code::already_loaded); case E_PDB_INVALID_SIG: case E_PDB_INVALID_AGE: return make_error<DIAError>(dia_error_code::debug_info_mismatch); default: return make_error<DIAError>(dia_error_code::unspecified); } } Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) { if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource, reinterpret_cast<LPVOID *>(&DiaDataSource)))) return Error::success(); // If the CoCreateInstance call above failed, msdia*.dll is not registered. // Try loading the DLL corresponding to the #included DIA SDK. #if !defined(_MSC_VER) return llvm::make_error<GenericError>( "DIA is only supported when using MSVC."); #endif const wchar_t *msdia_dll = nullptr; #if _MSC_VER == 1900 msdia_dll = L"msdia140.dll"; // VS2015 #elif _MSC_VER == 1800 msdia_dll = L"msdia120.dll"; // VS2013 #else #error "Unknown Visual Studio version." #endif HRESULT HR; if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource, reinterpret_cast<LPVOID *>(&DiaDataSource)))) return ErrorFromHResult(HR); return Error::success(); } } DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {} Error 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. if (auto E = LoadDIA(DiaDataSource)) return E; llvm::SmallVector<UTF16, 128> Path16; if (!llvm::convertUTF8ToUTF16String(Path, Path16)) return make_error<GenericError>(generic_error_code::invalid_path); const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data()); HRESULT HR; if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) return ErrorFromHResult(HR); if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) return ErrorFromHResult(HR); Session.reset(new DIASession(DiaSession)); return Error::success(); } Error 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. if (auto EC = LoadDIA(DiaDataSource)) return EC; llvm::SmallVector<UTF16, 128> Path16; if (!llvm::convertUTF8ToUTF16String(Path, Path16)) return make_error<GenericError>(generic_error_code::invalid_path, Path); const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data()); HRESULT HR; if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) return ErrorFromHResult(HR); if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) return ErrorFromHResult(HR); Session.reset(new DIASession(DiaSession)); return Error::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::findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const { const DIARawSymbol &RawCompiland = static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); const DIASourceFile &RawFile = static_cast<const DIASourceFile &>(File); CComPtr<IDiaEnumLineNumbers> LineNumbers; if (S_OK != Session->findLines(RawCompiland.getDiaSymbol(), RawFile.getDiaFile(), &LineNumbers)) return nullptr; return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers); } 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::findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { IDiaSymbol *DiaCompiland = nullptr; CComBSTR Utf16Pattern; if (!Pattern.empty()) Utf16Pattern = CComBSTR(Pattern.data()); if (Compiland) DiaCompiland = static_cast<const DIARawSymbol &>(Compiland->getRawSymbol()) .getDiaSymbol(); Flags = static_cast<PDB_NameSearchFlags>( Flags | PDB_NameSearchFlags::NS_FileNameExtMatch); CComPtr<IDiaEnumSourceFiles> SourceFiles; if (S_OK != Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles)) return nullptr; return llvm::make_unique<DIAEnumSourceFiles>(*this, SourceFiles); } std::unique_ptr<IPDBSourceFile> DIASession::findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto SourceFiles = findSourceFiles(Compiland, Pattern, Flags); if (!SourceFiles || SourceFiles->getChildCount() == 0) return nullptr; return SourceFiles->getNext(); } std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>> DIASession::findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto File = findOneSourceFile(nullptr, Pattern, Flags); if (!File) return nullptr; return File->getCompilands(); } std::unique_ptr<PDBSymbolCompiland> DIASession::findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto Compilands = findCompilandsForSourceFile(Pattern, Flags); if (!Compilands || Compilands->getChildCount() == 0) return nullptr; return Compilands->getNext(); } 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); }
수정본
파일 열기
//===- 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/DebugInfo/PDB/DIA/DIASession.h" #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/DIAError.h" #include "llvm/DebugInfo/PDB/DIA/DIARawSymbol.h" #include "llvm/DebugInfo/PDB/DIA/DIASourceFile.h" #include "llvm/DebugInfo/PDB/DIA/DIASupport.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/Support/ConvertUTF.h" using namespace llvm; using namespace llvm::pdb; namespace { Error ErrorFromHResult(HRESULT Result) { switch (Result) { case E_PDB_NOT_FOUND: return make_error<GenericError>(generic_error_code::invalid_path); case E_PDB_FORMAT: return make_error<DIAError>(dia_error_code::invalid_file_format); case E_INVALIDARG: return make_error<DIAError>(dia_error_code::invalid_parameter); case E_UNEXPECTED: return make_error<DIAError>(dia_error_code::already_loaded); case E_PDB_INVALID_SIG: case E_PDB_INVALID_AGE: return make_error<DIAError>(dia_error_code::debug_info_mismatch); default: return make_error<DIAError>(dia_error_code::unspecified); } } Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) { if (SUCCEEDED(CoCreateInstance(CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, IID_IDiaDataSource, reinterpret_cast<LPVOID *>(&DiaDataSource)))) return Error::success(); // If the CoCreateInstance call above failed, msdia*.dll is not registered. // Try loading the DLL corresponding to the #included DIA SDK. #if !defined(_MSC_VER) return llvm::make_error<GenericError>( "DIA is only supported when using MSVC."); #endif const wchar_t *msdia_dll = nullptr; #if _MSC_VER >= 1900 && _MSC_VER < 2000 msdia_dll = L"msdia140.dll"; // VS2015 #elif _MSC_VER == 1800 msdia_dll = L"msdia120.dll"; // VS2013 #else #error "Unknown Visual Studio version." #endif HRESULT HR; if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource, reinterpret_cast<LPVOID *>(&DiaDataSource)))) return ErrorFromHResult(HR); return Error::success(); } } DIASession::DIASession(CComPtr<IDiaSession> DiaSession) : Session(DiaSession) {} Error 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. if (auto E = LoadDIA(DiaDataSource)) return E; llvm::SmallVector<UTF16, 128> Path16; if (!llvm::convertUTF8ToUTF16String(Path, Path16)) return make_error<GenericError>(generic_error_code::invalid_path); const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data()); HRESULT HR; if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) return ErrorFromHResult(HR); if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) return ErrorFromHResult(HR); Session.reset(new DIASession(DiaSession)); return Error::success(); } Error 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. if (auto EC = LoadDIA(DiaDataSource)) return EC; llvm::SmallVector<UTF16, 128> Path16; if (!llvm::convertUTF8ToUTF16String(Path, Path16)) return make_error<GenericError>(generic_error_code::invalid_path, Path); const wchar_t *Path16Str = reinterpret_cast<const wchar_t *>(Path16.data()); HRESULT HR; if (FAILED(HR = DiaDataSource->loadDataForExe(Path16Str, nullptr, nullptr))) return ErrorFromHResult(HR); if (FAILED(HR = DiaDataSource->openSession(&DiaSession))) return ErrorFromHResult(HR); Session.reset(new DIASession(DiaSession)); return Error::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::findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const { const DIARawSymbol &RawCompiland = static_cast<const DIARawSymbol &>(Compiland.getRawSymbol()); const DIASourceFile &RawFile = static_cast<const DIASourceFile &>(File); CComPtr<IDiaEnumLineNumbers> LineNumbers; if (S_OK != Session->findLines(RawCompiland.getDiaSymbol(), RawFile.getDiaFile(), &LineNumbers)) return nullptr; return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers); } 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::findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { IDiaSymbol *DiaCompiland = nullptr; CComBSTR Utf16Pattern; if (!Pattern.empty()) Utf16Pattern = CComBSTR(Pattern.data()); if (Compiland) DiaCompiland = static_cast<const DIARawSymbol &>(Compiland->getRawSymbol()) .getDiaSymbol(); Flags = static_cast<PDB_NameSearchFlags>( Flags | PDB_NameSearchFlags::NS_FileNameExtMatch); CComPtr<IDiaEnumSourceFiles> SourceFiles; if (S_OK != Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles)) return nullptr; return llvm::make_unique<DIAEnumSourceFiles>(*this, SourceFiles); } std::unique_ptr<IPDBSourceFile> DIASession::findOneSourceFile(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto SourceFiles = findSourceFiles(Compiland, Pattern, Flags); if (!SourceFiles || SourceFiles->getChildCount() == 0) return nullptr; return SourceFiles->getNext(); } std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>> DIASession::findCompilandsForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto File = findOneSourceFile(nullptr, Pattern, Flags); if (!File) return nullptr; return File->getCompilands(); } std::unique_ptr<PDBSymbolCompiland> DIASession::findOneCompilandForSourceFile(llvm::StringRef Pattern, PDB_NameSearchFlags Flags) const { auto Compilands = findCompilandsForSourceFile(Pattern, Flags); if (!Compilands || Compilands->getChildCount() == 0) return nullptr; return Compilands->getNext(); } 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); }
비교하기