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
59namespace google_breakpad {
60
61class 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
73struct 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
85struct 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
110struct 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
124struct 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
145struct 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
168class 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