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 | // source_line_resolver_base_types.h: definition of nested classes/structs in |
31 | // SourceLineResolverBase. It moves the definitions out of |
32 | // source_line_resolver_base.cc, so that other classes may have access |
33 | // to these private nested types without including source_line_resolver_base.cc |
34 | // In addition, Module is defined as a pure abstract class to be implemented by |
35 | // each concrete source line resolver class. |
36 | // |
37 | // See source_line_resolver_base.h for more documentation. |
38 | // |
39 | // Author: Siyang Xie (lambxsy@google.com) |
40 | |
41 | #include <stdio.h> |
42 | |
43 | #include <deque> |
44 | #include <map> |
45 | #include <memory> |
46 | #include <string> |
47 | |
48 | #include "google_breakpad/common/breakpad_types.h" |
49 | #include "google_breakpad/processor/source_line_resolver_base.h" |
50 | #include "google_breakpad/processor/stack_frame.h" |
51 | #include "processor/cfi_frame_info.h" |
52 | #include "processor/linked_ptr.h" |
53 | #include "processor/range_map.h" |
54 | #include "processor/windows_frame_info.h" |
55 | |
56 | #ifndef PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ |
57 | #define PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ |
58 | |
59 | namespace google_breakpad { |
60 | |
61 | class SourceLineResolverBase::AutoFileCloser { |
62 | public: |
63 | explicit AutoFileCloser(FILE* file) : file_(file) {} |
64 | ~AutoFileCloser() { |
65 | if (file_) |
66 | fclose(file_); |
67 | } |
68 | |
69 | private: |
70 | FILE* file_; |
71 | }; |
72 | |
73 | struct SourceLineResolverBase::InlineOrigin { |
74 | InlineOrigin() {} |
75 | InlineOrigin(bool has_file_id, int32_t source_file_id, const string& name) |
76 | : has_file_id(has_file_id), |
77 | source_file_id(source_file_id), |
78 | name(name) {} |
79 | // If it's old format, source file id is set, otherwise not useful. |
80 | bool has_file_id; |
81 | int32_t source_file_id; |
82 | string name; |
83 | }; |
84 | |
85 | struct SourceLineResolverBase::Inline { |
86 | // A vector of (address, size) pair for a INLINE record. |
87 | using InlineRanges = std::vector<std::pair<MemAddr, MemAddr>>; |
88 | Inline() {} |
89 | Inline(bool has_call_site_file_id, |
90 | int32_t inline_nest_level, |
91 | int32_t call_site_line, |
92 | int32_t call_site_file_id, |
93 | int32_t origin_id, |
94 | InlineRanges inline_ranges) |
95 | : has_call_site_file_id(has_call_site_file_id), |
96 | inline_nest_level(inline_nest_level), |
97 | call_site_line(call_site_line), |
98 | call_site_file_id(call_site_file_id), |
99 | origin_id(origin_id), |
100 | inline_ranges(inline_ranges) {} |
101 | // If it's new format, call site file id is set, otherwise not useful. |
102 | bool has_call_site_file_id; |
103 | int32_t inline_nest_level; |
104 | int32_t call_site_line; |
105 | int32_t call_site_file_id; |
106 | int32_t origin_id; |
107 | InlineRanges inline_ranges; |
108 | }; |
109 | |
110 | struct SourceLineResolverBase::Line { |
111 | Line() { } |
112 | Line(MemAddr addr, MemAddr code_size, int file_id, int source_line) |
113 | : address(addr) |
114 | , size(code_size) |
115 | , source_file_id(file_id) |
116 | , line(source_line) { } |
117 | |
118 | MemAddr address; |
119 | MemAddr size; |
120 | int32_t source_file_id; |
121 | int32_t line; |
122 | }; |
123 | |
124 | struct SourceLineResolverBase::Function { |
125 | Function() { } |
126 | Function(const string& function_name, |
127 | MemAddr function_address, |
128 | MemAddr code_size, |
129 | int set_parameter_size, |
130 | bool is_multiple) |
131 | : name(function_name), address(function_address), size(code_size), |
132 | parameter_size(set_parameter_size), is_multiple(is_multiple) { } |
133 | |
134 | string name; |
135 | MemAddr address; |
136 | MemAddr size; |
137 | |
138 | // The size of parameters passed to this function on the stack. |
139 | int32_t parameter_size; |
140 | |
141 | // If the function's instructions correspond to multiple symbols. |
142 | bool is_multiple; |
143 | }; |
144 | |
145 | struct SourceLineResolverBase::PublicSymbol { |
146 | PublicSymbol() { } |
147 | PublicSymbol(const string& set_name, |
148 | MemAddr set_address, |
149 | int set_parameter_size, |
150 | bool is_multiple) |
151 | : name(set_name), |
152 | address(set_address), |
153 | parameter_size(set_parameter_size), |
154 | is_multiple(is_multiple) {} |
155 | |
156 | string name; |
157 | MemAddr address; |
158 | |
159 | // If the public symbol is used as a function entry point, parameter_size |
160 | // is set to the size of the parameters passed to the funciton on the |
161 | // stack, if known. |
162 | int32_t parameter_size; |
163 | |
164 | // If the function's instructions correspond to multiple symbols. |
165 | bool is_multiple; |
166 | }; |
167 | |
168 | class SourceLineResolverBase::Module { |
169 | public: |
170 | virtual ~Module() { }; |
171 | // Loads a map from the given buffer in char* type. |
172 | // Does NOT take ownership of memory_buffer (the caller, source line resolver, |
173 | // is the owner of memory_buffer). |
174 | // The passed in |memory buffer| is of size |memory_buffer_size|. If it is |
175 | // not null terminated, LoadMapFromMemory will null terminate it by modifying |
176 | // the passed in buffer. |
177 | virtual bool LoadMapFromMemory(char* memory_buffer, |
178 | size_t memory_buffer_size) = 0; |
179 | |
180 | // Tells whether the loaded symbol data is corrupt. Return value is |
181 | // undefined, if the symbol data hasn't been loaded yet. |
182 | virtual bool IsCorrupt() const = 0; |
183 | |
184 | // Looks up the given relative address, and fills the StackFrame struct |
185 | // with the result. |
186 | virtual void LookupAddress( |
187 | StackFrame* frame, |
188 | std::deque<std::unique_ptr<StackFrame>>* inlined_frames) const = 0; |
189 | |
190 | // If Windows stack walking information is available covering ADDRESS, |
191 | // return a WindowsFrameInfo structure describing it. If the information |
192 | // is not available, returns NULL. A NULL return value does not indicate |
193 | // an error. The caller takes ownership of any returned WindowsFrameInfo |
194 | // object. |
195 | virtual WindowsFrameInfo* |
196 | FindWindowsFrameInfo(const StackFrame* frame) const = 0; |
197 | |
198 | // If CFI stack walking information is available covering ADDRESS, |
199 | // return a CFIFrameInfo structure describing it. If the information |
200 | // is not available, return NULL. The caller takes ownership of any |
201 | // returned CFIFrameInfo object. |
202 | virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame) const = 0; |
203 | protected: |
204 | virtual bool ParseCFIRuleSet(const string& rule_set, |
205 | CFIFrameInfo* frame_info) const; |
206 | }; |
207 | |
208 | } // namespace google_breakpad |
209 | |
210 | #endif // PROCESSOR_SOURCE_LINE_RESOLVER_BASE_TYPES_H__ |
211 | |