tools/profiler/LulExidxExt.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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

mercurial