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 | |
48 | namespace google_breakpad { |
49 | |
50 | using std::map; |
51 | |
52 | class 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. |
86 | class 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 | |