1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,184 @@ 1.4 +// -*- mode: c++ -*- 1.5 + 1.6 +// Copyright (c) 2010, Google Inc. 1.7 +// All rights reserved. 1.8 +// 1.9 +// Redistribution and use in source and binary forms, with or without 1.10 +// modification, are permitted provided that the following conditions are 1.11 +// met: 1.12 +// 1.13 +// * Redistributions of source code must retain the above copyright 1.14 +// notice, this list of conditions and the following disclaimer. 1.15 +// * Redistributions in binary form must reproduce the above 1.16 +// copyright notice, this list of conditions and the following disclaimer 1.17 +// in the documentation and/or other materials provided with the 1.18 +// distribution. 1.19 +// * Neither the name of Google Inc. nor the names of its 1.20 +// contributors may be used to endorse or promote products derived from 1.21 +// this software without specific prior written permission. 1.22 +// 1.23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.24 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.25 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.26 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.27 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.28 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.29 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.30 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.31 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.32 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.33 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.34 + 1.35 +// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 1.36 + 1.37 +// dwarf_cfi_to_module.h: Define the DwarfCFIToModule class, which 1.38 +// accepts parsed DWARF call frame info and adds it to a 1.39 +// google_breakpad::Module object, which can write that information to 1.40 +// a Breakpad symbol file. 1.41 + 1.42 +#ifndef COMMON_LINUX_DWARF_CFI_TO_MODULE_H 1.43 +#define COMMON_LINUX_DWARF_CFI_TO_MODULE_H 1.44 + 1.45 +#include <assert.h> 1.46 +#include <stdio.h> 1.47 + 1.48 +#include <set> 1.49 +#include <string> 1.50 +#include <vector> 1.51 + 1.52 +#include "common/module.h" 1.53 +#include "common/dwarf/dwarf2reader.h" 1.54 +#include "common/using_std_string.h" 1.55 +#include "common/unique_string.h" 1.56 + 1.57 +namespace google_breakpad { 1.58 + 1.59 +using dwarf2reader::CallFrameInfo; 1.60 +using google_breakpad::Module; 1.61 +using std::set; 1.62 +using std::vector; 1.63 + 1.64 +// A class that accepts parsed call frame information from the DWARF 1.65 +// CFI parser and populates a google_breakpad::Module object with the 1.66 +// contents. 1.67 +class DwarfCFIToModule: public CallFrameInfo::Handler { 1.68 + public: 1.69 + 1.70 + // DwarfCFIToModule uses an instance of this class to report errors 1.71 + // detected while converting DWARF CFI to Breakpad STACK CFI records. 1.72 + class Reporter { 1.73 + public: 1.74 + // Create a reporter that writes messages to the standard error 1.75 + // stream. FILE is the name of the file we're processing, and 1.76 + // SECTION is the name of the section within that file that we're 1.77 + // looking at (.debug_frame, .eh_frame, etc.). 1.78 + Reporter(const string &file, const string §ion) 1.79 + : file_(file), section_(section) { } 1.80 + virtual ~Reporter() { } 1.81 + 1.82 + // The DWARF CFI entry at OFFSET cites register REG, but REG is not 1.83 + // covered by the vector of register names passed to the 1.84 + // DwarfCFIToModule constructor, nor does it match the return 1.85 + // address column number for this entry. 1.86 + virtual void UnnamedRegister(size_t offset, int reg); 1.87 + 1.88 + // The DWARF CFI entry at OFFSET says that REG is undefined, but the 1.89 + // Breakpad symbol file format cannot express this. 1.90 + virtual void UndefinedNotSupported(size_t offset, 1.91 + const UniqueString* reg); 1.92 + 1.93 + // The DWARF CFI entry at OFFSET says that REG uses a DWARF 1.94 + // expression to find its value, but DwarfCFIToModule is not 1.95 + // capable of translating DWARF expressions to Breakpad postfix 1.96 + // expressions. 1.97 + virtual void ExpressionsNotSupported(size_t offset, 1.98 + const UniqueString* reg); 1.99 + 1.100 + protected: 1.101 + string file_, section_; 1.102 + }; 1.103 + 1.104 + // Register name tables. If TABLE is a vector returned by one of these 1.105 + // functions, then TABLE[R] is the name of the register numbered R in 1.106 + // DWARF call frame information. 1.107 + class RegisterNames { 1.108 + public: 1.109 + // Intel's "x86" or IA-32. 1.110 + static vector<const UniqueString*> I386(); 1.111 + 1.112 + // AMD x86_64, AMD64, Intel EM64T, or Intel 64 1.113 + static vector<const UniqueString*> X86_64(); 1.114 + 1.115 + // ARM. 1.116 + static vector<const UniqueString*> ARM(); 1.117 + 1.118 + private: 1.119 + // Given STRINGS, an array of C strings with SIZE elements, return an 1.120 + // equivalent vector<string>. 1.121 + static vector<const UniqueString*> MakeVector(const char * const *strings, 1.122 + size_t size); 1.123 + }; 1.124 + 1.125 + // Create a handler for the dwarf2reader::CallFrameInfo parser that 1.126 + // records the stack unwinding information it receives in MODULE. 1.127 + // 1.128 + // Use REGISTER_NAMES[I] as the name of register number I; *this 1.129 + // keeps a reference to the vector, so the vector should remain 1.130 + // alive for as long as the DwarfCFIToModule does. 1.131 + // 1.132 + // Use REPORTER for reporting problems encountered in the conversion 1.133 + // process. 1.134 + DwarfCFIToModule(Module *module, 1.135 + const vector<const UniqueString*> ®ister_names, 1.136 + Reporter *reporter) 1.137 + : module_(module), register_names_(register_names), reporter_(reporter), 1.138 + entry_(NULL), return_address_(-1) { 1.139 + } 1.140 + virtual ~DwarfCFIToModule() { delete entry_; } 1.141 + 1.142 + virtual bool Entry(size_t offset, uint64 address, uint64 length, 1.143 + uint8 version, const string &augmentation, 1.144 + unsigned return_address); 1.145 + virtual bool UndefinedRule(uint64 address, int reg); 1.146 + virtual bool SameValueRule(uint64 address, int reg); 1.147 + virtual bool OffsetRule(uint64 address, int reg, 1.148 + int base_register, long offset); 1.149 + virtual bool ValOffsetRule(uint64 address, int reg, 1.150 + int base_register, long offset); 1.151 + virtual bool RegisterRule(uint64 address, int reg, int base_register); 1.152 + virtual bool ExpressionRule(uint64 address, int reg, 1.153 + const string &expression); 1.154 + virtual bool ValExpressionRule(uint64 address, int reg, 1.155 + const string &expression); 1.156 + virtual bool End(); 1.157 + 1.158 + private: 1.159 + // Return the name to use for register REG. 1.160 + const UniqueString* RegisterName(int i); 1.161 + 1.162 + // Record RULE for register REG at ADDRESS. 1.163 + void Record(Module::Address address, int reg, const Module::Expr &rule); 1.164 + 1.165 + // The module to which we should add entries. 1.166 + Module *module_; 1.167 + 1.168 + // Map from register numbers to register names. 1.169 + const vector<const UniqueString*> ®ister_names_; 1.170 + 1.171 + // The reporter to use to report problems. 1.172 + Reporter *reporter_; 1.173 + 1.174 + // The current entry we're constructing. 1.175 + Module::StackFrameEntry *entry_; 1.176 + 1.177 + // The section offset of the current frame description entry, for 1.178 + // use in error messages. 1.179 + size_t entry_offset_; 1.180 + 1.181 + // The return address column for that entry. 1.182 + unsigned return_address_; 1.183 +}; 1.184 + 1.185 +} // namespace google_breakpad 1.186 + 1.187 +#endif // COMMON_LINUX_DWARF_CFI_TO_MODULE_H