Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
4 /* libunwind - a platform-independent unwind library
5 Copyright 2011 Linaro Limited
7 This file is part of libunwind.
9 Permission is hereby granted, free of charge, to any person obtaining
10 a copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sublicense, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice shall be
18 included in all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 // Copyright (c) 2010, 2011 Google Inc.
30 // All rights reserved.
31 //
32 // Redistribution and use in source and binary forms, with or without
33 // modification, are permitted provided that the following conditions are
34 // met:
35 //
36 // * Redistributions of source code must retain the above copyright
37 // notice, this list of conditions and the following disclaimer.
38 // * Redistributions in binary form must reproduce the above
39 // copyright notice, this list of conditions and the following disclaimer
40 // in the documentation and/or other materials provided with the
41 // distribution.
42 // * Neither the name of Google Inc. nor the names of its
43 // contributors may be used to endorse or promote products derived from
44 // this software without specific prior written permission.
45 //
46 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
49 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
50 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 // Derived from libunwind, with extensive modifications.
60 // This file is derived from the following files in
61 // toolkit/crashreporter/google-breakpad:
62 // src/common/arm_ex_to_module.h
63 // src/common/memory_range.h
64 // src/common/arm_ex_reader.h
66 #ifndef LulExidxExt_h
67 #define LulExidxExt_h
69 #include "LulMainInt.h"
71 using lul::LExpr;
72 using lul::RuleSet;
73 using lul::SecMap;
75 namespace lul {
77 typedef enum extab_cmd {
78 ARM_EXIDX_CMD_FINISH,
79 ARM_EXIDX_CMD_SUB_FROM_VSP,
80 ARM_EXIDX_CMD_ADD_TO_VSP,
81 ARM_EXIDX_CMD_REG_POP,
82 ARM_EXIDX_CMD_REG_TO_SP,
83 ARM_EXIDX_CMD_VFP_POP,
84 ARM_EXIDX_CMD_WREG_POP,
85 ARM_EXIDX_CMD_WCGR_POP,
86 ARM_EXIDX_CMD_RESERVED,
87 ARM_EXIDX_CMD_REFUSED,
88 } extab_cmd_t;
90 struct exidx_entry {
91 uint32_t addr;
92 uint32_t data;
93 };
95 struct extab_data {
96 extab_cmd_t cmd;
97 uint32_t data;
98 };
100 enum extab_cmd_flags {
101 ARM_EXIDX_VFP_SHIFT_16 = 1 << 16,
102 ARM_EXIDX_VFP_FSTMD = 1 << 17, // distinguishes FSTMxxD from FSTMxxX
103 };
105 // Receives information from arm_ex_reader::ExceptionTableInfo
106 // and adds it to the SecMap object
107 // This is in effect the EXIDX summariser.
108 class ARMExToModule {
109 public:
110 ARMExToModule(SecMap* smap, void(*log)(const char*)) : smap_(smap)
111 , log_(log) { }
112 ~ARMExToModule() { }
113 void AddStackFrame(uintptr_t addr, size_t size);
114 int ImproveStackFrame(const struct extab_data* edata);
115 void DeleteStackFrame();
116 void SubmitStackFrame();
117 private:
118 SecMap* smap_;
119 LExpr vsp_; // Always appears to be of the form "sp + offset"
120 RuleSet curr_rules_; // Also holds the address range being summarised
121 // debugging message sink
122 void (*log_)(const char*);
123 int TranslateCmd(const struct extab_data* edata, LExpr& vsp);
124 };
127 // (derived from)
128 // memory_range.h: Define the google_breakpad::MemoryRange class, which
129 // is a lightweight wrapper with a pointer and a length to encapsulate
130 // a contiguous range of memory.
132 // A lightweight wrapper with a pointer and a length to encapsulate a
133 // contiguous range of memory. It provides helper methods for checked
134 // access of a subrange of the memory. Its implemementation does not
135 // allocate memory or call into libc functions, and is thus safer to use
136 // in a crashed environment.
137 class MemoryRange {
138 public:
140 MemoryRange(const void* data, size_t length) {
141 Set(data, length);
142 }
144 // Sets this memory range to point to |data| and its length to |length|.
145 void Set(const void* data, size_t length) {
146 data_ = reinterpret_cast<const uint8_t*>(data);
147 // Always set |length_| to zero if |data_| is NULL.
148 length_ = data ? length : 0;
149 }
151 // Returns true if this range covers a subrange of |sub_length| bytes
152 // at |sub_offset| bytes of this memory range, or false otherwise.
153 bool Covers(size_t sub_offset, size_t sub_length) const {
154 // The following checks verify that:
155 // 1. sub_offset is within [ 0 .. length_ - 1 ]
156 // 2. sub_offset + sub_length is within
157 // [ sub_offset .. length_ ]
158 return sub_offset < length_ &&
159 sub_offset + sub_length >= sub_offset &&
160 sub_offset + sub_length <= length_;
161 }
163 // Returns a pointer to the beginning of this memory range.
164 const uint8_t* data() const { return data_; }
166 // Returns the length, in bytes, of this memory range.
167 size_t length() const { return length_; }
169 private:
170 // Pointer to the beginning of this memory range.
171 const uint8_t* data_;
173 // Length, in bytes, of this memory range.
174 size_t length_;
175 };
178 // This class is a reader for ARM unwind information
179 // from .ARM.exidx and .ARM.extab sections.
180 class ExceptionTableInfo {
181 public:
182 ExceptionTableInfo(const char* exidx, size_t exidx_size,
183 const char* extab, size_t extab_size,
184 uint32_t text_last_svma,
185 lul::ARMExToModule* handler,
186 const char* mapping_addr,
187 uint32_t loading_addr,
188 uintptr_t text_bias,
189 void (*log)(const char*))
190 : mr_exidx_(lul::MemoryRange(exidx, exidx_size)),
191 mr_extab_(lul::MemoryRange(extab, extab_size)),
192 text_last_svma_(text_last_svma),
193 handler_(handler), mapping_addr_(mapping_addr),
194 loading_addr_(loading_addr),
195 text_bias_(text_bias),
196 log_(log) { }
198 ~ExceptionTableInfo() { }
200 // Parses the entries in .ARM.exidx and possibly
201 // in .ARM.extab tables, reports what we find to
202 // arm_ex_to_module::ARMExToModule.
203 void Start();
205 private:
206 lul::MemoryRange mr_exidx_;
207 lul::MemoryRange mr_extab_;
208 uint32_t text_last_svma_;
209 lul::ARMExToModule* handler_;
210 const char* mapping_addr_;
211 uint32_t loading_addr_;
212 uintptr_t text_bias_;
213 // debugging message sink
214 void (*log_)(const char*);
215 enum ExExtractResult {
216 ExSuccess, // success
217 ExInBufOverflow, // out-of-range while reading .exidx
218 ExOutBufOverflow, // output buffer is too small
219 ExCantUnwind, // this function is marked CANT_UNWIND
220 ExCantRepresent, // entry valid, but we can't represent it
221 ExInvalid // entry is invalid
222 };
223 ExExtractResult
224 ExtabEntryExtract(const struct lul::exidx_entry* entry,
225 uint8_t* buf, size_t buf_size,
226 /*OUT*/size_t* buf_used);
228 int ExtabEntryDecode(const uint8_t* buf, size_t buf_size);
229 };
231 } // namespace lul
233 #endif // LulExidxExt_h