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_types.h: definition of nested classes/structs in |
31 | // BasicSourceLineResolver. It moves the definitions out of |
32 | // basic_source_line_resolver.cc, so that other classes could have access |
33 | // to these private nested types without including basic_source_line_resolver.cc |
34 | // |
35 | // Author: Siyang Xie (lambxsy@google.com) |
36 | |
37 | #ifndef PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ |
38 | #define PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ |
39 | |
40 | #include <map> |
41 | #include <string> |
42 | |
43 | #include "common/scoped_ptr.h" |
44 | #include "google_breakpad/processor/basic_source_line_resolver.h" |
45 | #include "processor/source_line_resolver_base_types.h" |
46 | |
47 | #include "processor/address_map-inl.h" |
48 | #include "processor/range_map-inl.h" |
49 | #include "processor/contained_range_map-inl.h" |
50 | |
51 | #include "processor/linked_ptr.h" |
52 | #include "google_breakpad/processor/stack_frame.h" |
53 | #include "processor/cfi_frame_info.h" |
54 | #include "processor/windows_frame_info.h" |
55 | |
56 | namespace google_breakpad { |
57 | |
58 | struct |
59 | BasicSourceLineResolver::Function : public SourceLineResolverBase::Function { |
60 | Function(const string& function_name, |
61 | MemAddr function_address, |
62 | MemAddr code_size, |
63 | int set_parameter_size, |
64 | bool is_mutiple) |
65 | : Base(function_name, |
66 | function_address, |
67 | code_size, |
68 | set_parameter_size, |
69 | is_mutiple), |
70 | inlines(true), |
71 | last_added_inline_nest_level(0) {} |
72 | |
73 | // Append inline into corresponding RangeMap. |
74 | // This function assumes it's called in the order of reading INLINE records. |
75 | bool AppendInline(linked_ptr<Inline> in); |
76 | |
77 | ContainedRangeMap<MemAddr, linked_ptr<Inline>> inlines; |
78 | RangeMap<MemAddr, linked_ptr<Line>> lines; |
79 | |
80 | private: |
81 | typedef SourceLineResolverBase::Function Base; |
82 | |
83 | // The last added inline_nest_level from INLINE record. |
84 | int last_added_inline_nest_level; |
85 | }; |
86 | |
87 | |
88 | class BasicSourceLineResolver::Module : public SourceLineResolverBase::Module { |
89 | public: |
90 | explicit Module(const string& name) : name_(name), is_corrupt_(false) { } |
91 | virtual ~Module() { } |
92 | |
93 | // Loads a map from the given buffer in char* type. |
94 | // Does NOT have ownership of memory_buffer. |
95 | // The passed in |memory buffer| is of size |memory_buffer_size|. If it is |
96 | // not null terminated, LoadMapFromMemory() will null terminate it by |
97 | // modifying the passed in buffer. |
98 | virtual bool LoadMapFromMemory(char* memory_buffer, |
99 | size_t memory_buffer_size); |
100 | |
101 | // Tells whether the loaded symbol data is corrupt. Return value is |
102 | // undefined, if the symbol data hasn't been loaded yet. |
103 | virtual bool IsCorrupt() const { return is_corrupt_; } |
104 | |
105 | // Looks up the given relative address, and fills the StackFrame struct |
106 | // with the result. |
107 | virtual void LookupAddress( |
108 | StackFrame* frame, |
109 | std::deque<std::unique_ptr<StackFrame>>* inlined_frame) const; |
110 | |
111 | // Construct inlined frames for |frame| and store them in |inline_frames|. |
112 | // |frame|'s source line and source file name may be updated if an inlined |
113 | // frame is found inside |frame|. As a result, the innermost inlined frame |
114 | // will be the first one in |inline_frames|. |
115 | virtual void ConstructInlineFrames( |
116 | StackFrame* frame, |
117 | MemAddr address, |
118 | const ContainedRangeMap<uint64_t, linked_ptr<Inline>>& inline_map, |
119 | std::deque<std::unique_ptr<StackFrame>>* inline_frames) const; |
120 | |
121 | // If Windows stack walking information is available covering ADDRESS, |
122 | // return a WindowsFrameInfo structure describing it. If the information |
123 | // is not available, returns NULL. A NULL return value does not indicate |
124 | // an error. The caller takes ownership of any returned WindowsFrameInfo |
125 | // object. |
126 | virtual WindowsFrameInfo* FindWindowsFrameInfo(const StackFrame* frame) const; |
127 | |
128 | // If CFI stack walking information is available covering ADDRESS, |
129 | // return a CFIFrameInfo structure describing it. If the information |
130 | // is not available, return NULL. The caller takes ownership of any |
131 | // returned CFIFrameInfo object. |
132 | virtual CFIFrameInfo* FindCFIFrameInfo(const StackFrame* frame) const; |
133 | |
134 | private: |
135 | // Friend declarations. |
136 | friend class BasicSourceLineResolver; |
137 | friend class ModuleComparer; |
138 | friend class ModuleSerializer; |
139 | |
140 | typedef std::map<int, string> FileMap; |
141 | |
142 | // Logs parse errors. |*num_errors| is increased every time LogParseError is |
143 | // called. |
144 | static void LogParseError( |
145 | const string& message, |
146 | int line_number, |
147 | int* num_errors); |
148 | |
149 | // Parses a file declaration |
150 | bool ParseFile(char* file_line); |
151 | |
152 | // Parses an inline origin declaration. |
153 | bool ParseInlineOrigin(char* inline_origin_line); |
154 | |
155 | // Parses an inline declaration. |
156 | linked_ptr<Inline> ParseInline(char* inline_line); |
157 | |
158 | // Parses a function declaration, returning a new Function object. |
159 | Function* ParseFunction(char* function_line); |
160 | |
161 | // Parses a line declaration, returning a new Line object. |
162 | Line* ParseLine(char* line_line); |
163 | |
164 | // Parses a PUBLIC symbol declaration, storing it in public_symbols_. |
165 | // Returns false if an error occurs. |
166 | bool ParsePublicSymbol(char* public_line); |
167 | |
168 | // Parses a STACK WIN or STACK CFI frame info declaration, storing |
169 | // it in the appropriate table. |
170 | bool ParseStackInfo(char* stack_info_line); |
171 | |
172 | // Parses a STACK CFI record, storing it in cfi_frame_info_. |
173 | bool ParseCFIFrameInfo(char* stack_info_line); |
174 | |
175 | string name_; |
176 | FileMap files_; |
177 | std::map<int, linked_ptr<InlineOrigin>> inline_origins_; |
178 | RangeMap< MemAddr, linked_ptr<Function> > functions_; |
179 | AddressMap< MemAddr, linked_ptr<PublicSymbol> > public_symbols_; |
180 | bool is_corrupt_; |
181 | |
182 | // Each element in the array is a ContainedRangeMap for a type |
183 | // listed in WindowsFrameInfoTypes. These are split by type because |
184 | // there may be overlaps between maps of different types, but some |
185 | // information is only available as certain types. |
186 | ContainedRangeMap< MemAddr, linked_ptr<WindowsFrameInfo> > |
187 | windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST]; |
188 | |
189 | // DWARF CFI stack walking data. The Module stores the initial rule sets |
190 | // and rule deltas as strings, just as they appear in the symbol file: |
191 | // although the file may contain hundreds of thousands of STACK CFI |
192 | // records, walking a stack will only ever use a few of them, so it's |
193 | // best to delay parsing a record until it's actually needed. |
194 | |
195 | // STACK CFI INIT records: for each range, an initial set of register |
196 | // recovery rules. The RangeMap's itself gives the starting and ending |
197 | // addresses. |
198 | RangeMap<MemAddr, string> cfi_initial_rules_; |
199 | |
200 | // STACK CFI records: at a given address, the changes to the register |
201 | // recovery rules that take effect at that address. The map key is the |
202 | // starting address; the ending address is the key of the next entry in |
203 | // this map, or the end of the range as given by the cfi_initial_rules_ |
204 | // entry (which FindCFIFrameInfo looks up first). |
205 | std::map<MemAddr, string> cfi_delta_rules_; |
206 | }; |
207 | |
208 | } // namespace google_breakpad |
209 | |
210 | #endif // PROCESSOR_BASIC_SOURCE_LINE_RESOLVER_TYPES_H__ |
211 | |