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 | // fast_source_line_resolver_types.h: definition of nested classes/structs in |
31 | // FastSourceLineResolver. It moves the definitions out of |
32 | // fast_source_line_resolver.cc, so that other classes could have access |
33 | // to these private nested types without including fast_source_line_resolver.cc |
34 | // |
35 | // Author: lambxsy@google.com (Siyang Xie) |
36 | |
37 | #ifndef PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ |
38 | #define PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ |
39 | |
40 | #include <cstdint> |
41 | #include <map> |
42 | #include <string> |
43 | |
44 | #include "google_breakpad/processor/fast_source_line_resolver.h" |
45 | #include "google_breakpad/processor/stack_frame.h" |
46 | #include "processor/cfi_frame_info.h" |
47 | #include "processor/contained_range_map.h" |
48 | #include "processor/simple_serializer-inl.h" |
49 | #include "processor/source_line_resolver_base_types.h" |
50 | #include "processor/static_address_map-inl.h" |
51 | #include "processor/static_contained_range_map-inl.h" |
52 | #include "processor/static_map.h" |
53 | #include "processor/static_range_map-inl.h" |
54 | #include "processor/windows_frame_info.h" |
55 | |
56 | namespace google_breakpad { |
57 | |
58 | #define DESERIALIZE(raw_ptr, field) \ |
59 | field = *(reinterpret_cast<const decltype(field)*>(raw_ptr)); \ |
60 | raw_ptr += sizeof(field); |
61 | |
62 | struct FastSourceLineResolver::Line : public SourceLineResolverBase::Line { |
63 | void CopyFrom(const Line* line_ptr) { |
64 | const char* raw = reinterpret_cast<const char*>(line_ptr); |
65 | CopyFrom(raw); |
66 | } |
67 | |
68 | // De-serialize the memory data of a Line. |
69 | void CopyFrom(const char* raw) { |
70 | DESERIALIZE(raw, address); |
71 | DESERIALIZE(raw, size); |
72 | DESERIALIZE(raw, source_file_id); |
73 | DESERIALIZE(raw, line); |
74 | } |
75 | }; |
76 | |
77 | struct FastSourceLineResolver::Function : |
78 | public SourceLineResolverBase::Function { |
79 | void CopyFrom(const Function* func_ptr) { |
80 | const char* raw = reinterpret_cast<const char*>(func_ptr); |
81 | CopyFrom(raw); |
82 | } |
83 | |
84 | // De-serialize the memory data of a Function. |
85 | void CopyFrom(const char* raw) { |
86 | size_t name_size = strlen(raw) + 1; |
87 | name = raw; |
88 | raw += name_size; |
89 | DESERIALIZE(raw, address); |
90 | DESERIALIZE(raw, size); |
91 | DESERIALIZE(raw, parameter_size); |
92 | raw = SimpleSerializer<bool>::Read(raw, &is_multiple); |
93 | int32_t inline_size; |
94 | DESERIALIZE(raw, inline_size); |
95 | inlines = StaticContainedRangeMap<MemAddr, char>(raw); |
96 | lines = StaticRangeMap<MemAddr, Line>(raw + inline_size); |
97 | } |
98 | |
99 | StaticContainedRangeMap<MemAddr, char> inlines; |
100 | StaticRangeMap<MemAddr, Line> lines; |
101 | }; |
102 | |
103 | struct FastSourceLineResolver::Inline : public SourceLineResolverBase::Inline { |
104 | void CopyFrom(const Inline* inline_ptr) { |
105 | const char* raw = reinterpret_cast<const char*>(inline_ptr); |
106 | CopyFrom(raw); |
107 | } |
108 | |
109 | // De-serialize the memory data of a Inline. |
110 | void CopyFrom(const char* raw) { |
111 | DESERIALIZE(raw, has_call_site_file_id); |
112 | DESERIALIZE(raw, inline_nest_level); |
113 | DESERIALIZE(raw, call_site_line); |
114 | DESERIALIZE(raw, call_site_file_id); |
115 | DESERIALIZE(raw, origin_id); |
116 | uint32_t inline_range_size; |
117 | DESERIALIZE(raw, inline_range_size); |
118 | for (size_t i = 0; i < inline_range_size; i += 2) { |
119 | std::pair<MemAddr, MemAddr> range; |
120 | DESERIALIZE(raw, range.first); |
121 | DESERIALIZE(raw, range.second); |
122 | inline_ranges.push_back(range); |
123 | } |
124 | } |
125 | }; |
126 | |
127 | struct FastSourceLineResolver::InlineOrigin |
128 | : public SourceLineResolverBase::InlineOrigin { |
129 | void CopyFrom(const InlineOrigin* origin_ptr) { |
130 | const char* raw = reinterpret_cast<const char*>(origin_ptr); |
131 | CopyFrom(raw); |
132 | } |
133 | |
134 | // De-serialize the memory data of a Line. |
135 | void CopyFrom(const char* raw) { |
136 | DESERIALIZE(raw, has_file_id); |
137 | DESERIALIZE(raw, source_file_id); |
138 | name = raw; |
139 | } |
140 | }; |
141 | |
142 | struct FastSourceLineResolver::PublicSymbol : |
143 | public SourceLineResolverBase::PublicSymbol { |
144 | void CopyFrom(const PublicSymbol* public_symbol_ptr) { |
145 | const char* raw = reinterpret_cast<const char*>(public_symbol_ptr); |
146 | CopyFrom(raw); |
147 | } |
148 | |
149 | // De-serialize the memory data of a PublicSymbol. |
150 | void CopyFrom(const char* raw) { |
151 | size_t name_size = strlen(raw) + 1; |
152 | name = raw; |
153 | raw += name_size; |
154 | DESERIALIZE(raw, address); |
155 | DESERIALIZE(raw, parameter_size); |
156 | raw = SimpleSerializer<bool>::Read(raw, &is_multiple); |
157 | } |
158 | }; |
159 | |
160 | #undef DESERIALIZE |
161 | |
162 | class FastSourceLineResolver::Module: public SourceLineResolverBase::Module { |
163 | public: |
164 | explicit Module(const string& name) : name_(name), is_corrupt_(false) { } |
165 | virtual ~Module() { } |
166 | |
167 | // Looks up the given relative address, and fills the StackFrame struct |
168 | // with the result. |
169 | virtual void LookupAddress( |
170 | StackFrame* frame, |
171 | std::deque<std::unique_ptr<StackFrame>>* inlined_frames) const; |
172 | |
173 | // Construct inlined frames for |frame| and store them in |inline_frames|. |
174 | // |frame|'s source line and source file name may be updated if an inlined |
175 | // frame is found inside |frame|. As a result, the innermost inlined frame |
176 | // will be the first one in |inline_frames|. |
177 | virtual void ConstructInlineFrames( |
178 | StackFrame* frame, |
179 | MemAddr address, |
180 | const StaticContainedRangeMap<MemAddr, char>& inline_map, |
181 | std::deque<std::unique_ptr<StackFrame>>* inlined_frames) const; |
182 | |
183 | // Loads a map from the given buffer in char* type. |
184 | virtual bool LoadMapFromMemory(char* memory_buffer, |
185 | size_t memory_buffer_size); |
186 | |
187 | // Tells whether the loaded symbol data is corrupt. Return value is |
188 | // undefined, if the symbol data hasn't been loaded yet. |
189 | virtual bool IsCorrupt() const { return is_corrupt_; } |
190 | |
191 | // If Windows stack walking information is available covering ADDRESS, |
192 | // return a WindowsFrameInfo structure describing it. If the information |
193 | // is not available, returns NULL. A NULL return value does not indicate |
194 | // an error. The caller takes ownership of any returned WindowsFrameInfo |
195 | // object. |
196 | virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame) const; |
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; |
203 | |
204 | // Number of serialized map components of Module. |
205 | static const int kNumberMaps_ = 6 + WindowsFrameInfo::STACK_INFO_LAST; |
206 | |
207 | private: |
208 | friend class FastSourceLineResolver; |
209 | friend class ModuleComparer; |
210 | typedef StaticMap<int, char> FileMap; |
211 | |
212 | string name_; |
213 | StaticMap<int, char> files_; |
214 | StaticRangeMap<MemAddr, Function> functions_; |
215 | StaticAddressMap<MemAddr, PublicSymbol> public_symbols_; |
216 | bool is_corrupt_; |
217 | |
218 | // Each element in the array is a ContainedRangeMap for a type |
219 | // listed in WindowsFrameInfoTypes. These are split by type because |
220 | // there may be overlaps between maps of different types, but some |
221 | // information is only available as certain types. |
222 | StaticContainedRangeMap<MemAddr, char> |
223 | windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST]; |
224 | |
225 | // DWARF CFI stack walking data. The Module stores the initial rule sets |
226 | // and rule deltas as strings, just as they appear in the symbol file: |
227 | // although the file may contain hundreds of thousands of STACK CFI |
228 | // records, walking a stack will only ever use a few of them, so it's |
229 | // best to delay parsing a record until it's actually needed. |
230 | // |
231 | // STACK CFI INIT records: for each range, an initial set of register |
232 | // recovery rules. The RangeMap's itself gives the starting and ending |
233 | // addresses. |
234 | StaticRangeMap<MemAddr, char> cfi_initial_rules_; |
235 | |
236 | // STACK CFI records: at a given address, the changes to the register |
237 | // recovery rules that take effect at that address. The map key is the |
238 | // starting address; the ending address is the key of the next entry in |
239 | // this map, or the end of the range as given by the cfi_initial_rules_ |
240 | // entry (which FindCFIFrameInfo looks up first). |
241 | StaticMap<MemAddr, char> cfi_delta_rules_; |
242 | |
243 | // INLINE_ORIGIN records: used as a function name string pool for INLINE |
244 | // records. |
245 | StaticMap<int, char> inline_origins_; |
246 | }; |
247 | |
248 | } // namespace google_breakpad |
249 | |
250 | #endif // PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__ |
251 | |