toolkit/crashreporter/google-breakpad/src/common/dwarf_cfi_to_module.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 // -*- mode: c++ -*-
michael@0 2
michael@0 3 // Copyright (c) 2010, Google Inc.
michael@0 4 // All rights reserved.
michael@0 5 //
michael@0 6 // Redistribution and use in source and binary forms, with or without
michael@0 7 // modification, are permitted provided that the following conditions are
michael@0 8 // met:
michael@0 9 //
michael@0 10 // * Redistributions of source code must retain the above copyright
michael@0 11 // notice, this list of conditions and the following disclaimer.
michael@0 12 // * Redistributions in binary form must reproduce the above
michael@0 13 // copyright notice, this list of conditions and the following disclaimer
michael@0 14 // in the documentation and/or other materials provided with the
michael@0 15 // distribution.
michael@0 16 // * Neither the name of Google Inc. nor the names of its
michael@0 17 // contributors may be used to endorse or promote products derived from
michael@0 18 // this software without specific prior written permission.
michael@0 19 //
michael@0 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 31
michael@0 32 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
michael@0 33
michael@0 34 // dwarf_cfi_to_module.h: Define the DwarfCFIToModule class, which
michael@0 35 // accepts parsed DWARF call frame info and adds it to a
michael@0 36 // google_breakpad::Module object, which can write that information to
michael@0 37 // a Breakpad symbol file.
michael@0 38
michael@0 39 #ifndef COMMON_LINUX_DWARF_CFI_TO_MODULE_H
michael@0 40 #define COMMON_LINUX_DWARF_CFI_TO_MODULE_H
michael@0 41
michael@0 42 #include <assert.h>
michael@0 43 #include <stdio.h>
michael@0 44
michael@0 45 #include <set>
michael@0 46 #include <string>
michael@0 47 #include <vector>
michael@0 48
michael@0 49 #include "common/module.h"
michael@0 50 #include "common/dwarf/dwarf2reader.h"
michael@0 51 #include "common/using_std_string.h"
michael@0 52 #include "common/unique_string.h"
michael@0 53
michael@0 54 namespace google_breakpad {
michael@0 55
michael@0 56 using dwarf2reader::CallFrameInfo;
michael@0 57 using google_breakpad::Module;
michael@0 58 using std::set;
michael@0 59 using std::vector;
michael@0 60
michael@0 61 // A class that accepts parsed call frame information from the DWARF
michael@0 62 // CFI parser and populates a google_breakpad::Module object with the
michael@0 63 // contents.
michael@0 64 class DwarfCFIToModule: public CallFrameInfo::Handler {
michael@0 65 public:
michael@0 66
michael@0 67 // DwarfCFIToModule uses an instance of this class to report errors
michael@0 68 // detected while converting DWARF CFI to Breakpad STACK CFI records.
michael@0 69 class Reporter {
michael@0 70 public:
michael@0 71 // Create a reporter that writes messages to the standard error
michael@0 72 // stream. FILE is the name of the file we're processing, and
michael@0 73 // SECTION is the name of the section within that file that we're
michael@0 74 // looking at (.debug_frame, .eh_frame, etc.).
michael@0 75 Reporter(const string &file, const string &section)
michael@0 76 : file_(file), section_(section) { }
michael@0 77 virtual ~Reporter() { }
michael@0 78
michael@0 79 // The DWARF CFI entry at OFFSET cites register REG, but REG is not
michael@0 80 // covered by the vector of register names passed to the
michael@0 81 // DwarfCFIToModule constructor, nor does it match the return
michael@0 82 // address column number for this entry.
michael@0 83 virtual void UnnamedRegister(size_t offset, int reg);
michael@0 84
michael@0 85 // The DWARF CFI entry at OFFSET says that REG is undefined, but the
michael@0 86 // Breakpad symbol file format cannot express this.
michael@0 87 virtual void UndefinedNotSupported(size_t offset,
michael@0 88 const UniqueString* reg);
michael@0 89
michael@0 90 // The DWARF CFI entry at OFFSET says that REG uses a DWARF
michael@0 91 // expression to find its value, but DwarfCFIToModule is not
michael@0 92 // capable of translating DWARF expressions to Breakpad postfix
michael@0 93 // expressions.
michael@0 94 virtual void ExpressionsNotSupported(size_t offset,
michael@0 95 const UniqueString* reg);
michael@0 96
michael@0 97 protected:
michael@0 98 string file_, section_;
michael@0 99 };
michael@0 100
michael@0 101 // Register name tables. If TABLE is a vector returned by one of these
michael@0 102 // functions, then TABLE[R] is the name of the register numbered R in
michael@0 103 // DWARF call frame information.
michael@0 104 class RegisterNames {
michael@0 105 public:
michael@0 106 // Intel's "x86" or IA-32.
michael@0 107 static vector<const UniqueString*> I386();
michael@0 108
michael@0 109 // AMD x86_64, AMD64, Intel EM64T, or Intel 64
michael@0 110 static vector<const UniqueString*> X86_64();
michael@0 111
michael@0 112 // ARM.
michael@0 113 static vector<const UniqueString*> ARM();
michael@0 114
michael@0 115 private:
michael@0 116 // Given STRINGS, an array of C strings with SIZE elements, return an
michael@0 117 // equivalent vector<string>.
michael@0 118 static vector<const UniqueString*> MakeVector(const char * const *strings,
michael@0 119 size_t size);
michael@0 120 };
michael@0 121
michael@0 122 // Create a handler for the dwarf2reader::CallFrameInfo parser that
michael@0 123 // records the stack unwinding information it receives in MODULE.
michael@0 124 //
michael@0 125 // Use REGISTER_NAMES[I] as the name of register number I; *this
michael@0 126 // keeps a reference to the vector, so the vector should remain
michael@0 127 // alive for as long as the DwarfCFIToModule does.
michael@0 128 //
michael@0 129 // Use REPORTER for reporting problems encountered in the conversion
michael@0 130 // process.
michael@0 131 DwarfCFIToModule(Module *module,
michael@0 132 const vector<const UniqueString*> &register_names,
michael@0 133 Reporter *reporter)
michael@0 134 : module_(module), register_names_(register_names), reporter_(reporter),
michael@0 135 entry_(NULL), return_address_(-1) {
michael@0 136 }
michael@0 137 virtual ~DwarfCFIToModule() { delete entry_; }
michael@0 138
michael@0 139 virtual bool Entry(size_t offset, uint64 address, uint64 length,
michael@0 140 uint8 version, const string &augmentation,
michael@0 141 unsigned return_address);
michael@0 142 virtual bool UndefinedRule(uint64 address, int reg);
michael@0 143 virtual bool SameValueRule(uint64 address, int reg);
michael@0 144 virtual bool OffsetRule(uint64 address, int reg,
michael@0 145 int base_register, long offset);
michael@0 146 virtual bool ValOffsetRule(uint64 address, int reg,
michael@0 147 int base_register, long offset);
michael@0 148 virtual bool RegisterRule(uint64 address, int reg, int base_register);
michael@0 149 virtual bool ExpressionRule(uint64 address, int reg,
michael@0 150 const string &expression);
michael@0 151 virtual bool ValExpressionRule(uint64 address, int reg,
michael@0 152 const string &expression);
michael@0 153 virtual bool End();
michael@0 154
michael@0 155 private:
michael@0 156 // Return the name to use for register REG.
michael@0 157 const UniqueString* RegisterName(int i);
michael@0 158
michael@0 159 // Record RULE for register REG at ADDRESS.
michael@0 160 void Record(Module::Address address, int reg, const Module::Expr &rule);
michael@0 161
michael@0 162 // The module to which we should add entries.
michael@0 163 Module *module_;
michael@0 164
michael@0 165 // Map from register numbers to register names.
michael@0 166 const vector<const UniqueString*> &register_names_;
michael@0 167
michael@0 168 // The reporter to use to report problems.
michael@0 169 Reporter *reporter_;
michael@0 170
michael@0 171 // The current entry we're constructing.
michael@0 172 Module::StackFrameEntry *entry_;
michael@0 173
michael@0 174 // The section offset of the current frame description entry, for
michael@0 175 // use in error messages.
michael@0 176 size_t entry_offset_;
michael@0 177
michael@0 178 // The return address column for that entry.
michael@0 179 unsigned return_address_;
michael@0 180 };
michael@0 181
michael@0 182 } // namespace google_breakpad
michael@0 183
michael@0 184 #endif // COMMON_LINUX_DWARF_CFI_TO_MODULE_H

mercurial