tools/profiler/LulExidxExt.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial