llvm.org GIT mirror llvm / 7b8e8e5
Make llvm-symbolizer work on Windows. Differential Revision: http://reviews.llvm.org/D9234 Reviewed By: Alexey Samsonov git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235900 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
12 changed file(s) with 202 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
0 //===-- PDBContext.h --------------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===/
8
9 #ifndef LLVM_DEBUGINFO_PDB_PDBCONTEXT_H
10 #define LLVM_DEBUGINFO_PDB_PDBCONTEXT_H
11
12 #include "llvm/DebugInfo/DIContext.h"
13 #include "llvm/DebugInfo/PDB/IPDBSession.h"
14
15 namespace llvm {
16
17 namespace object {
18 class COFFObjectFile;
19 }
20
21 /// PDBContext
22 /// This data structure is the top level entity that deals with PDB debug
23 /// information parsing. This data structure exists only when there is a
24 /// need for a transparent interface to different debug information formats
25 /// (e.g. PDB and DWARF). More control and power over the debug information
26 /// access can be had by using the PDB interfaces directly.
27 class PDBContext : public DIContext {
28
29 PDBContext(PDBContext &) = delete;
30 PDBContext &operator=(PDBContext &) = delete;
31
32 public:
33 PDBContext(const object::COFFObjectFile &Object,
34 std::unique_ptr PDBSession);
35
36 static bool classof(const DIContext *DICtx) {
37 return DICtx->getKind() == CK_PDB;
38 }
39
40 void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
41
42 DILineInfo getLineInfoForAddress(
43 uint64_t Address,
44 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
45 DILineInfoTable getLineInfoForAddressRange(
46 uint64_t Address, uint64_t Size,
47 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
48 DIInliningInfo getInliningInfoForAddress(
49 uint64_t Address,
50 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
51
52 private:
53 std::unique_ptr Session;
54 };
55 }
56
57 #endif
3131 add_llvm_library(LLVMDebugInfoPDB
3232 IPDBSourceFile.cpp
3333 PDB.cpp
34 PDBContext.cpp
3435 PDBExtras.cpp
3536 PDBInterfaceAnchors.cpp
3637 PDBSymbol.cpp
0 //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===/
8
9 #include "llvm/DebugInfo/PDB/PDBContext.h"
10 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
11 #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
12 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
13 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
15 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
16 #include "llvm/Object/COFF.h"
17
18 using namespace llvm;
19 using namespace llvm::object;
20
21 PDBContext::PDBContext(const COFFObjectFile &Object,
22 std::unique_ptr PDBSession)
23 : DIContext(CK_PDB), Session(std::move(PDBSession)) {
24 uint64_t ImageBase = 0;
25 if (Object.is64()) {
26 const pe32plus_header *Header = nullptr;
27 Object.getPE32PlusHeader(Header);
28 if (Header)
29 ImageBase = Header->ImageBase;
30 } else {
31 const pe32_header *Header = nullptr;
32 Object.getPE32Header(Header);
33 if (Header)
34 ImageBase = static_cast(Header->ImageBase);
35 }
36 Session->setLoadAddress(ImageBase);
37 }
38
39 void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
40
41 DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
42 DILineInfoSpecifier Specifier) {
43 auto Symbol = Session->findSymbolByAddress(Address);
44
45 uint32_t Length = 1;
46 DILineInfo Result;
47 if (auto Func = dyn_cast_or_null(Symbol.get())) {
48 if (Specifier.FNKind == DINameKind::LinkageName)
49 Result.FunctionName = Func->getUndecoratedName();
50 else if (Specifier.FNKind == DINameKind::ShortName)
51 Result.FunctionName = Func->getName();
52
53 Length = Func->getLength();
54 } else if (auto Data = dyn_cast_or_null(Symbol.get())) {
55 Length = Data->getLength();
56 }
57
58 // If we couldn't find a symbol, then just assume 1 byte, so that we get
59 // only the line number of the first instruction.
60 auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
61 if (!LineNumbers || LineNumbers->getChildCount() == 0)
62 return Result;
63
64 auto LineInfo = LineNumbers->getNext();
65 assert(LineInfo);
66 auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
67
68 if (SourceFile &&
69 Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
70 Result.FileName = SourceFile->getFileName();
71 Result.Column = LineInfo->getColumnNumber();
72 Result.Line = LineInfo->getLineNumber();
73 return Result;
74 }
75
76 DILineInfoTable
77 PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
78 DILineInfoSpecifier Specifier) {
79 if (Size == 0)
80 return DILineInfoTable();
81
82 DILineInfoTable Table;
83 auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
84 if (!LineNumbers || LineNumbers->getChildCount() == 0)
85 return Table;
86
87 while (auto LineInfo = LineNumbers->getNext()) {
88 DILineInfo LineEntry =
89 getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
90 Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
91 }
92 return Table;
93 }
94
95 DIInliningInfo
96 PDBContext::getInliningInfoForAddress(uint64_t Address,
97 DILineInfoSpecifier Specifier) {
98 DIInliningInfo InlineInfo;
99 DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
100 InlineInfo.addFrame(Frame);
101 return InlineInfo;
102 }
0 // To generate the corresponding EXE/PDB, run:
1 // cl /Zi test.c
2 void foo() {
3 }
4
5 int main() {
6 foo();
7 }
0 config.unsupported = not config.have_dia_sdk
0 RUN: llvm-symbolizer -obj="%p/Inputs/test.exe" < "%p/Inputs/test.exe.input" | FileCheck %s --check-prefix=CHECK
1
2 CHECK: _foo
3 CHECK-NEXT: test.c:3:0
4 CHECK: _main
5 CHECK-NEXT: test.c:6:0
6 CHECK: ??
7 CHECK-NEXT: ??:0:0
44
55 set(LLVM_LINK_COMPONENTS
66 DebugInfoDWARF
7 DebugInfoPDB
78 Object
89 Support
910 )
1414 #include "llvm/ADT/STLExtras.h"
1515 #include "llvm/Config/config.h"
1616 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
17 #include "llvm/DebugInfo/PDB/PDB.h"
18 #include "llvm/DebugInfo/PDB/PDBContext.h"
1719 #include "llvm/Object/ELFObjectFile.h"
1820 #include "llvm/Object/MachO.h"
1921 #include "llvm/Support/Casting.h"
163165 DIInliningInfo ModuleInfo::symbolizeInlinedCode(
164166 uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const {
165167 DIInliningInfo InlinedContext;
168
166169 if (DebugInfoContext) {
167170 InlinedContext = DebugInfoContext->getInliningInfoForAddress(
168171 ModuleOffset, getDILineInfoSpecifier(Opts));
460463 Modules.insert(make_pair(ModuleName, (ModuleInfo *)nullptr));
461464 return nullptr;
462465 }
463 DIContext *Context = new DWARFContextInMemory(*Objects.second);
466 DIContext *Context = nullptr;
467 if (auto CoffObject = dyn_cast(Objects.first)) {
468 // If this is a COFF object, assume it contains PDB debug information. If
469 // we don't find any we will fall back to the DWARF case.
470 std::unique_ptr Session;
471 PDB_ErrorCode Error = loadDataForEXE(PDB_ReaderType::DIA,
472 Objects.first->getFileName(), Session);
473 if (Error == PDB_ErrorCode::Success)
474 Context = new PDBContext(*CoffObject, std::move(Session));
475 }
476 if (!Context)
477 Context = new DWARFContextInMemory(*Objects.second);
464478 assert(Context);
465479 ModuleInfo *Info = new ModuleInfo(Objects.first, Context);
466480 Modules.insert(make_pair(ModuleName, Info));
1616
1717 #include "LLVMSymbolize.h"
1818 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/COM.h"
1920 #include "llvm/Support/CommandLine.h"
2021 #include "llvm/Support/Debug.h"
2122 #include "llvm/Support/FileSystem.h"
122123 PrettyStackTraceProgram X(argc, argv);
123124 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
124125
126 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
127
125128 cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n");
126129 LLVMSymbolizer::Options Opts(ClUseSymbolTable, ClPrintFunctions,
127130 ClPrintInlining, ClDemangle, ClDefaultArch);
145148 outs() << Result << "\n";
146149 outs().flush();
147150 }
151
148152 return 0;
149153 }