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 "google_breakpad/processor/fast_source_line_resolver.h"
41#include "processor/source_line_resolver_base_types.h"
42
43#include <map>
44#include <string>
45
46#include "google_breakpad/processor/stack_frame.h"
47#include "processor/cfi_frame_info.h"
48#include "processor/static_address_map-inl.h"
49#include "processor/static_contained_range_map-inl.h"
50#include "processor/static_map.h"
51#include "processor/static_range_map-inl.h"
52#include "processor/windows_frame_info.h"
53
54namespace google_breakpad {
55
56struct FastSourceLineResolver::Line : public SourceLineResolverBase::Line {
57  void CopyFrom(const Line *line_ptr) {
58    const char *raw = reinterpret_cast<const char*>(line_ptr);
59    CopyFrom(raw);
60  }
61
62  // De-serialize the memory data of a Line.
63  void CopyFrom(const char *raw) {
64    address = *(reinterpret_cast<const MemAddr*>(raw));
65    size = *(reinterpret_cast<const MemAddr*>(raw + sizeof(address)));
66    source_file_id = *(reinterpret_cast<const int32_t *>(
67        raw + 2 * sizeof(address)));
68    line = *(reinterpret_cast<const int32_t*>(
69        raw + 2 * sizeof(address) + sizeof(source_file_id)));
70  }
71};
72
73struct FastSourceLineResolver::Function :
74public SourceLineResolverBase::Function {
75  void CopyFrom(const Function *func_ptr) {
76    const char *raw = reinterpret_cast<const char*>(func_ptr);
77    CopyFrom(raw);
78  }
79
80  // De-serialize the memory data of a Function.
81  void CopyFrom(const char *raw) {
82    size_t name_size = strlen(raw) + 1;
83    name = raw;
84    address = *(reinterpret_cast<const MemAddr*>(raw + name_size));
85    size = *(reinterpret_cast<const MemAddr*>(
86        raw + name_size + sizeof(MemAddr)));
87    parameter_size = *(reinterpret_cast<const int32_t*>(
88        raw + name_size + 2 * sizeof(MemAddr)));
89    lines = StaticRangeMap<MemAddr, Line>(
90        raw + name_size + 2 * sizeof(MemAddr) + sizeof(int32_t));
91  }
92
93  StaticRangeMap<MemAddr, Line> lines;
94};
95
96struct FastSourceLineResolver::PublicSymbol :
97public SourceLineResolverBase::PublicSymbol {
98  void CopyFrom(const PublicSymbol *public_symbol_ptr) {
99    const char *raw = reinterpret_cast<const char*>(public_symbol_ptr);
100    CopyFrom(raw);
101  }
102
103  // De-serialize the memory data of a PublicSymbol.
104  void CopyFrom(const char *raw) {
105    size_t name_size = strlen(raw) + 1;
106    name = raw;
107    address = *(reinterpret_cast<const MemAddr*>(raw + name_size));
108    parameter_size = *(reinterpret_cast<const int32_t*>(
109        raw + name_size + sizeof(MemAddr)));
110  }
111};
112
113class FastSourceLineResolver::Module: public SourceLineResolverBase::Module {
114 public:
115  explicit Module(const string &name) : name_(name), is_corrupt_(false) { }
116  virtual ~Module() { }
117
118  // Looks up the given relative address, and fills the StackFrame struct
119  // with the result.
120  virtual void LookupAddress(StackFrame *frame) const;
121
122  // Loads a map from the given buffer in char* type.
123  virtual bool LoadMapFromMemory(char *memory_buffer,
124                                 size_t memory_buffer_size);
125
126  // Tells whether the loaded symbol data is corrupt.  Return value is
127  // undefined, if the symbol data hasn't been loaded yet.
128  virtual bool IsCorrupt() const { return is_corrupt_; }
129
130  // If Windows stack walking information is available covering ADDRESS,
131  // return a WindowsFrameInfo structure describing it. If the information
132  // is not available, returns NULL. A NULL return value does not indicate
133  // an error. The caller takes ownership of any returned WindowsFrameInfo
134  // object.
135  virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) const;
136
137  // If CFI stack walking information is available covering ADDRESS,
138  // return a CFIFrameInfo structure describing it. If the information
139  // is not available, return NULL. The caller takes ownership of any
140  // returned CFIFrameInfo object.
141  virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) const;
142
143  // Number of serialized map components of Module.
144  static const int kNumberMaps_ = 5 + WindowsFrameInfo::STACK_INFO_LAST;
145
146 private:
147  friend class FastSourceLineResolver;
148  friend class ModuleComparer;
149  typedef StaticMap<int, char> FileMap;
150
151  string name_;
152  StaticMap<int, char> files_;
153  StaticRangeMap<MemAddr, Function> functions_;
154  StaticAddressMap<MemAddr, PublicSymbol> public_symbols_;
155  bool is_corrupt_;
156
157  // Each element in the array is a ContainedRangeMap for a type
158  // listed in WindowsFrameInfoTypes. These are split by type because
159  // there may be overlaps between maps of different types, but some
160  // information is only available as certain types.
161  StaticContainedRangeMap<MemAddr, char>
162    windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST];
163
164  // DWARF CFI stack walking data. The Module stores the initial rule sets
165  // and rule deltas as strings, just as they appear in the symbol file:
166  // although the file may contain hundreds of thousands of STACK CFI
167  // records, walking a stack will only ever use a few of them, so it's
168  // best to delay parsing a record until it's actually needed.
169  //
170  // STACK CFI INIT records: for each range, an initial set of register
171  // recovery rules. The RangeMap's itself gives the starting and ending
172  // addresses.
173  StaticRangeMap<MemAddr, char> cfi_initial_rules_;
174
175  // STACK CFI records: at a given address, the changes to the register
176  // recovery rules that take effect at that address. The map key is the
177  // starting address; the ending address is the key of the next entry in
178  // this map, or the end of the range as given by the cfi_initial_rules_
179  // entry (which FindCFIFrameInfo looks up first).
180  StaticMap<MemAddr, char> cfi_delta_rules_;
181};
182
183}  // namespace google_breakpad
184
185#endif  // PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__
186