toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/arm_ex_to_module.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,191 @@
     1.4 +
     1.5 +/* libunwind - a platform-independent unwind library
     1.6 +   Copyright 2011 Linaro Limited
     1.7 +
     1.8 +This file is part of libunwind.
     1.9 +
    1.10 +Permission is hereby granted, free of charge, to any person obtaining
    1.11 +a copy of this software and associated documentation files (the
    1.12 +"Software"), to deal in the Software without restriction, including
    1.13 +without limitation the rights to use, copy, modify, merge, publish,
    1.14 +distribute, sublicense, and/or sell copies of the Software, and to
    1.15 +permit persons to whom the Software is furnished to do so, subject to
    1.16 +the following conditions:
    1.17 +
    1.18 +The above copyright notice and this permission notice shall be
    1.19 +included in all copies or substantial portions of the Software.
    1.20 +
    1.21 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    1.22 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    1.23 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    1.24 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
    1.25 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
    1.26 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    1.27 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
    1.28 +
    1.29 +// Copyright (c) 2010 Google Inc.
    1.30 +// All rights reserved.
    1.31 +//
    1.32 +// Redistribution and use in source and binary forms, with or without
    1.33 +// modification, are permitted provided that the following conditions are
    1.34 +// met:
    1.35 +//
    1.36 +//     * Redistributions of source code must retain the above copyright
    1.37 +// notice, this list of conditions and the following disclaimer.
    1.38 +//     * Redistributions in binary form must reproduce the above
    1.39 +// copyright notice, this list of conditions and the following disclaimer
    1.40 +// in the documentation and/or other materials provided with the
    1.41 +// distribution.
    1.42 +//     * Neither the name of Google Inc. nor the names of its
    1.43 +// contributors may be used to endorse or promote products derived from
    1.44 +// this software without specific prior written permission.
    1.45 +//
    1.46 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.47 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.48 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.49 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.50 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.51 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.52 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.53 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.54 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.55 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.56 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.57 +
    1.58 +
    1.59 +// Derived from libunwind, with extensive modifications.
    1.60 +
    1.61 +#include "common/unique_string.h"
    1.62 +#include "common/arm_ex_to_module.h"
    1.63 +
    1.64 +#include <stdio.h>
    1.65 +#include <assert.h>
    1.66 +
    1.67 +// For big-picture comments on how the EXIDX reader works, 
    1.68 +// see arm_ex_reader.cc.
    1.69 +
    1.70 +#define ARM_EXBUF_START(x) (((x) >> 4) & 0x0f)
    1.71 +#define ARM_EXBUF_COUNT(x) ((x) & 0x0f)
    1.72 +#define ARM_EXBUF_END(x)   (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
    1.73 +
    1.74 +using google_breakpad::ustr__pc;
    1.75 +using google_breakpad::ustr__lr;
    1.76 +using google_breakpad::ustr__sp;
    1.77 +using google_breakpad::ustr__ZDra;
    1.78 +using google_breakpad::ustr__ZDcfa;
    1.79 +using google_breakpad::Module;
    1.80 +using google_breakpad::ToUniqueString;
    1.81 +using google_breakpad::UniqueString;
    1.82 +
    1.83 +namespace arm_ex_to_module {
    1.84 +
    1.85 +// Translate command from extab_data to command for Module.
    1.86 +int ARMExToModule::TranslateCmd(const struct extab_data* edata,
    1.87 +                                Module::StackFrameEntry* entry,
    1.88 +                                Module::Expr& vsp) {
    1.89 +  int ret = 0;
    1.90 +  switch (edata->cmd) {
    1.91 +    case ARM_EXIDX_CMD_FINISH:
    1.92 +      /* Copy LR to PC if there isn't currently a rule for PC in force. */
    1.93 +      if (entry->initial_rules.find(ustr__pc())
    1.94 +          == entry->initial_rules.end()) {
    1.95 +        if (entry->initial_rules.find(ustr__lr())
    1.96 +            == entry->initial_rules.end()) {
    1.97 +          entry->initial_rules[ustr__pc()] = Module::Expr(ustr__lr(),
    1.98 +                                                          0, false); // "lr"
    1.99 +        } else {
   1.100 +          entry->initial_rules[ustr__pc()] = entry->initial_rules[ustr__lr()];
   1.101 +        }
   1.102 +      }
   1.103 +      break;
   1.104 +    case ARM_EXIDX_CMD_SUB_FROM_VSP:
   1.105 +      vsp = vsp.add_delta(- static_cast<long>(edata->data));
   1.106 +      break;
   1.107 +    case ARM_EXIDX_CMD_ADD_TO_VSP:
   1.108 +      vsp = vsp.add_delta(static_cast<long>(edata->data));
   1.109 +      break;
   1.110 +    case ARM_EXIDX_CMD_REG_POP:
   1.111 +      for (unsigned int i = 0; i < 16; i++) {
   1.112 +        if (edata->data & (1 << i)) {
   1.113 +          entry->initial_rules[ToUniqueString(regnames[i])] = vsp.deref();
   1.114 +          vsp = vsp.add_delta(4);
   1.115 +        }
   1.116 +      }
   1.117 +      /* Set cfa in case the SP got popped. */
   1.118 +      if (edata->data & (1 << 13)) {
   1.119 +        vsp = entry->initial_rules[ustr__sp()];
   1.120 +      }
   1.121 +      break;
   1.122 +    case ARM_EXIDX_CMD_REG_TO_SP: {
   1.123 +      assert (edata->data < 16);
   1.124 +      const char* const regname = regnames[edata->data];
   1.125 +      const UniqueString* regname_us = ToUniqueString(regname);
   1.126 +      if (entry->initial_rules.find(regname_us) == entry->initial_rules.end()) {
   1.127 +        entry->initial_rules[ustr__sp()] = Module::Expr(regname_us,
   1.128 +                                                        0, false); // "regname"
   1.129 +      } else {
   1.130 +        entry->initial_rules[ustr__sp()] = entry->initial_rules[regname_us];
   1.131 +      }
   1.132 +      vsp = entry->initial_rules[ustr__sp()];
   1.133 +      break;
   1.134 +    }
   1.135 +    case ARM_EXIDX_CMD_VFP_POP:
   1.136 +      /* Don't recover VFP registers, but be sure to adjust the stack
   1.137 +         pointer. */
   1.138 +      for (unsigned int i = ARM_EXBUF_START(edata->data);
   1.139 +           i <= ARM_EXBUF_END(edata->data); i++) {
   1.140 +        vsp = vsp.add_delta(8);
   1.141 +      }
   1.142 +      if (!(edata->data & ARM_EXIDX_VFP_FSTMD)) {
   1.143 +        vsp = vsp.add_delta(4);
   1.144 +      }
   1.145 +      break;
   1.146 +    case ARM_EXIDX_CMD_WREG_POP:
   1.147 +      for (unsigned int i = ARM_EXBUF_START(edata->data);
   1.148 +           i <= ARM_EXBUF_END(edata->data); i++) {
   1.149 +        vsp = vsp.add_delta(8);
   1.150 +      }
   1.151 +      break;
   1.152 +    case ARM_EXIDX_CMD_WCGR_POP:
   1.153 +      // Pop wCGR registers under mask {wCGR3,2,1,0}, hence "i < 4"
   1.154 +      for (unsigned int i = 0; i < 4; i++) {
   1.155 +        if (edata->data & (1 << i)) {
   1.156 +          vsp = vsp.add_delta(4);
   1.157 +        }
   1.158 +      }
   1.159 +      break;
   1.160 +    case ARM_EXIDX_CMD_REFUSED:
   1.161 +    case ARM_EXIDX_CMD_RESERVED:
   1.162 +      ret = -1;
   1.163 +      break;
   1.164 +  }
   1.165 +  return ret;
   1.166 +}
   1.167 +
   1.168 +void ARMExToModule::AddStackFrame(uintptr_t addr, size_t size) {
   1.169 +  stack_frame_entry_ = new Module::StackFrameEntry;
   1.170 +  stack_frame_entry_->address = addr;
   1.171 +  stack_frame_entry_->size = size;
   1.172 +  Module::Expr sp_expr = Module::Expr(ustr__sp(), 0, false); // "sp"
   1.173 +  stack_frame_entry_->initial_rules[ustr__ZDcfa()] = sp_expr; // ".cfa"
   1.174 +  vsp_ = sp_expr;
   1.175 +}
   1.176 +
   1.177 +int ARMExToModule::ImproveStackFrame(const struct extab_data* edata) {
   1.178 +  return TranslateCmd(edata, stack_frame_entry_, vsp_) ;
   1.179 +}
   1.180 +
   1.181 +void ARMExToModule::DeleteStackFrame() {
   1.182 +  delete stack_frame_entry_;
   1.183 +}
   1.184 +
   1.185 +void ARMExToModule::SubmitStackFrame() {
   1.186 +  // return address always winds up in pc
   1.187 +  stack_frame_entry_->initial_rules[ustr__ZDra()] // ".ra"
   1.188 +    = stack_frame_entry_->initial_rules[ustr__pc()];
   1.189 +  // the final value of vsp is the new value of sp
   1.190 +  stack_frame_entry_->initial_rules[ustr__sp()] = vsp_;
   1.191 +  module_->AddStackFrameEntry(stack_frame_entry_);
   1.192 +}
   1.193 +
   1.194 +} // namespace arm_ex_to_module

mercurial