1// Copyright (c) 2010 Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// basic_source_line_resolver.h: BasicSourceLineResolver is derived from
31// SourceLineResolverBase, and is a concrete implementation of
32// SourceLineResolverInterface, using address map files produced by a
33// compatible writer, e.g. PDBSourceLineWriter.
34//
35// see "processor/source_line_resolver_base.h"
36// and "source_line_resolver_interface.h" for more documentation.
37
38#ifndef GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
39#define GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
40
41#include <map>
42#include <string>
43#include <vector>
44
45#include "common/using_std_string.h"
46#include "google_breakpad/processor/source_line_resolver_base.h"
47
48namespace google_breakpad {
49
50using std::map;
51
52class BasicSourceLineResolver : public SourceLineResolverBase {
53 public:
54 BasicSourceLineResolver();
55 virtual ~BasicSourceLineResolver() { }
56
57 using SourceLineResolverBase::LoadModule;
58 using SourceLineResolverBase::LoadModuleUsingMapBuffer;
59 using SourceLineResolverBase::LoadModuleUsingMemoryBuffer;
60 using SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule;
61 using SourceLineResolverBase::UnloadModule;
62 using SourceLineResolverBase::HasModule;
63 using SourceLineResolverBase::IsModuleCorrupt;
64 using SourceLineResolverBase::FillSourceLineInfo;
65 using SourceLineResolverBase::FindWindowsFrameInfo;
66 using SourceLineResolverBase::FindCFIFrameInfo;
67
68 private:
69 // friend declarations:
70 friend class BasicModuleFactory;
71 friend class ModuleComparer;
72 friend class ModuleSerializer;
73 template<class> friend class SimpleSerializer;
74
75 // Function derives from SourceLineResolverBase::Function.
76 struct Function;
77 // Module implements SourceLineResolverBase::Module interface.
78 class Module;
79
80 // Disallow unwanted copy ctor and assignment operator
81 BasicSourceLineResolver(const BasicSourceLineResolver&);
82 void operator=(const BasicSourceLineResolver&);
83};
84
85// Helper class, containing useful methods for parsing of Breakpad symbol files.
86class SymbolParseHelper {
87 public:
88 using MemAddr = SourceLineResolverInterface::MemAddr;
89
90 // Parses a |file_line| declaration. Returns true on success.
91 // Format: FILE <id> <filename>.
92 // Notice, that this method modifies the input |file_line| which is why it
93 // can't be const. On success, <id>, and <filename> are stored in |*index|,
94 // and |*filename|. No allocation is done, |*filename| simply points inside
95 // |file_line|.
96 static bool ParseFile(char* file_line, // in
97 long* index, // out
98 char** filename); // out
99
100 // Parses a |inline_origin_line| declaration. Returns true on success.
101 // Old Format: INLINE_ORIGIN <origin_id> <file_id> <name>.
102 // New Format: INLINE_ORIGIN <origin_id> <name>.
103 // Notice, that this method modifies the input |inline_origin_line| which is
104 // why it can't be const. On success, <has_file_id>, <origin_id>, <file_id>
105 // and <name> are stored in |*has_file_id*|, |*origin_id|, |*file_id|, and
106 // |*name|. No allocation is done, |*name| simply points inside
107 // |inline_origin_line|.
108 static bool ParseInlineOrigin(char* inline_origin_line, // in
109 bool* has_file_id, // out
110 long* origin_id, // out
111 long* file_id, // out
112 char** name); // out
113
114 // Parses a |inline| declaration. Returns true on success.
115 // Old Format: INLINE <inline_nest_level> <call_site_line> <origin_id>
116 // [<address> <size>]+
117 // New Format: INLINE <inline_nest_level> <call_site_line> <call_site_file_id>
118 // <origin_id> [<address> <size>]+
119 // Notice, that this method modifies the input |inline|
120 // which is why it can't be const. On success, <has_call_site_file_id>,
121 // <inline_nest_level>, <call_site_line> and <origin_id> are stored in
122 // |*has_call_site_file_id*|, |*inline_nest_level|, |*call_site_line|, and
123 // |*origin_id|, and all pairs of (<address>, <size>) are added into ranges.
124 static bool ParseInline(
125 char* inline_line, // in
126 bool* has_call_site_file_id, // out
127 long* inline_nest_level, // out
128 long* call_site_line, // out
129 long* call_site_file_id, // out
130 long* origin_id, // out
131 std::vector<std::pair<MemAddr, MemAddr>>* ranges); // out
132
133 // Parses a |function_line| declaration. Returns true on success.
134 // Format: FUNC [<multiple>] <address> <size> <stack_param_size> <name>.
135 // Notice, that this method modifies the input |function_line| which is why it
136 // can't be const. On success, the presence of <multiple>, <address>, <size>,
137 // <stack_param_size>, and <name> are stored in |*is_multiple|, |*address|,
138 // |*size|, |*stack_param_size|, and |*name|. No allocation is done, |*name|
139 // simply points inside |function_line|.
140 static bool ParseFunction(char* function_line, // in
141 bool* is_multiple, // out
142 uint64_t* address, // out
143 uint64_t* size, // out
144 long* stack_param_size, // out
145 char** name); // out
146
147 // Parses a |line| declaration. Returns true on success.
148 // Format: <address> <size> <line number> <source file id>
149 // Notice, that this method modifies the input |function_line| which is why
150 // it can't be const. On success, <address>, <size>, <line number>, and
151 // <source file id> are stored in |*address|, |*size|, |*line_number|, and
152 // |*source_file|.
153 static bool ParseLine(char* line_line, // in
154 uint64_t* address, // out
155 uint64_t* size, // out
156 long* line_number, // out
157 long* source_file); // out
158
159 // Parses a |public_line| declaration. Returns true on success.
160 // Format: PUBLIC [<multiple>] <address> <stack_param_size> <name>
161 // Notice, that this method modifies the input |function_line| which is why
162 // it can't be const. On success, the presence of <multiple>, <address>,
163 // <stack_param_size>, <name> are stored in |*is_multiple|, |*address|,
164 // |*stack_param_size|, and |*name|. No allocation is done, |*name| simply
165 // points inside |public_line|.
166 static bool ParsePublicSymbol(char* public_line, // in
167 bool* is_multiple, // out
168 uint64_t* address, // out
169 long* stack_param_size, // out
170 char** name); // out
171
172 private:
173 // Used for success checks after strtoull and strtol.
174 static bool IsValidAfterNumber(char* after_number);
175
176 // Only allow static methods.
177 SymbolParseHelper();
178 SymbolParseHelper(const SymbolParseHelper&);
179 void operator=(const SymbolParseHelper&);
180};
181
182} // namespace google_breakpad
183
184#endif // GOOGLE_BREAKPAD_PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_H__
185