From e8a6c3eb9628e9833ae41196dc52a5c47041e3e6 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 11 Oct 2018 18:45:44 +0000 Subject: [PATCH] Revert SymbolFileNativePDB plugin. This was originally causing some test failures on non-Windows platforms, which required fixes in the compiler and linker. After those fixes, however, other tests started failing. Reverting temporarily until I can address everything. llvm-svn: 344279 --- lld/COFF/PDB.cpp | 31 +- lldb/include/lldb/Utility/LLDBAssert.h | 3 +- .../NativePDB/Inputs/breakpoints.lldbinit | 6 - .../NativePDB/Inputs/disassembly.lldbinit | 2 - .../NativePDB/Inputs/source-list.lldbinit | 3 - lldb/lit/SymbolFile/NativePDB/disassembly.cpp | 38 -- lldb/lit/SymbolFile/NativePDB/lit.local.cfg | 1 - .../NativePDB/simple-breakpoints.cpp | 63 -- lldb/lit/SymbolFile/NativePDB/source-list.cpp | 42 -- lldb/lit/lit.cfg | 5 +- lldb/source/Plugins/SymbolFile/CMakeLists.txt | 1 - .../SymbolFile/NativePDB/CMakeLists.txt | 16 - .../SymbolFile/NativePDB/CompileUnitIndex.cpp | 227 ------- .../SymbolFile/NativePDB/CompileUnitIndex.h | 99 --- .../Plugins/SymbolFile/NativePDB/PdbIndex.cpp | 203 ------ .../Plugins/SymbolFile/NativePDB/PdbIndex.h | 161 ----- .../Plugins/SymbolFile/NativePDB/PdbSymUid.h | 202 ------ .../Plugins/SymbolFile/NativePDB/PdbUtil.cpp | 258 -------- .../Plugins/SymbolFile/NativePDB/PdbUtil.h | 58 -- .../NativePDB/SymbolFileNativePDB.cpp | 620 ------------------ .../NativePDB/SymbolFileNativePDB.h | 181 ----- .../Plugins/SymbolFile/PDB/CMakeLists.txt | 1 - .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 26 +- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 5 +- 24 files changed, 25 insertions(+), 2227 deletions(-) delete mode 100644 lldb/lit/SymbolFile/NativePDB/Inputs/breakpoints.lldbinit delete mode 100644 lldb/lit/SymbolFile/NativePDB/Inputs/disassembly.lldbinit delete mode 100644 lldb/lit/SymbolFile/NativePDB/Inputs/source-list.lldbinit delete mode 100644 lldb/lit/SymbolFile/NativePDB/disassembly.cpp delete mode 100644 lldb/lit/SymbolFile/NativePDB/lit.local.cfg delete mode 100644 lldb/lit/SymbolFile/NativePDB/simple-breakpoints.cpp delete mode 100644 lldb/lit/SymbolFile/NativePDB/source-list.cpp delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp delete mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 34344dd3f1cb..6790ae687014 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -222,22 +222,26 @@ public: // PDB to work without additional configuration: // https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box static void pdbMakeAbsolute(SmallVectorImpl &FileName) { - // The default behavior is to produce paths that are valid within the context - // of the machine that you perform the link on. If the linker is running on - // a POSIX system, we will output absolute POSIX paths. If the linker is - // running on a Windows system, we will output absolute Windows paths. If the - // user desires any other kind of behavior, they should explicitly pass - // /pdbsourcepath and/or /pdbaltpath. - if (sys::path::is_absolute(FileName)) + if (sys::path::is_absolute(FileName, sys::path::Style::windows)) return; if (Config->PDBSourcePath.empty()) { + // Debuggers generally want that PDB files contain absolute, Windows-style + // paths. On POSIX hosts, this here will produce an absolute POSIX-style + // path, which is weird -- but it's not clear what else to do. + // People doing cross builds should probably just always pass + // /pbdsourcepath: and make sure paths to input obj files and to lld-link + // itself are relative. sys::fs::make_absolute(FileName); return; } + // Using /pdbsourcepath: with absolute POSIX paths will prepend + // PDBSourcePath to the absolute POSIX path. Since absolute POSIX paths + // don't make sense in PDB files anyways, this is gargabe-in-garbage-out. SmallString<128> AbsoluteFileName = Config->PDBSourcePath; - sys::path::append(AbsoluteFileName, FileName); - sys::path::native(AbsoluteFileName); - sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true); + sys::path::append(AbsoluteFileName, sys::path::Style::windows, FileName); + sys::path::native(AbsoluteFileName, sys::path::Style::windows); + sys::path::remove_dots(AbsoluteFileName, /*remove_dot_dots=*/true, + sys::path::Style::windows); FileName = std::move(AbsoluteFileName); } @@ -440,7 +444,8 @@ PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, TypeServer2Record &TS) { StringRef LocalPath = !File->ParentName.empty() ? File->ParentName : File->getName(); SmallString<128> Path = sys::path::parent_path(LocalPath); - sys::path::append(Path, sys::path::filename(TSPath)); + sys::path::append( + Path, sys::path::filename(TSPath, sys::path::Style::windows)); return tryToLoadPDB(TSId, Path); }, [&](std::unique_ptr EC) -> Error { @@ -1022,7 +1027,7 @@ void PDBLinker::addObjFile(ObjFile *File) { bool InArchive = !File->ParentName.empty(); SmallString<128> Path = InArchive ? File->ParentName : File->getName(); pdbMakeAbsolute(Path); - sys::path::native(Path); + sys::path::native(Path, sys::path::Style::windows); StringRef Name = InArchive ? File->getName() : StringRef(Path); pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); @@ -1307,7 +1312,7 @@ void PDBLinker::addSections(ArrayRef OutputSections, pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); NativePath = Config->PDBPath; pdbMakeAbsolute(NativePath); - sys::path::native(NativePath); + sys::path::native(NativePath, sys::path::Style::windows); uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath); auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); LinkerModule.setPdbFilePathNI(PdbFilePathNI); diff --git a/lldb/include/lldb/Utility/LLDBAssert.h b/lldb/include/lldb/Utility/LLDBAssert.h index e7448cdac545..9d9f3ceefab0 100644 --- a/lldb/include/lldb/Utility/LLDBAssert.h +++ b/lldb/include/lldb/Utility/LLDBAssert.h @@ -14,8 +14,7 @@ #define lldbassert(x) assert(x) #else #define lldbassert(x) \ - lldb_private::lldb_assert(static_cast(x), #x, __FUNCTION__, __FILE__, \ - __LINE__) + lldb_private::lldb_assert(x, #x, __FUNCTION__, __FILE__, __LINE__) #endif namespace lldb_private { diff --git a/lldb/lit/SymbolFile/NativePDB/Inputs/breakpoints.lldbinit b/lldb/lit/SymbolFile/NativePDB/Inputs/breakpoints.lldbinit deleted file mode 100644 index ff9bf21a8864..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/Inputs/breakpoints.lldbinit +++ /dev/null @@ -1,6 +0,0 @@ -break set -n main -break set -n OvlGlobalFn -break set -n StaticFn -break set -n DoesntExist -break list -quit diff --git a/lldb/lit/SymbolFile/NativePDB/Inputs/disassembly.lldbinit b/lldb/lit/SymbolFile/NativePDB/Inputs/disassembly.lldbinit deleted file mode 100644 index 2b552a0b01dd..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/Inputs/disassembly.lldbinit +++ /dev/null @@ -1,2 +0,0 @@ -disassemble --flavor=intel -m -n main -quit diff --git a/lldb/lit/SymbolFile/NativePDB/Inputs/source-list.lldbinit b/lldb/lit/SymbolFile/NativePDB/Inputs/source-list.lldbinit deleted file mode 100644 index 624ce5ba156b..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/Inputs/source-list.lldbinit +++ /dev/null @@ -1,3 +0,0 @@ -source list -n main -source list -n OvlGlobalFn -quit diff --git a/lldb/lit/SymbolFile/NativePDB/disassembly.cpp b/lldb/lit/SymbolFile/NativePDB/disassembly.cpp deleted file mode 100644 index 80cd0991704f..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/disassembly.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// clang-format off - -// Test that we can show disassembly and source. -// RUN: clang-cl /Z7 /GS- /GR- /c %s /Fo%t.obj -// RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb %t.obj -// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ -// RUN: %p/Inputs/disassembly.lldbinit | FileCheck %s - -// Some context lines before -// the function. - -int foo() { return 42; } - -int main(int argc, char **argv) { - foo(); - return 0; -} - - -// CHECK: (lldb) disassemble --flavor=intel -m -n main -// CHECK: 12 int foo() { return 42; } -// CHECK-NEXT: 13 -// CHECK-NEXT: ** 14 int main(int argc, char **argv) { -// CHECK: disassembly.cpp.tmp.exe`main: -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+0>: sub rsp, 0x38 -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+4>: mov dword ptr [rsp + 0x34], 0x0 -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+12>: mov qword ptr [rsp + 0x28], rdx -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+17>: mov dword ptr [rsp + 0x24], ecx -// CHECK: ** 15 foo(); -// CHECK: disassembly.cpp.tmp.exe[{{.*}}] <+21>: call {{.*}} ; foo at disassembly.cpp:12 -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+26>: xor ecx, ecx -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+28>: mov dword ptr [rsp + 0x20], eax -// CHECK: ** 16 return 0; -// CHECK-NEXT: 17 } -// CHECK-NEXT: 18 -// CHECK: disassembly.cpp.tmp.exe[{{.*}}] <+32>: mov eax, ecx -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+34>: add rsp, 0x38 -// CHECK-NEXT: disassembly.cpp.tmp.exe[{{.*}}] <+38>: ret diff --git a/lldb/lit/SymbolFile/NativePDB/lit.local.cfg b/lldb/lit/SymbolFile/NativePDB/lit.local.cfg deleted file mode 100644 index fe74441d5817..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/lit.local.cfg +++ /dev/null @@ -1 +0,0 @@ -config.suffixes = ['.test', '.cpp'] diff --git a/lldb/lit/SymbolFile/NativePDB/simple-breakpoints.cpp b/lldb/lit/SymbolFile/NativePDB/simple-breakpoints.cpp deleted file mode 100644 index 8fe2ea4b9a88..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/simple-breakpoints.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// clang-format off - -// Test that we can set simple breakpoints using PDB on any platform. -// RUN: clang-cl /Z7 /GS- /GR- /c %s /Fo%t.obj -// RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb %t.obj -// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ -// RUN: %p/Inputs/breakpoints.lldbinit | FileCheck %s - -// Use different indentation style for each overload so that the starting -// line is in a different place. -int OvlGlobalFn(int X) { - return X + 42; -} - -int OvlGlobalFn(int X, int Y) { return X + Y + 42; } - -int OvlGlobalFn(int X, int Y, int Z) -{ - return X + Y + Z + 42; -} - -static int StaticFn(int X) { - return X + 42; -} - -int main(int argc, char **argv) { - // Make sure they don't get optimized out. - // Note the comments here, we want to make sure the line number reported - // for the breakpoint is the first actual line of code. - int Result = OvlGlobalFn(argc) + OvlGlobalFn(argc, argc) - + OvlGlobalFn(argc, argc, argc) + StaticFn(argc); - return Result; -} - - -// CHECK: (lldb) target create "{{.*}}simple-breakpoints.cpp.tmp.exe" -// CHECK: Current executable set to '{{.*}}simple-breakpoints.cpp.tmp.exe' (x86_64). -// CHECK: (lldb) break set -n main -// CHECK: Breakpoint 1: where = simple-breakpoints.cpp.tmp.exe`main + 21 -// CHECK-SAME: at simple-breakpoints.cpp:30 -// CHECK: (lldb) break set -n OvlGlobalFn -// CHECK: Breakpoint 2: 3 locations. -// CHECK: (lldb) break set -n StaticFn -// CHECK: Breakpoint 3: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 -// CHECK-SAME: at simple-breakpoints.cpp:23 -// CHECK: (lldb) break set -n DoesntExist -// CHECK: Breakpoint 4: no locations (pending). -// CHECK: (lldb) break list -// CHECK: Current breakpoints: -// CHECK: 1: name = 'main', locations = 1 -// CHECK: 1.1: where = simple-breakpoints.cpp.tmp.exe`main + 21 -// CHECK-SAME: at simple-breakpoints.cpp:30 -// CHECK: 2: name = 'OvlGlobalFn', locations = 3 -// CHECK: 2.1: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 5 -// CHECK-SAME: at simple-breakpoints.cpp:12 -// CHECK: 2.2: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn -// CHECK-SAME: at simple-breakpoints.cpp:15 -// CHECK: 2.3: where = simple-breakpoints.cpp.tmp.exe`OvlGlobalFn + 17 -// CHECK-SAME: at simple-breakpoints.cpp:19 -// CHECK: 3: name = 'StaticFn', locations = 1 -// CHECK: 3.1: where = simple-breakpoints.cpp.tmp.exe`StaticFn + 5 -// CHECK-SAME: at simple-breakpoints.cpp:23 -// CHECK: 4: name = 'DoesntExist', locations = 0 (pending) diff --git a/lldb/lit/SymbolFile/NativePDB/source-list.cpp b/lldb/lit/SymbolFile/NativePDB/source-list.cpp deleted file mode 100644 index abd90cde9dde..000000000000 --- a/lldb/lit/SymbolFile/NativePDB/source-list.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// clang-format off - -// Test that we can set display source of functions. -// RUN: clang-cl /Z7 /GS- /GR- /c %s /Fo%t.obj -// RUN: lld-link /DEBUG /nodefaultlib /entry:main /OUT:%t.exe /PDB:%t.pdb %t.obj -// RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb -f %t.exe -s \ -// RUN: %p/Inputs/source-list.lldbinit | FileCheck %s - - - -// Some context lines before -// the function. - - -int main(int argc, char **argv) { - // Here are some comments. - // That we should print when listing source. - return 0; -} - -// Some context lines after -// the function. - -// check lines go at the end so that line numbers stay stable when -// changing this file. - -// CHECK: (lldb) source list -n main -// CHECK: File: {{.*}}source-list.cpp -// CHECK: 10 -// CHECK: 11 // Some context lines before -// CHECK: 12 // the function. -// CHECK: 13 -// CHECK: 14 -// CHECK: 15 int main(int argc, char **argv) { -// CHECK: 16 // Here are some comments. -// CHECK: 17 // That we should print when listing source. -// CHECK: 18 return 0; -// CHECK: 19 } -// CHECK: 20 -// CHECK: 21 // Some context lines after -// CHECK: 22 // the function. -// CHECK: 23 diff --git a/lldb/lit/lit.cfg b/lldb/lit/lit.cfg index 38c819e45b27..b25231d7f666 100644 --- a/lldb/lit/lit.cfg +++ b/lldb/lit/lit.cfg @@ -64,8 +64,6 @@ lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir), config.test_source_root) lldbmi = lit.util.which('lldb-mi', lldb_tools_dir) -if lldbmi: - config.available_features.add('lldb-mi') if not os.path.exists(config.cc): config.cc = lit.util.which(config.cc, config.environment['PATH']) @@ -92,8 +90,7 @@ if platform.system() in ['OpenBSD']: config.substitutions.append(('%cc', config.cc)) config.substitutions.append(('%cxx', config.cxx)) -if lldbmi: - config.substitutions.append(('%lldbmi', lldbmi + " --synchronous")) +config.substitutions.append(('%lldbmi', lldbmi + " --synchronous")) config.substitutions.append(('%lldb', lldb)) if debugserver is not None: diff --git a/lldb/source/Plugins/SymbolFile/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/CMakeLists.txt index 3ee2827d85e3..98510704ce73 100644 --- a/lldb/source/Plugins/SymbolFile/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/CMakeLists.txt @@ -1,4 +1,3 @@ add_subdirectory(DWARF) add_subdirectory(Symtab) -add_subdirectory(NativePDB) add_subdirectory(PDB) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt deleted file mode 100644 index 4c7307a80faf..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN - CompileUnitIndex.cpp - PdbIndex.cpp - PdbUtil.cpp - SymbolFileNativePDB.cpp - - LINK_LIBS - clangAST - clangLex - lldbCore - lldbSymbol - lldbUtility - LINK_COMPONENTS - DebugInfoPDB - Support - ) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp deleted file mode 100644 index b4725e591a45..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ /dev/null @@ -1,227 +0,0 @@ -//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CompileUnitIndex.h" - -#include "PdbIndex.h" -#include "PdbUtil.h" - -#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" -#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" -#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" -#include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" -#include "llvm/DebugInfo/PDB/Native/DbiStream.h" -#include "llvm/DebugInfo/PDB/Native/InfoStream.h" -#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" -#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" -#include "llvm/DebugInfo/PDB/Native/TpiStream.h" -#include "llvm/Support/Path.h" - -#include "lldb/Utility/LLDBAssert.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::npdb; -using namespace llvm::codeview; -using namespace llvm::pdb; - -static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) { - if (main == other) - return true; - - // If the files refer to the local file system, we can just ask the file - // system if they're equivalent. But if the source isn't present on disk - // then we still want to try. - if (llvm::sys::fs::equivalent(main, other)) - return true; - - llvm::SmallString<64> normalized(other); - llvm::sys::path::native(normalized); - return main.equals_lower(normalized); -} - -static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) { - cci.m_compile_opts.emplace(); - llvm::cantFail( - SymbolDeserializer::deserializeAs(sym, *cci.m_compile_opts)); -} - -static void ParseObjname(const CVSymbol &sym, CompilandIndexItem &cci) { - cci.m_obj_name.emplace(); - llvm::cantFail( - SymbolDeserializer::deserializeAs(sym, *cci.m_obj_name)); -} - -static void ParseBuildInfo(PdbIndex &index, const CVSymbol &sym, - CompilandIndexItem &cci) { - BuildInfoSym bis(SymbolRecordKind::BuildInfoSym); - llvm::cantFail(SymbolDeserializer::deserializeAs(sym, bis)); - - // S_BUILDINFO just points to an LF_BUILDINFO in the IPI stream. Let's do - // a little extra work to pull out the LF_BUILDINFO. - LazyRandomTypeCollection &types = index.ipi().typeCollection(); - llvm::Optional cvt = types.tryGetType(bis.BuildId); - - if (!cvt || cvt->kind() != LF_BUILDINFO) - return; - - BuildInfoRecord bir; - llvm::cantFail(TypeDeserializer::deserializeAs(*cvt, bir)); - cci.m_build_info.assign(bir.ArgIndices.begin(), bir.ArgIndices.end()); -} - -static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) { - const CVSymbolArray &syms = item.m_debug_stream.getSymbolArray(); - - // This is a private function, it shouldn't be called if the information - // has already been parsed. - lldbassert(!item.m_obj_name); - lldbassert(!item.m_compile_opts); - lldbassert(item.m_build_info.empty()); - - // We're looking for 3 things. S_COMPILE3, S_OBJNAME, and S_BUILDINFO. - int found = 0; - for (const CVSymbol &sym : syms) { - switch (sym.kind()) { - case S_COMPILE3: - ParseCompile3(sym, item); - break; - case S_OBJNAME: - ParseObjname(sym, item); - break; - case S_BUILDINFO: - ParseBuildInfo(index, sym, item); - break; - default: - continue; - } - if (++found >= 3) - break; - } -} - -CompilandIndexItem::CompilandIndexItem( - PdbSymUid uid, llvm::pdb::ModuleDebugStreamRef debug_stream, - llvm::pdb::DbiModuleDescriptor descriptor) - : m_uid(uid), m_debug_stream(std::move(debug_stream)), - m_module_descriptor(std::move(descriptor)) {} - -CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { - PdbSymUid uid = PdbSymUid::makeCompilandId(modi); - return GetOrCreateCompiland(uid); -} - -CompilandIndexItem & -CompileUnitIndex::GetOrCreateCompiland(PdbSymUid compiland_uid) { - auto result = m_comp_units.try_emplace(compiland_uid.toOpaqueId(), nullptr); - if (!result.second) - return *result.first->second; - - // Find the module list and load its debug information stream and cache it - // since we need to use it for almost all interesting operations. - const DbiModuleList &modules = m_index.dbi().modules(); - uint16_t modi = compiland_uid.asCompiland().modi; - llvm::pdb::DbiModuleDescriptor descriptor = modules.getModuleDescriptor(modi); - uint16_t stream = descriptor.getModuleStreamIndex(); - std::unique_ptr stream_data = - m_index.pdb().createIndexedStream(stream); - llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, - std::move(stream_data)); - cantFail(debug_stream.reload()); - - std::unique_ptr &cci = result.first->second; - - cci = llvm::make_unique( - compiland_uid, std::move(debug_stream), std::move(descriptor)); - ParseExtendedInfo(m_index, *cci); - - cci->m_strings.initialize(debug_stream.getSubsectionsArray()); - PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); - cci->m_strings.setStrings(strings.getStringTable()); - - // We want the main source file to always comes first. Note that we can't - // just push_back the main file onto the front because `GetMainSourceFile` - // computes it in such a way that it doesn't own the resulting memory. So we - // have to iterate the module file list comparing each one to the main file - // name until we find it, and we can cache that one since the memory is backed - // by a contiguous chunk inside the mapped PDB. - llvm::SmallString<64> main_file = GetMainSourceFile(*cci); - std::string s = main_file.str(); - llvm::sys::path::native(main_file); - - uint32_t file_count = modules.getSourceFileCount(modi); - cci->m_file_list.reserve(file_count); - bool found_main_file = false; - for (llvm::StringRef file : modules.source_files(modi)) { - if (!found_main_file && IsMainFile(main_file, file)) { - cci->m_file_list.insert(cci->m_file_list.begin(), file); - found_main_file = true; - continue; - } - cci->m_file_list.push_back(file); - } - - return *cci; -} - -const CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) const { - return GetCompiland(PdbSymUid::makeCompilandId(modi)); -} - -const CompilandIndexItem * -CompileUnitIndex::GetCompiland(PdbSymUid compiland_uid) const { - auto iter = m_comp_units.find(compiland_uid.toOpaqueId()); - if (iter == m_comp_units.end()) - return nullptr; - return iter->second.get(); -} - -CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) { - return GetCompiland(PdbSymUid::makeCompilandId(modi)); -} - -CompilandIndexItem *CompileUnitIndex::GetCompiland(PdbSymUid compiland_uid) { - auto iter = m_comp_units.find(compiland_uid.toOpaqueId()); - if (iter == m_comp_units.end()) - return nullptr; - return iter->second.get(); -} - -llvm::SmallString<64> -CompileUnitIndex::GetMainSourceFile(const CompilandIndexItem &item) const { - // LF_BUILDINFO contains a list of arg indices which point to LF_STRING_ID - // records in the IPI stream. The order of the arg indices is as follows: - // [0] - working directory where compiler was invoked. - // [1] - absolute path to compiler binary - // [2] - source file name - // [3] - path to compiler generated PDB (the /Zi PDB, although this entry gets - // added even when using /Z7) - // [4] - full command line invocation. - // - // We need to form the path [0]\[2] to generate the full path to the main - // file.source - if (item.m_build_info.size() < 3) - return {""}; - - LazyRandomTypeCollection &types = m_index.ipi().typeCollection(); - - StringIdRecord working_dir; - StringIdRecord file_name; - CVType dir_cvt = types.getType(item.m_build_info[0]); - CVType file_cvt = types.getType(item.m_build_info[2]); - llvm::cantFail( - TypeDeserializer::deserializeAs(dir_cvt, working_dir)); - llvm::cantFail( - TypeDeserializer::deserializeAs(file_cvt, file_name)); - - llvm::SmallString<64> absolute_path = working_dir.String; - llvm::sys::path::append(absolute_path, file_name.String); - return absolute_path; -} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h deleted file mode 100644 index 54c40a0f8bfc..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ /dev/null @@ -1,99 +0,0 @@ -//===-- CompileUnitIndex.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/IntervalMap.h" -#include "llvm/ADT/Optional.h" -#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" -#include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" -#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" - -#include "PdbSymUid.h" - -#include -#include - -namespace lldb_private { - -namespace npdb { -class PdbIndex; - -/// Represents a single compile unit. This class is useful for collecting the -/// important accessors and information about a compile unit from disparate -/// parts of the PDB into a single place, simplifying acess to compile unit -/// information for the callers. -struct CompilandIndexItem { - CompilandIndexItem(PdbSymUid uid, - llvm::pdb::ModuleDebugStreamRef debug_stream, - llvm::pdb::DbiModuleDescriptor descriptor); - - // uid of this compile unit. - PdbSymUid m_uid; - - // debug stream. - llvm::pdb::ModuleDebugStreamRef m_debug_stream; - - // dbi module descriptor. - llvm::pdb::DbiModuleDescriptor m_module_descriptor; - - llvm::codeview::StringsAndChecksumsRef m_strings; - - // List of files which contribute to this compiland. - std::vector m_file_list; - - // Maps virtual address to global symbol id, which can then be used to - // locate the exact compile unit and offset of the symbol. Note that this - // is intentionally an ordered map so that we can find all symbols up to a - // given starting address. - std::map m_symbols_by_va; - - // S_COMPILE3 sym describing compilation settings for the module. - llvm::Optional m_compile_opts; - - // S_OBJNAME sym describing object name. - llvm::Optional m_obj_name; - - // LF_BUILDINFO sym describing source file name, working directory, - // command line, etc. This usually contains exactly 5 items which - // are references to other strings. - llvm::SmallVector m_build_info; -}; - -/// Indexes information about all compile units. This is really just a map of -/// global compile unit index to |CompilandIndexItem| structures. -class CompileUnitIndex { - PdbIndex &m_index; - llvm::DenseMap> - m_comp_units; - -public: - explicit CompileUnitIndex(PdbIndex &index) : m_index(index) {} - - CompilandIndexItem &GetOrCreateCompiland(uint16_t modi); - CompilandIndexItem &GetOrCreateCompiland(PdbSymUid compiland_uid); - - const CompilandIndexItem *GetCompiland(uint16_t modi) const; - const CompilandIndexItem *GetCompiland(PdbSymUid compiland_uid) const; - - CompilandIndexItem *GetCompiland(uint16_t modi); - CompilandIndexItem *GetCompiland(PdbSymUid compiland_uid); - - llvm::SmallString<64> GetMainSourceFile(const CompilandIndexItem &item) const; -}; -} // namespace npdb -} // namespace lldb_private - -#endif diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp deleted file mode 100644 index c9bd9a485689..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ /dev/null @@ -1,203 +0,0 @@ -//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PdbIndex.h" -#include "PdbUtil.h" - -#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" -#include "llvm/DebugInfo/PDB/Native/DbiStream.h" -#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" -#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/PublicsStream.h" -#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/Error.h" - -#include "lldb/Utility/LLDBAssert.h" -#include "lldb/lldb-defines.h" - -using namespace lldb_private; -using namespace lldb_private::npdb; -using namespace llvm::codeview; -using namespace llvm::pdb; - -PdbIndex::PdbIndex() : m_cus(*this), m_va_to_modi(m_allocator) {} - -#define ASSIGN_PTR_OR_RETURN(result_ptr, expr) \ - { \ - auto expected_result = expr; \ - if (!expected_result) \ - return expected_result.takeError(); \ - result_ptr = &expected_result.get(); \ - } - -llvm::Expected> -PdbIndex::create(std::unique_ptr file) { - lldbassert(file); - - std::unique_ptr result(new PdbIndex()); - ASSIGN_PTR_OR_RETURN(result->m_dbi, file->getPDBDbiStream()); - ASSIGN_PTR_OR_RETURN(result->m_tpi, file->getPDBTpiStream()); - ASSIGN_PTR_OR_RETURN(result->m_ipi, file->getPDBIpiStream()); - ASSIGN_PTR_OR_RETURN(result->m_info, file->getPDBInfoStream()); - ASSIGN_PTR_OR_RETURN(result->m_publics, file->getPDBPublicsStream()); - ASSIGN_PTR_OR_RETURN(result->m_globals, file->getPDBGlobalsStream()); - ASSIGN_PTR_OR_RETURN(result->m_symrecords, file->getPDBSymbolStream()); - - result->m_file = std::move(file); - - return std::move(result); -} - -lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, - uint32_t offset) const { - // Segment indices are 1-based. - lldbassert(segment > 0); - - uint32_t max_section = dbi().getSectionHeaders().size(); - lldbassert(segment <= max_section + 1); - - // If this is an absolute symbol, it's indicated by the magic section index - // |max_section+1|. In this case, the offset is meaningless, so just return. - if (segment == max_section + 1) - return LLDB_INVALID_ADDRESS; - - const llvm::object::coff_section &cs = dbi().getSectionHeaders()[segment - 1]; - return m_load_address + static_cast(cs.VirtualAddress) + - static_cast(offset); -} - -lldb::addr_t PdbIndex::MakeVirtualAddress(const SegmentOffset &so) const { - return MakeVirtualAddress(so.segment, so.offset); -} - -llvm::Optional -PdbIndex::GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const { - return GetModuleIndexForVa(MakeVirtualAddress(segment, offset)); -} - -llvm::Optional PdbIndex::GetModuleIndexForVa(lldb::addr_t va) const { - auto iter = m_va_to_modi.find(va); - if (iter == m_va_to_modi.end()) - return llvm::None; - - return iter.value(); -} - -void PdbIndex::ParseSectionContribs() { - class Visitor : public ISectionContribVisitor { - PdbIndex &m_ctx; - llvm::IntervalMap &m_imap; - - public: - Visitor(PdbIndex &ctx, llvm::IntervalMap &imap) - : m_ctx(ctx), m_imap(imap) {} - - void visit(const SectionContrib &C) override { - uint64_t va = m_ctx.MakeVirtualAddress(C.ISect, C.Off); - uint64_t end = va + C.Size; - // IntervalMap's start and end represent a closed range, not a half-open - // range, so we have to subtract 1. - m_imap.insert(va, end - 1, C.Imod); - } - void visit(const SectionContrib2 &C) override { visit(C.Base); } - }; - Visitor v(*this, m_va_to_modi); - dbi().visitSectionContributions(v); -} - -void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { - lldbassert(cci.m_symbols_by_va.empty() && - "Addr to symbol map is already built!"); - uint16_t modi = cci.m_uid.asCompiland().modi; - const CVSymbolArray &syms = cci.m_debug_stream.getSymbolArray(); - for (auto iter = syms.begin(); iter != syms.end(); ++iter) { - if (!SymbolHasAddress(*iter)) - continue; - - SegmentOffset so = GetSegmentAndOffset(*iter); - lldb::addr_t va = MakeVirtualAddress(so); - - // We need to add 4 here to adjust for the codeview debug magic - // at the beginning of the debug info stream. - uint32_t sym_offset = iter.offset() + 4; - PdbSymUid cu_sym_uid = - PdbSymUid::makeCuSymId(CVSymToPDBSym(iter->kind()), modi, sym_offset); - - // If the debug info is incorrect, we could have multiple symbols with the - // same address. So use try_emplace instead of insert, and the first one - // will win. - auto insert_result = - cci.m_symbols_by_va.insert(std::make_pair(va, cu_sym_uid)); - (void)insert_result; - - // The odds of an error in some function such as GetSegmentAndOffset or - // MakeVirtualAddress are much higher than the odds of encountering bad - // debug info, so assert that this item was inserted in the map as opposed - // to having already been there. - lldbassert(insert_result.second); - } -} - -std::vector PdbIndex::FindSymbolsByVa(lldb::addr_t va) { - std::vector result; - - llvm::Optional modi = GetModuleIndexForVa(va); - if (!modi) - return result; - - CompilandIndexItem &cci = compilands().GetOrCreateCompiland(*modi); - if (cci.m_symbols_by_va.empty()) - BuildAddrToSymbolMap(cci); - - // The map is sorted by starting address of the symbol. So for example - // we could (in theory) have this situation - // - // [------------------] - // [----------] - // [-----------] - // [-------------] - // [----] - // [-----] - // ^ Address we're searching for - // In order to find this, we use the upper_bound of the key value which would - // be the first symbol whose starting address is higher than the element we're - // searching for. - - auto ub = cci.m_symbols_by_va.upper_bound(va); - - for (auto iter = cci.m_symbols_by_va.begin(); iter != ub; ++iter) { - const PdbCuSymId &cu_sym_id = iter->second.asCuSym(); - CVSymbol sym = ReadSymbolRecord(cu_sym_id); - - SegmentOffsetLength sol; - if (SymbolIsCode(sym)) - sol = GetSegmentOffsetAndLength(sym); - else - sol.so = GetSegmentAndOffset(sym); - - lldb::addr_t start = MakeVirtualAddress(sol.so); - lldb::addr_t end = start + sol.length; - if (va >= start && va < end) - result.push_back({std::move(sym), iter->second}); - } - - return result; -} - -CVSymbol PdbIndex::ReadSymbolRecord(PdbCuSymId cu_sym) const { - // We need to subtract 4 here to adjust for the codeview debug magic - // at the beginning of the debug info stream. - PdbSymUid cuid = PdbSymUid::makeCompilandId(cu_sym.modi); - const CompilandIndexItem *cci = compilands().GetCompiland(cuid); - auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset - 4); - lldbassert(iter != cci->m_debug_stream.getSymbolArray().end()); - return *iter; -} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h deleted file mode 100644 index ee03f305acbf..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ /dev/null @@ -1,161 +0,0 @@ -//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H - -#include "lldb/lldb-types.h" -#include "llvm/ADT/IntervalMap.h" -#include "llvm/ADT/Optional.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" - -#include "CompileUnitIndex.h" -#include "PdbSymUid.h" - -#include -#include - -namespace llvm { -namespace pdb { -class DbiStream; -class TpiStream; -class TpiStream; -class InfoStream; -class PublicsStream; -class GlobalsStream; -class SymbolStream; -} // namespace pdb -} // namespace llvm - -namespace lldb_private { -namespace npdb { -struct SegmentOffset; - -/// PdbIndex - Lazy access to the important parts of a PDB file. -/// -/// This is a layer on top of LLVM's native PDB support libraries which cache -/// certain data when it is accessed the first time. The entire PDB file is -/// mapped into memory, and the underlying support libraries vend out memory -/// that is always backed by the file, so it is safe to hold StringRefs and -/// ArrayRefs into the backing memory as long as the PdbIndex instance is -/// alive. -class PdbIndex { - - /// The underlying PDB file. - std::unique_ptr m_file; - - /// The DBI stream. This contains general high level information about the - /// features present in the PDB file, compile units (such as the information - /// necessary to locate full symbol information for each compile unit), - /// section contributions, and other data which is not specifically symbol or - /// type records. - llvm::pdb::DbiStream *m_dbi = nullptr; - - /// TPI (types) and IPI (indices) streams. These are both in the exact same - /// format with different data. Most type records are stored in the TPI - /// stream but certain specific types of records are stored in the IPI stream. - /// The IPI stream records can refer to the records in the TPI stream, but not - /// the other way around. - llvm::pdb::TpiStream *m_tpi = nullptr; - llvm::pdb::TpiStream *m_ipi = nullptr; - - /// This is called the "PDB Stream" in the Microsoft reference implementation. - /// It contains information about the structure of the file, as well as fields - /// used to match EXE and PDB. - llvm::pdb::InfoStream *m_info = nullptr; - - /// Publics stream. Is actually a serialized hash table where the keys are - /// addresses of symbols in the executable, and values are a record containing - /// mangled names and an index which can be used to locate more detailed info - /// about the symbol in the Symbol Records stream. The publics stream only - /// contains info about externally visible symbols. - llvm::pdb::PublicsStream *m_publics = nullptr; - - /// Globals stream. Contrary to its name, this does not contain information - /// about all "global variables" or "global functions". Rather, it is the - /// "global symbol table", i.e. it contains information about *every* symbol - /// in the executable. It is a hash table keyed on name, whose values are - /// indices into the symbol records stream to find the full record. - llvm::pdb::GlobalsStream *m_globals = nullptr; - - /// Symbol records stream. The publics and globals stream refer to records - /// in this stream. For some records, like constants and typedefs, the - /// complete record lives in this stream. For other symbol types, such as - /// functions, data, and other things that have been materialied into a - /// specific compile unit, the records here simply provide a reference - /// necessary to locate the full information. - llvm::pdb::SymbolStream *m_symrecords = nullptr; - - /// Index of all compile units, mapping identifier to |CompilandIndexItem| - /// instance. - CompileUnitIndex m_cus; - - /// An allocator for the interval maps - llvm::IntervalMap::Allocator m_allocator; - - /// Maps virtual address to module index - llvm::IntervalMap m_va_to_modi; - - /// The address at which the program has been loaded into memory. - lldb::addr_t m_load_address = 0; - - PdbIndex(); - - void BuildAddrToSymbolMap(CompilandIndexItem &cci); - -public: - static llvm::Expected> - create(std::unique_ptr); - - void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } - void ParseSectionContribs(); - - llvm::pdb::PDBFile &pdb() { return *m_file; } - const llvm::pdb::PDBFile &pdb() const { return *m_file; } - - llvm::pdb::DbiStream &dbi() { return *m_dbi; } - const llvm::pdb::DbiStream &dbi() const { return *m_dbi; } - - llvm::pdb::TpiStream &tpi() { return *m_tpi; } - const llvm::pdb::TpiStream &tpi() const { return *m_tpi; } - - llvm::pdb::TpiStream &ipi() { return *m_ipi; } - const llvm::pdb::TpiStream &ipi() const { return *m_ipi; } - - llvm::pdb::InfoStream &info() { return *m_info; } - const llvm::pdb::InfoStream &info() const { return *m_info; } - - llvm::pdb::PublicsStream &publics() { return *m_publics; } - const llvm::pdb::PublicsStream &publics() const { return *m_publics; } - - llvm::pdb::GlobalsStream &globals() { return *m_globals; } - const llvm::pdb::GlobalsStream &globals() const { return *m_globals; } - - llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; } - const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; } - - CompileUnitIndex &compilands() { return m_cus; } - const CompileUnitIndex &compilands() const { return m_cus; } - - lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; - lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; - - std::vector FindSymbolsByVa(lldb::addr_t va); - - llvm::codeview::CVSymbol ReadSymbolRecord(PdbCuSymId cu_sym) const; - - llvm::Optional GetModuleIndexForAddr(uint16_t segment, - uint32_t offset) const; - llvm::Optional GetModuleIndexForVa(lldb::addr_t va) const; -}; -} // namespace npdb -} // namespace lldb_private - -#endif diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h deleted file mode 100644 index ffa1c2627e6b..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h +++ /dev/null @@ -1,202 +0,0 @@ -//===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// A unique identification scheme for Pdb records. -// The scheme is to partition a 64-bit integer into an 8-bit tag field, which -// will contain some value from the PDB_SymType enumeration. The format of the -// other 48-bits depend on the tag, but must be sufficient to locate the -// corresponding entry in the underlying PDB file quickly. For example, for -// a compile unit, we use 2 bytes to represent the index, which allows fast -// access to the compile unit's information. -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H - -#include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/Support/Compiler.h" - -#include "lldb/Utility/LLDBAssert.h" -#include "lldb/lldb-types.h" - -namespace lldb_private { -namespace npdb { - -// **important** - All concrete id types must have the 1-byte tag field at -// the beginning so that the types are all layout-compatible with each -// other, which is necessary in order to be able to safely access the tag -// member through any union member. - -struct PdbCompilandId { - uint64_t tag : 8; // PDB_SymType::Compiland - uint64_t modi : 16; // 0-based index of module in PDB - uint64_t unused : 32; -}; -struct PdbCuSymId { - uint64_t tag : 8; // PDB_SymType::Data, Function, Block, etc. - uint64_t - offset : 32; // Offset of symbol's record in module stream. This is - // offset by 4 from the CVSymbolArray's notion of offset - // due to the debug magic at the beginning of the stream. - uint64_t modi : 16; // 0-based index of module in PDB -}; -struct PdbTypeSymId { - uint64_t tag : 8; // PDB_SymType::FunctionSig, Enum, PointerType, etc. - uint64_t is_ipi : 8; // 1 if this value is from the IPI stream, 0 for TPI. - uint64_t unused : 16; - uint64_t index : 32; // codeview::TypeIndex -}; - -static_assert(sizeof(PdbCompilandId) == 8, "invalid uid size"); -static_assert(sizeof(PdbCuSymId) == 8, "invalid uid size"); -static_assert(std::is_standard_layout::value, - "type is not standard layout!"); -static_assert(std::is_standard_layout::value, - "type is not standard layout!"); - -class PdbSymUid { - union { - PdbCompilandId comp_id; - PdbCuSymId cu_sym; - PdbTypeSymId type_sym; - } m_uid; - - PdbSymUid() { ::memset(&m_uid, 0, sizeof(m_uid)); } - -public: - static bool isTypeSym(llvm::pdb::PDB_SymType tag) { - switch (tag) { - case llvm::pdb::PDB_SymType::ArrayType: - case llvm::pdb::PDB_SymType::BaseClass: - case llvm::pdb::PDB_SymType::BaseInterface: - case llvm::pdb::PDB_SymType::BuiltinType: - case llvm::pdb::PDB_SymType::CustomType: - case llvm::pdb::PDB_SymType::Enum: - case llvm::pdb::PDB_SymType::FunctionArg: - case llvm::pdb::PDB_SymType::FunctionSig: - case llvm::pdb::PDB_SymType::Typedef: - case llvm::pdb::PDB_SymType::VectorType: - case llvm::pdb::PDB_SymType::VTableShape: - case llvm::pdb::PDB_SymType::PointerType: - case llvm::pdb::PDB_SymType::UDT: - return true; - default: - return false; - } - } - - static bool isCuSym(llvm::pdb::PDB_SymType tag) { - switch (tag) { - case llvm::pdb::PDB_SymType::Block: - case llvm::pdb::PDB_SymType::Callee: - case llvm::pdb::PDB_SymType::Caller: - case llvm::pdb::PDB_SymType::CallSite: - case llvm::pdb::PDB_SymType::CoffGroup: - case llvm::pdb::PDB_SymType::CompilandDetails: - case llvm::pdb::PDB_SymType::CompilandEnv: - case llvm::pdb::PDB_SymType::Custom: - case llvm::pdb::PDB_SymType::Data: - case llvm::pdb::PDB_SymType::Function: - case llvm::pdb::PDB_SymType::Inlinee: - case llvm::pdb::PDB_SymType::InlineSite: - case llvm::pdb::PDB_SymType::Label: - case llvm::pdb::PDB_SymType::Thunk: - return true; - default: - return false; - } - } - - static PdbSymUid makeCuSymId(llvm::codeview::ProcRefSym sym) { - return makeCuSymId(llvm::pdb::PDB_SymType::Function, sym.Module - 1, - sym.SymOffset); - } - - static PdbSymUid makeCuSymId(llvm::pdb::PDB_SymType type, uint16_t modi, - uint32_t offset) { - lldbassert(isCuSym(type)); - - PdbSymUid uid; - uid.m_uid.cu_sym.modi = modi; - uid.m_uid.cu_sym.offset = offset; - uid.m_uid.cu_sym.tag = static_cast(type); - return uid; - } - - static PdbSymUid makeCompilandId(llvm::codeview::ProcRefSym sym) { - // S_PROCREF symbols are 1-based - lldbassert(sym.Module > 0); - return makeCompilandId(sym.Module - 1); - } - - static PdbSymUid makeCompilandId(uint16_t modi) { - PdbSymUid uid; - uid.m_uid.comp_id.modi = modi; - uid.m_uid.cu_sym.tag = - static_cast(llvm::pdb::PDB_SymType::Compiland); - return uid; - } - - static PdbSymUid makeTypeSymId(llvm::pdb::PDB_SymType type, - llvm::codeview::TypeIndex index, bool is_ipi) { - lldbassert(isTypeSym(type)); - - PdbSymUid uid; - uid.m_uid.type_sym.tag = static_cast(type); - uid.m_uid.type_sym.index = index.getIndex(); - uid.m_uid.type_sym.is_ipi = static_cast(is_ipi); - return uid; - } - - static PdbSymUid fromOpaqueId(uint64_t value) { - PdbSymUid result; - ::memcpy(&result.m_uid, &value, sizeof(value)); - return result; - } - - uint64_t toOpaqueId() const { - uint64_t result; - ::memcpy(&result, &m_uid, sizeof(m_uid)); - return result; - } - - bool isPubSym() const { - return tag() == llvm::pdb::PDB_SymType::PublicSymbol; - } - bool isCompiland() const { - return tag() == llvm::pdb::PDB_SymType::Compiland; - } - - llvm::pdb::PDB_SymType tag() const { - return static_cast(m_uid.comp_id.tag); - } - - const PdbCompilandId &asCompiland() const { - lldbassert(tag() == llvm::pdb::PDB_SymType::Compiland); - return m_uid.comp_id; - } - - const PdbCuSymId &asCuSym() const { - lldbassert(isCuSym(tag())); - return m_uid.cu_sym; - } - - const PdbTypeSymId &asTypeSym() const { - lldbassert(isTypeSym(tag())); - return m_uid.type_sym; - } -}; - -struct SymbolAndUid { - llvm::codeview::CVSymbol sym; - PdbSymUid uid; -}; -} // namespace npdb -} // namespace lldb_private - -#endif diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp deleted file mode 100644 index 55de9662592e..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PdbUtil.h" - -#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" - -#include "lldb/Utility/LLDBAssert.h" - -using namespace lldb_private; -using namespace lldb_private::npdb; -using namespace llvm::codeview; -using namespace llvm::pdb; - -llvm::pdb::PDB_SymType -lldb_private::npdb::CVSymToPDBSym(llvm::codeview::SymbolKind kind) { - switch (kind) { - case S_COMPILE3: - case S_OBJNAME: - return PDB_SymType::CompilandDetails; - case S_ENVBLOCK: - return PDB_SymType::CompilandEnv; - case S_THUNK32: - case S_TRAMPOLINE: - return PDB_SymType::Thunk; - case S_COFFGROUP: - return PDB_SymType::CoffGroup; - case S_EXPORT: - return PDB_SymType::Export; - case S_LPROC32: - case S_GPROC32: - case S_LPROC32_DPC: - return PDB_SymType::Function; - case S_PUB32: - return PDB_SymType::PublicSymbol; - case S_INLINESITE: - return PDB_SymType::InlineSite; - case S_LOCAL: - case S_BPREL32: - case S_REGREL32: - case S_MANCONSTANT: - case S_CONSTANT: - case S_LDATA32: - case S_GDATA32: - case S_LMANDATA: - case S_GMANDATA: - case S_LTHREAD32: - case S_GTHREAD32: - return PDB_SymType::Data; - case S_BLOCK32: - return PDB_SymType::Block; - case S_LABEL32: - return PDB_SymType::Label; - case S_CALLSITEINFO: - return PDB_SymType::CallSite; - case S_HEAPALLOCSITE: - return PDB_SymType::HeapAllocationSite; - case S_CALLEES: - return PDB_SymType::Callee; - case S_CALLERS: - return PDB_SymType::Caller; - default: - lldbassert(false && "Invalid symbol record kind!"); - } - return PDB_SymType::None; -} - -bool lldb_private::npdb::SymbolHasAddress(const llvm::codeview::CVSymbol &sym) { - switch (sym.kind()) { - case S_GPROC32: - case S_LPROC32: - case S_GPROC32_ID: - case S_LPROC32_ID: - case S_LPROC32_DPC: - case S_LPROC32_DPC_ID: - case S_THUNK32: - case S_TRAMPOLINE: - case S_COFFGROUP: - case S_BLOCK32: - case S_LABEL32: - case S_CALLSITEINFO: - case S_HEAPALLOCSITE: - case S_LDATA32: - case S_GDATA32: - case S_LMANDATA: - case S_GMANDATA: - case S_LTHREAD32: - case S_GTHREAD32: - return true; - default: - return false; - } -} - -bool lldb_private::npdb::SymbolIsCode(const llvm::codeview::CVSymbol &sym) { - switch (sym.kind()) { - case S_GPROC32: - case S_LPROC32: - case S_GPROC32_ID: - case S_LPROC32_ID: - case S_LPROC32_DPC: - case S_LPROC32_DPC_ID: - case S_THUNK32: - case S_TRAMPOLINE: - case S_COFFGROUP: - case S_BLOCK32: - return true; - default: - return false; - } -} - -template RecordT createRecord(const CVSymbol &sym) { - RecordT record(static_cast(sym.kind())); - cantFail(SymbolDeserializer::deserializeAs(sym, record)); - return record; -} - -template -static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - RecordT record = createRecord(sym); - return {record.Segment, record.CodeOffset}; -} - -template <> -SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - TrampolineSym record = createRecord(sym); - return {record.ThunkSection, record.ThunkOffset}; -} - -template <> SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - Thunk32Sym record = createRecord(sym); - return {record.Segment, record.Offset}; -} - -template <> -SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - CoffGroupSym record = createRecord(sym); - return {record.Segment, record.Offset}; -} - -template <> SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - DataSym record = createRecord(sym); - return {record.Segment, record.DataOffset}; -} - -template <> -SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { - ThreadLocalDataSym record = createRecord(sym); - return {record.Segment, record.DataOffset}; -} - -SegmentOffset -lldb_private::npdb::GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym) { - switch (sym.kind()) { - case S_GPROC32: - case S_LPROC32: - case S_GPROC32_ID: - case S_LPROC32_ID: - case S_LPROC32_DPC: - case S_LPROC32_DPC_ID: - return ::GetSegmentAndOffset(sym); - case S_THUNK32: - return ::GetSegmentAndOffset(sym); - break; - case S_TRAMPOLINE: - return ::GetSegmentAndOffset(sym); - break; - case S_COFFGROUP: - return ::GetSegmentAndOffset(sym); - break; - case S_BLOCK32: - return ::GetSegmentAndOffset(sym); - break; - case S_LABEL32: - return ::GetSegmentAndOffset(sym); - break; - case S_CALLSITEINFO: - return ::GetSegmentAndOffset(sym); - break; - case S_HEAPALLOCSITE: - return ::GetSegmentAndOffset(sym); - break; - case S_LDATA32: - case S_GDATA32: - case S_LMANDATA: - case S_GMANDATA: - return ::GetSegmentAndOffset(sym); - break; - case S_LTHREAD32: - case S_GTHREAD32: - return ::GetSegmentAndOffset(sym); - break; - default: - lldbassert(false && "Record does not have a segment/offset!"); - } - return {0, 0}; -} - -template -SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { - RecordT record = createRecord(sym); - return {record.Segment, record.CodeOffset, record.CodeSize}; -} - -template <> -SegmentOffsetLength -GetSegmentOffsetAndLength(const CVSymbol &sym) { - TrampolineSym record = createRecord(sym); - return {record.ThunkSection, record.ThunkOffset, record.Size}; -} - -template <> -SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { - Thunk32Sym record = createRecord(sym); - return SegmentOffsetLength{record.Segment, record.Offset, record.Length}; -} - -template <> -SegmentOffsetLength -GetSegmentOffsetAndLength(const CVSymbol &sym) { - CoffGroupSym record = createRecord(sym); - return SegmentOffsetLength{record.Segment, record.Offset, record.Size}; -} - -SegmentOffsetLength lldb_private::npdb::GetSegmentOffsetAndLength( - const llvm::codeview::CVSymbol &sym) { - switch (sym.kind()) { - case S_GPROC32: - case S_LPROC32: - case S_GPROC32_ID: - case S_LPROC32_ID: - case S_LPROC32_DPC: - case S_LPROC32_DPC_ID: - return ::GetSegmentOffsetAndLength(sym); - case S_THUNK32: - return ::GetSegmentOffsetAndLength(sym); - break; - case S_TRAMPOLINE: - return ::GetSegmentOffsetAndLength(sym); - break; - case S_COFFGROUP: - return ::GetSegmentOffsetAndLength(sym); - break; - case S_BLOCK32: - return ::GetSegmentOffsetAndLength(sym); - break; - default: - lldbassert(false && "Record does not have a segment/offset/length triple!"); - } - return {0, 0, 0}; -} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h deleted file mode 100644 index 61b164931e48..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ /dev/null @@ -1,58 +0,0 @@ -//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H -#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H - -#include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" - -#include -#include - -namespace lldb_private { -namespace npdb { - -struct SegmentOffset { - SegmentOffset() = default; - SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} - uint16_t segment = 0; - uint32_t offset = 0; -}; - -struct SegmentOffsetLength { - SegmentOffsetLength() = default; - SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) - : so(s, o), length(l) {} - SegmentOffset so; - uint32_t length = 0; -}; - -llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); - -bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); -bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); - -SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); -SegmentOffsetLength -GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); - -template bool IsValidRecord(const RecordT &sym) { - return true; -} - -inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { - // S_PROCREF symbols have 1-based module indices. - return sym.Module > 0; -} - -} // namespace npdb -} // namespace lldb_private - -#endif diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp deleted file mode 100644 index a4cf37448be6..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ /dev/null @@ -1,620 +0,0 @@ -//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "SymbolFileNativePDB.h" - -#include "clang/Lex/Lexer.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/SymbolVendor.h" - -#include "llvm/DebugInfo/CodeView/CVRecord.h" -#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" -#include "llvm/DebugInfo/CodeView/RecordName.h" -#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" -#include "llvm/DebugInfo/PDB/Native/DbiStream.h" -#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" -#include "llvm/DebugInfo/PDB/Native/InfoStream.h" -#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" -#include "llvm/DebugInfo/PDB/Native/PDBFile.h" -#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" -#include "llvm/Object/COFF.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/MemoryBuffer.h" - -#include "PdbSymUid.h" -#include "PdbUtil.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::npdb; -using namespace llvm::codeview; -using namespace llvm::pdb; - -static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { - switch (lang) { - case PDB_Lang::Cpp: - return lldb::LanguageType::eLanguageTypeC_plus_plus; - case PDB_Lang::C: - return lldb::LanguageType::eLanguageTypeC; - default: - return lldb::LanguageType::eLanguageTypeUnknown; - } -} - -static std::unique_ptr loadPDBFile(std::string PdbPath, - llvm::BumpPtrAllocator &Allocator) { - llvm::ErrorOr> ErrorOrBuffer = - llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1, - /*RequiresNullTerminator=*/false); - if (!ErrorOrBuffer) - return nullptr; - std::unique_ptr Buffer = std::move(*ErrorOrBuffer); - - llvm::StringRef Path = Buffer->getBufferIdentifier(); - auto Stream = llvm::make_unique( - std::move(Buffer), llvm::support::little); - - auto File = llvm::make_unique(Path, std::move(Stream), Allocator); - if (auto EC = File->parseFileHeaders()) - return nullptr; - if (auto EC = File->parseStreamData()) - return nullptr; - - return File; -} - -static std::unique_ptr -loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { - // Try to find a matching PDB for an EXE. - using namespace llvm::object; - auto expected_binary = createBinary(exe_path); - - // If the file isn't a PE/COFF executable, fail. - if (!expected_binary) { - llvm::consumeError(expected_binary.takeError()); - return nullptr; - } - OwningBinary binary = std::move(*expected_binary); - - auto *obj = llvm::dyn_cast(binary.getBinary()); - if (!obj) - return nullptr; - const llvm::codeview::DebugInfo *pdb_info = nullptr; - - // If it doesn't have a debug directory, fail. - llvm::StringRef pdb_file; - auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file); - if (ec) - return nullptr; - - // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, - // fail. - llvm::file_magic magic; - ec = llvm::identify_magic(pdb_file, magic); - if (ec || magic != llvm::file_magic::pdb) - return nullptr; - std::unique_ptr pdb = loadPDBFile(pdb_file, allocator); - auto expected_info = pdb->getPDBInfoStream(); - if (!expected_info) { - llvm::consumeError(expected_info.takeError()); - return nullptr; - } - llvm::codeview::GUID guid; - memcpy(&guid, pdb_info->PDB70.Signature, 16); - - if (expected_info->getGuid() != guid) - return nullptr; - return pdb; -} - -static bool IsFunctionPrologue(const CompilandIndexItem &cci, - lldb::addr_t addr) { - // FIXME: Implement this. - return false; -} - -static bool IsFunctionEpilogue(const CompilandIndexItem &cci, - lldb::addr_t addr) { - // FIXME: Implement this. - return false; -} - -void SymbolFileNativePDB::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); -} - -void SymbolFileNativePDB::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -void SymbolFileNativePDB::DebuggerInitialize(lldb_private::Debugger &debugger) { -} - -lldb_private::ConstString SymbolFileNativePDB::GetPluginNameStatic() { - static ConstString g_name("native-pdb"); - return g_name; -} - -const char *SymbolFileNativePDB::GetPluginDescriptionStatic() { - return "Microsoft PDB debug symbol cross-platform file reader."; -} - -lldb_private::SymbolFile * -SymbolFileNativePDB::CreateInstance(lldb_private::ObjectFile *obj_file) { - return new SymbolFileNativePDB(obj_file); -} - -SymbolFileNativePDB::SymbolFileNativePDB(lldb_private::ObjectFile *object_file) - : SymbolFile(object_file) {} - -SymbolFileNativePDB::~SymbolFileNativePDB() {} - -uint32_t SymbolFileNativePDB::CalculateAbilities() { - uint32_t abilities = 0; - if (!m_obj_file) - return 0; - - if (!m_index) { - // Lazily load and match the PDB file, but only do this once. - std::unique_ptr file_up = - loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator); - - if (!file_up) { - auto module_sp = m_obj_file->GetModule(); - if (!module_sp) - return 0; - // See if any symbol file is specified through `--symfile` option. - FileSpec symfile = module_sp->GetSymbolFileFileSpec(); - if (!symfile) - return 0; - file_up = loadPDBFile(symfile.GetPath(), m_allocator); - } - - if (!file_up) - return 0; - - auto expected_index = PdbIndex::create(std::move(file_up)); - if (!expected_index) { - llvm::consumeError(expected_index.takeError()); - return 0; - } - m_index = std::move(*expected_index); - } - if (!m_index) - return 0; - - // We don't especially have to be precise here. We only distinguish between - // stripped and not stripped. - abilities = kAllAbilities; - - if (m_index->dbi().isStripped()) - abilities &= ~(Blocks | LocalVariables); - return abilities; -} - -void SymbolFileNativePDB::InitializeObject() { - m_obj_load_address = m_obj_file->GetFileOffset(); - m_index->SetLoadAddress(m_obj_load_address); - m_index->ParseSectionContribs(); -} - -uint32_t SymbolFileNativePDB::GetNumCompileUnits() { - const DbiModuleList &modules = m_index->dbi().modules(); - uint32_t count = modules.getModuleCount(); - if (count == 0) - return count; - - // The linker can inject an additional "dummy" compilation unit into the - // PDB. Ignore this special compile unit for our purposes, if it is there. - // It is always the last one. - DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); - if (last.getModuleName() == "* Linker *") - --count; - return count; -} - -lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbSymUid func_uid, - const SymbolContext &sc) { - lldbassert(func_uid.tag() == PDB_SymType::Function); - - PdbSymUid cuid = PdbSymUid::makeCompilandId(func_uid.asCuSym().modi); - - const CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid); - lldbassert(cci); - CVSymbol sym_record = - cci->m_debug_stream.readSymbolAtOffset(func_uid.asCuSym().offset); - - lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); - SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); - - auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); - if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) - return nullptr; - - AddressRange func_range(file_vm_addr, sol.length, - sc.module_sp->GetSectionList()); - if (!func_range.GetBaseAddress().IsValid()) - return nullptr; - - lldb_private::Type *func_type = nullptr; - - // FIXME: Resolve types and mangled names. - PdbSymUid sig_uid = - PdbSymUid::makeTypeSymId(PDB_SymType::FunctionSig, TypeIndex{0}, false); - Mangled mangled(getSymbolName(sym_record)); - - FunctionSP func_sp = std::make_shared( - sc.comp_unit, func_uid.toOpaqueId(), sig_uid.toOpaqueId(), mangled, - func_type, func_range); - - sc.comp_unit->AddFunction(func_sp); - return func_sp; -} - -CompUnitSP -SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { - lldb::LanguageType lang = - cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) - : lldb::eLanguageTypeUnknown; - - LazyBool optimized = eLazyBoolNo; - if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) - optimized = eLazyBoolYes; - - llvm::StringRef source_file_name = - m_index->compilands().GetMainSourceFile(cci); - lldb_private::FileSpec fs(source_file_name, false); - - CompUnitSP cu_sp = - std::make_shared(m_obj_file->GetModule(), nullptr, fs, - cci.m_uid.toOpaqueId(), lang, optimized); - - const PdbCompilandId &cuid = cci.m_uid.asCompiland(); - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cuid.modi, - cu_sp); - return cu_sp; -} - -FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbSymUid func_uid, - const SymbolContext &sc) { - lldbassert(func_uid.tag() == PDB_SymType::Function); - auto emplace_result = m_functions.try_emplace(func_uid.toOpaqueId(), nullptr); - if (emplace_result.second) - emplace_result.first->second = CreateFunction(func_uid, sc); - - lldbassert(emplace_result.first->second); - return emplace_result.first->second; -} - -CompUnitSP -SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { - auto emplace_result = - m_compilands.try_emplace(cci.m_uid.toOpaqueId(), nullptr); - if (emplace_result.second) - emplace_result.first->second = CreateCompileUnit(cci); - - lldbassert(emplace_result.first->second); - return emplace_result.first->second; -} - -lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { - if (index >= GetNumCompileUnits()) - return CompUnitSP(); - lldbassert(index < UINT16_MAX); - if (index >= UINT16_MAX) - return nullptr; - - CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); - - return GetOrCreateCompileUnit(item); -} - -lldb::LanguageType SymbolFileNativePDB::ParseCompileUnitLanguage( - const lldb_private::SymbolContext &sc) { - // What fields should I expect to be filled out on the SymbolContext? Is it - // safe to assume that `sc.comp_unit` is valid? - if (!sc.comp_unit) - return lldb::eLanguageTypeUnknown; - PdbSymUid uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(uid.tag() == PDB_SymType::Compiland); - - CompilandIndexItem *item = m_index->compilands().GetCompiland(uid); - lldbassert(item); - if (!item->m_compile_opts) - return lldb::eLanguageTypeUnknown; - - return TranslateLanguage(item->m_compile_opts->getLanguage()); -} - -size_t SymbolFileNativePDB::ParseCompileUnitFunctions( - const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit); - return false; -} - -static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { - // If any of these flags are set, we need to resolve the compile unit. - uint32_t flags = eSymbolContextCompUnit; - flags |= eSymbolContextVariable; - flags |= eSymbolContextFunction; - flags |= eSymbolContextBlock; - flags |= eSymbolContextLineEntry; - return (resolve_scope & flags) != 0; -} - -uint32_t -SymbolFileNativePDB::ResolveSymbolContext(const lldb_private::Address &addr, - uint32_t resolve_scope, - lldb_private::SymbolContext &sc) { - uint32_t resolved_flags = 0; - lldb::addr_t file_addr = addr.GetFileAddress(); - - if (NeedsResolvedCompileUnit(resolve_scope)) { - llvm::Optional modi = m_index->GetModuleIndexForVa(file_addr); - if (!modi) - return 0; - PdbSymUid cuid = PdbSymUid::makeCompilandId(*modi); - CompilandIndexItem *cci = m_index->compilands().GetCompiland(cuid); - if (!cci) - return 0; - - sc.comp_unit = GetOrCreateCompileUnit(*cci).get(); - resolved_flags |= eSymbolContextCompUnit; - } - - if (resolve_scope & eSymbolContextFunction) { - lldbassert(sc.comp_unit); - std::vector matches = m_index->FindSymbolsByVa(file_addr); - for (const auto &match : matches) { - if (match.uid.tag() != PDB_SymType::Function) - continue; - sc.function = GetOrCreateFunction(match.uid, sc).get(); - } - resolved_flags |= eSymbolContextFunction; - } - - if (resolve_scope & eSymbolContextLineEntry) { - lldbassert(sc.comp_unit); - if (auto *line_table = sc.comp_unit->GetLineTable()) { - if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) - resolved_flags |= eSymbolContextLineEntry; - } - } - - return resolved_flags; -} - -static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, - const CompilandIndexItem &cci, - lldb::addr_t base_addr, - uint32_t file_number, - const LineFragmentHeader &block, - const LineNumberEntry &cur) { - LineInfo cur_info(cur.Flags); - - if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) - return; - - uint64_t addr = base_addr + cur.Offset; - - bool is_statement = cur_info.isStatement(); - bool is_prologue = IsFunctionPrologue(cci, addr); - bool is_epilogue = IsFunctionEpilogue(cci, addr); - - uint32_t lno = cur_info.getStartLine(); - - table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, - is_statement, false, is_prologue, is_epilogue, - false); -} - -static void TerminateLineSequence(LineTable &table, - const LineFragmentHeader &block, - lldb::addr_t base_addr, uint32_t file_number, - uint32_t last_line, - std::unique_ptr seq) { - // The end is always a terminal entry, so insert it regardless. - table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, - last_line, 0, file_number, false, false, - false, false, true); - table.InsertSequence(seq.release()); -} - -bool SymbolFileNativePDB::ParseCompileUnitLineTable( - const lldb_private::SymbolContext &sc) { - // Unfortunately LLDB is set up to parse the entire compile unit line table - // all at once, even if all it really needs is line info for a specific - // function. In the future it would be nice if it could set the sc.m_function - // member, and we could only get the line info for the function in question. - lldbassert(sc.comp_unit); - PdbSymUid cu_id = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(cu_id.isCompiland()); - CompilandIndexItem *cci = m_index->compilands().GetCompiland(cu_id); - lldbassert(cci); - auto line_table = llvm::make_unique(sc.comp_unit); - - // This is basically a copy of the .debug$S subsections from all original COFF - // object files merged together with address relocations applied. We are - // looking for all DEBUG_S_LINES subsections. - for (const DebugSubsectionRecord &dssr : - cci->m_debug_stream.getSubsectionsArray()) { - if (dssr.kind() != DebugSubsectionKind::Lines) - continue; - - DebugLinesSubsectionRef lines; - llvm::BinaryStreamReader reader(dssr.getRecordData()); - if (auto EC = lines.initialize(reader)) { - llvm::consumeError(std::move(EC)); - return false; - } - - const LineFragmentHeader *lfh = lines.header(); - uint64_t virtual_addr = - m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); - - const auto &checksums = cci->m_strings.checksums().getArray(); - const auto &strings = cci->m_strings.strings(); - for (const LineColumnEntry &group : lines) { - // Indices in this structure are actually offsets of records in the - // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index - // into the global PDB string table. - auto iter = checksums.at(group.NameIndex); - if (iter == checksums.end()) - continue; - - llvm::Expected efn = - strings.getString(iter->FileNameOffset); - if (!efn) { - llvm::consumeError(efn.takeError()); - continue; - } - - // LLDB wants the index of the file in the list of support files. - auto fn_iter = llvm::find(cci->m_file_list, *efn); - lldbassert(fn_iter != cci->m_file_list.end()); - uint32_t file_index = std::distance(cci->m_file_list.begin(), fn_iter); - - std::unique_ptr sequence( - line_table->CreateLineSequenceContainer()); - lldbassert(!group.LineNumbers.empty()); - - for (const LineNumberEntry &entry : group.LineNumbers) { - AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, - file_index, *lfh, entry); - } - LineInfo last_line(group.LineNumbers.back().Flags); - TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, - last_line.getEndLine(), std::move(sequence)); - } - } - - if (line_table->GetSize() == 0) - return false; - - sc.comp_unit->SetLineTable(line_table.release()); - return true; -} - -bool SymbolFileNativePDB::ParseCompileUnitDebugMacros( - const lldb_private::SymbolContext &sc) { - // PDB doesn't contain information about macros - return false; -} - -bool SymbolFileNativePDB::ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) { - lldbassert(sc.comp_unit); - - PdbSymUid comp_uid = PdbSymUid::fromOpaqueId(sc.comp_unit->GetID()); - lldbassert(comp_uid.tag() == PDB_SymType::Compiland); - - const CompilandIndexItem *cci = m_index->compilands().GetCompiland(comp_uid); - lldbassert(cci); - - for (llvm::StringRef f : cci->m_file_list) { - FileSpec::Style style = - f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows; - FileSpec spec(f, false, style); - support_files.Append(spec); - } - - return true; -} - -bool SymbolFileNativePDB::ParseImportedModules( - const lldb_private::SymbolContext &sc, - std::vector &imported_modules) { - // PDB does not yet support module debug info - return false; -} - -size_t SymbolFileNativePDB::ParseFunctionBlocks( - const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit && sc.function); - return 0; -} - -uint32_t SymbolFileNativePDB::FindFunctions( - const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) { - // For now we only support lookup by method name. - if (!(name_type_mask & eFunctionNameTypeMethod)) - return 0; - - using SymbolAndOffset = std::pair; - - std::vector matches = m_index->globals().findRecordsByName( - name.GetStringRef(), m_index->symrecords()); - for (const SymbolAndOffset &match : matches) { - if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) - continue; - ProcRefSym proc(match.second.kind()); - cantFail(SymbolDeserializer::deserializeAs(match.second, proc)); - - if (!IsValidRecord(proc)) - continue; - - PdbSymUid cuid = PdbSymUid::makeCompilandId(proc); - CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(cuid); - lldb_private::SymbolContext sc; - - sc.comp_unit = GetOrCreateCompileUnit(cci).get(); - sc.module_sp = sc.comp_unit->GetModule(); - PdbSymUid func_uid = PdbSymUid::makeCuSymId(proc); - sc.function = GetOrCreateFunction(func_uid, sc).get(); - - sc_list.Append(sc); - } - - return sc_list.GetSize(); -} - -uint32_t -SymbolFileNativePDB::FindFunctions(const lldb_private::RegularExpression ®ex, - bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) { - return 0; -} - -lldb_private::CompilerDeclContext SymbolFileNativePDB::FindNamespace( - const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) { - return {}; -} - -lldb_private::TypeSystem * -SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { - auto type_system = - m_obj_file->GetModule()->GetTypeSystemForLanguage(language); - if (type_system) - type_system->SetSymbolFile(this); - return type_system; -} - -lldb_private::ConstString SymbolFileNativePDB::GetPluginName() { - static ConstString g_name("pdb"); - return g_name; -} - -uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h deleted file mode 100644 index 1cd197b60d1d..000000000000 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ /dev/null @@ -1,181 +0,0 @@ -//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef lldb_Plugins_SymbolFile_PDB_SymbolFileNativePDB_h_ -#define lldb_Plugins_SymbolFile_PDB_SymbolFileNativePDB_h_ - -#include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/VariableList.h" -#include "lldb/Utility/UserID.h" - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" -#include "llvm/DebugInfo/CodeView/CVRecord.h" -#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" -#include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" -#include "llvm/DebugInfo/PDB/PDBTypes.h" - -#include "CompileUnitIndex.h" -#include "PdbIndex.h" - -#include - -namespace llvm { -namespace pdb { -class PDBFile; -class PDBSymbol; -class PDBSymbolCompiland; -class PDBSymbolData; -class PDBSymbolFunc; - -class DbiStream; -class TpiStream; -class TpiStream; -class InfoStream; -class PublicsStream; -class GlobalsStream; -class SymbolStream; -class ModuleDebugStreamRef; -} // namespace pdb -} // namespace llvm - -namespace lldb_private { -namespace npdb { - -class SymbolFileNativePDB : public lldb_private::SymbolFile { -public: - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void Initialize(); - - static void Terminate(); - - static void DebuggerInitialize(lldb_private::Debugger &debugger); - - static lldb_private::ConstString GetPluginNameStatic(); - - static const char *GetPluginDescriptionStatic(); - - static lldb_private::SymbolFile * - CreateInstance(lldb_private::ObjectFile *obj_file); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - SymbolFileNativePDB(lldb_private::ObjectFile *ofile); - - ~SymbolFileNativePDB() override; - - uint32_t CalculateAbilities() override; - - void InitializeObject() override; - - //------------------------------------------------------------------ - // Compile Unit function calls - //------------------------------------------------------------------ - - uint32_t GetNumCompileUnits() override; - - lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; - - lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; - - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; - - bool ParseImportedModules( - const lldb_private::SymbolContext &sc, - std::vector &imported_modules) override; - - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - - size_t ParseTypes(const lldb_private::SymbolContext &sc) override { - return 0; - } - size_t - ParseVariablesForContext(const lldb_private::SymbolContext &sc) override { - return 0; - } - lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override { - return nullptr; - } - bool CompleteType(lldb_private::CompilerType &compiler_type) override { - return false; - } - uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, - lldb_private::SymbolContext &sc) override; - - virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, - lldb_private::TypeList &type_list) override { - return 0; - } - - uint32_t - FindFunctions(const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; - - uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, - bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; - - lldb_private::TypeSystem * - GetTypeSystemForLanguage(lldb::LanguageType language) override; - - lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx) override; - - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); } - const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); } - -private: - lldb::FunctionSP GetOrCreateFunction(PdbSymUid func_uid, - const SymbolContext &sc); - lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci); - - lldb::FunctionSP CreateFunction(PdbSymUid func_uid, const SymbolContext &sc); - lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci); - - llvm::BumpPtrAllocator m_allocator; - - lldb::addr_t m_obj_load_address = 0; - - std::unique_ptr m_index; - - llvm::DenseMap m_functions; - llvm::DenseMap m_compilands; -}; - -} // namespace npdb -} // namespace lldb_private - -#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ diff --git a/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt index 19698a7187f7..1c176c32224d 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/PDB/CMakeLists.txt @@ -9,7 +9,6 @@ add_lldb_library(lldbPluginSymbolFilePDB PLUGIN lldbCore lldbSymbol lldbUtility - lldbPluginSymbolFileNativePDB LINK_COMPONENTS DebugInfoPDB Support diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 5f3422f3e890..228de6f118c1 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -46,7 +46,6 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName -#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" #include "Plugins/SymbolFile/PDB/PDBASTParser.h" #include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" @@ -75,31 +74,14 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, } } // namespace -static bool ShouldUseNativeReader() { -#if !defined(_WIN32) - return true; -#endif - llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); - return use_native.equals_lower("on") || use_native.equals_lower("yes") || - use_native.equals_lower("1") || use_native.equals_lower("true"); -} - void SymbolFilePDB::Initialize() { - if (ShouldUseNativeReader()) { - npdb::SymbolFileNativePDB::Initialize(); - } else { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); - } + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); } void SymbolFilePDB::Terminate() { - if (ShouldUseNativeReader()) { - npdb::SymbolFileNativePDB::Terminate(); - } else { - PluginManager::UnregisterPlugin(CreateInstance); - } + PluginManager::UnregisterPlugin(CreateInstance); } void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 8232f076a937..4d45a103c5a3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -73,7 +73,6 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/Path.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -135,9 +134,7 @@ StringRef CodeViewDebug::getFullFilepath(const DIFile *File) { // If this is a Unix-style path, just use it as is. Don't try to canonicalize // it textually because one of the path components could be a symlink. - if (Dir.startswith("/") || Filename.startswith("/")) { - if (llvm::sys::path::is_absolute(Filename, llvm::sys::path::Style::posix)) - return Filename; + if (!Dir.empty() && Dir[0] == '/') { Filepath = Dir; if (Dir.back() != '/') Filepath += '/';