1cf55ca5b5cb673677a8493aff1424e1b83211c1ajimblandy// -*- mode: c++ -*- 2cf55ca5b5cb673677a8493aff1424e1b83211c1ajimblandy 383e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc. 4eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// All rights reserved. 5eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// 6eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// Redistribution and use in source and binary forms, with or without 7eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// modification, are permitted provided that the following conditions are 8eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// met: 9eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// 10eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// * Redistributions of source code must retain the above copyright 11eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// notice, this list of conditions and the following disclaimer. 12eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// * Redistributions in binary form must reproduce the above 13eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// copyright notice, this list of conditions and the following disclaimer 14eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// in the documentation and/or other materials provided with the 15eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// distribution. 16eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// * Neither the name of Google Inc. nor the names of its 17eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// contributors may be used to endorse or promote products derived from 18eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// this software without specific prior written permission. 19eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// 20eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 32c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 33c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy 34c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// module.h: Define google_breakpad::Module. A Module holds debugging 35c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// information, and can write that information out as a Breakpad 36c50e7c604cd1b12bba9421b0a95357fc942ecd7cjimblandy// symbol file. 37eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 38eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#ifndef COMMON_LINUX_MODULE_H__ 39eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#define COMMON_LINUX_MODULE_H__ 40eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 413ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include <iostream> 42eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#include <map> 430dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org#include <set> 44eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#include <string> 45eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#include <vector> 46eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 4706e17f8d31507e3993609a9495dcaac02d96b4adted.mielczarek@gmail.com#include "common/symbol_data.h" 484e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h" 49eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#include "google_breakpad/common/breakpad_types.h" 50eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 51eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.comnamespace google_breakpad { 52eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 530dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.orgusing std::set; 54eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.comusing std::vector; 55eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.comusing std::map; 56eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 57eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// A Module represents the contents of a module, and supports methods 58eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// for adding information produced by parsing STABS or DWARF data 59eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// --- possibly both from the same file --- and then writing out the 60eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com// unified contents as a Breakpad-format symbol file. 61eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.comclass Module { 62eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com public: 63eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The type of addresses and sizes in a symbol table. 646162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com typedef uint64_t Address; 65eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct File; 66eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct Function; 67eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct Line; 68bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek struct Extern; 69eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 70eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Addresses appearing in File, Function, and Line structures are 71eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // absolute, not relative to the the module's load address. That 72eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // is, if the module were loaded at its nominal load address, the 73eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // addresses would be correct. 74eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 75eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // A source file. 76eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct File { 776105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org explicit File(const string &name_input) : name(name_input), source_id(0) {} 786105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org 79eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The name of the source file. 806105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org const string name; 81eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 82eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The file's source id. The Write member function clears this 83eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // field and assigns source ids a fresh, so any value placed here 84eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // before calling Write will be lost. 853e60d65111607f401461ff15981a463cde8f744ajimblandy int source_id; 86eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com }; 87eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 88eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // A function. 89eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct Function { 906105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org Function(const string &name_input, const Address &address_input) : 916105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org name(name_input), address(address_input), size(0), parameter_size(0) {} 926105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org 93eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // For sorting by address. (Not style-guide compliant, but it's 94eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // stupid not to put this in the struct.) 95eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com static bool CompareByAddress(const Function *x, const Function *y) { 963e60d65111607f401461ff15981a463cde8f744ajimblandy return x->address < y->address; 97eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com } 98eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 99eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The function's name. 1006105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org const string name; 1010dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org 102eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The start address and length of the function's code. 1036105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org const Address address; 1046105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org Address size; 105eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 106eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The function's parameter size. 1073e60d65111607f401461ff15981a463cde8f744ajimblandy Address parameter_size; 108eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 109eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Source lines belonging to this function, sorted by increasing 110eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // address. 1113e60d65111607f401461ff15981a463cde8f744ajimblandy vector<Line> lines; 112eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com }; 113eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 114eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // A source line. 115eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct Line { 116eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // For sorting by address. (Not style-guide compliant, but it's 117eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // stupid not to put this in the struct.) 118eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com static bool CompareByAddress(const Module::Line &x, const Module::Line &y) { 1193e60d65111607f401461ff15981a463cde8f744ajimblandy return x.address < y.address; 120eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com } 121eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 1223e60d65111607f401461ff15981a463cde8f744ajimblandy Address address, size; // The address and size of the line's code. 1233e60d65111607f401461ff15981a463cde8f744ajimblandy File *file; // The source file. 1243e60d65111607f401461ff15981a463cde8f744ajimblandy int number; // The source line number. 125eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com }; 1263e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 127bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // An exported symbol. 128bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek struct Extern { 1296105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org explicit Extern(const Address &address_input) : address(address_input) {} 1306105ae42dc0a63fe651b050244c9bbc6a549bfc5erikchen@chromium.org const Address address; 131bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek string name; 132bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek }; 133bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 1343e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // A map from register names to postfix expressions that recover 1353e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // their their values. This can represent a complete set of rules to 1363e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // follow at some address, or a set of changes to be applied to an 1373e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // extant set of rules. 1383e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy typedef map<string, string> RuleMap; 1393e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1403e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // A map from addresses to RuleMaps, representing changes that take 1413e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // effect at given addresses. 1423e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy typedef map<Address, RuleMap> RuleChangeMap; 1430dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org 1443e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // A range of 'STACK CFI' stack walking information. An instance of 1453e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // this structure corresponds to a 'STACK CFI INIT' record and the 1463e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // subsequent 'STACK CFI' records that fall within its range. 1473e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy struct StackFrameEntry { 1483e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The starting address and number of bytes of machine code this 1493e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // entry covers. 1503e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy Address address, size; 1513e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1523e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The initial register recovery rules, in force at the starting 1533e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // address. 1543e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy RuleMap initial_rules; 1553e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 1563e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // A map from addresses to rule changes. To find the rules in 1573e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // force at a given address, start with initial_rules, and then 1583e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // apply the changes given in this map for all addresses up to and 1593e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // including the address you're interested in. 1603e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy RuleChangeMap rule_changes; 1613e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy }; 1620dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org 1630dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org struct FunctionCompare { 1640dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org bool operator() (const Function *lhs, 1650dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org const Function *rhs) const { 1660dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org if (lhs->address == rhs->address) 1670dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org return lhs->name < rhs->name; 1680dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org return lhs->address < rhs->address; 1690dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org } 1700dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org }; 1710dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org 172bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek struct ExternCompare { 173bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek bool operator() (const Extern *lhs, 174bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek const Extern *rhs) const { 175bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek return lhs->address < rhs->address; 176bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek } 177bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek }; 178bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 179eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Create a new module with the given name, operating system, 180eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // architecture, and ID string. 1810dd6c95b3fcf0bef0a473901e47eb4c23fb30f5bthestig@chromium.org Module(const string &name, const string &os, const string &architecture, 182eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com const string &id); 183eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com ~Module(); 184eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 185eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Set the module's load address to LOAD_ADDRESS; addresses given 186eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // for functions and lines will be written to the Breakpad symbol 187eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // file as offsets from this address. Construction initializes this 188eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // module's load address to zero: addresses written to the symbol 18925b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // file will be the same as they appear in the Function, Line, and 19025b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // StackFrameEntry structures. 19125b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // 19225b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // Note that this member function has no effect on addresses stored 19325b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // in the data added to this module; the Write member function 19425b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // simply subtracts off the load address from addresses before it 19525b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // prints them. Only the last load address given before calling 19625b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy // Write is used. 197eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com void SetLoadAddress(Address load_address); 198eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 199fd18beeb5c817aa3ecdb21caceee8e6ce08c6ab3jimblandy // Add FUNCTION to the module. FUNCTION's name must not be empty. 20004683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // This module owns all Function objects added with this function: 20104683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // destroying the module destroys them as well. 202eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com void AddFunction(Function *function); 203eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 204eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Add all the functions in [BEGIN,END) to the module. 20504683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // This module owns all Function objects added with this function: 20604683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // destroying the module destroys them as well. 207eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com void AddFunctions(vector<Function *>::iterator begin, 208eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com vector<Function *>::iterator end); 209eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 2103e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Add STACK_FRAME_ENTRY to the module. 2113e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // This module owns all StackFrameEntry objects added with this 2123e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // function: destroying the module destroys them as well. 2133e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy void AddStackFrameEntry(StackFrameEntry *stack_frame_entry); 2143e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 215bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // Add PUBLIC to the module. 216bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // This module owns all Extern objects added with this function: 217bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // destroying the module destroys them as well. 218bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek void AddExtern(Extern *ext); 219bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 22004683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // If this module has a file named NAME, return a pointer to it. If 221d4a212a099b5c658a7e8a9b9df1dd6ff62e2b470jimblandy@gmail.com // it has none, then create one and return a pointer to the new 22204683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // file. This module owns all File objects created using these 22304683062456ed17ca4e1b890ec8a5e160287eaf3jimblandy // functions; destroying the module destroys them as well. 224eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com File *FindFile(const string &name); 225eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com File *FindFile(const char *name); 226eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 22752cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // If this module has a file named NAME, return a pointer to it. 22852cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Otherwise, return NULL. 22952cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy File *FindExistingFile(const string &name); 23052cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy 23152cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Insert pointers to the functions added to this module at I in 2323e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // VEC. The pointed-to Functions are still owned by this module. 2333e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // (Since this is effectively a copy of the function list, this is 2343e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // mostly useful for testing; other uses should probably get a more 2353e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // appropriate interface.) 23652cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy void GetFunctions(vector<Function *> *vec, vector<Function *>::iterator i); 23752cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy 238bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // Insert pointers to the externs added to this module at I in 239bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // VEC. The pointed-to Externs are still owned by this module. 240bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // (Since this is effectively a copy of the extern list, this is 241bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // mostly useful for testing; other uses should probably get a more 242bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // appropriate interface.) 243bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek void GetExterns(vector<Extern *> *vec, vector<Extern *>::iterator i); 244bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 24552cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Clear VEC and fill it with pointers to the Files added to this 2463e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // module, sorted by name. The pointed-to Files are still owned by 2473e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // this module. (Since this is effectively a copy of the file list, 2483e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // this is mostly useful for testing; other uses should probably get 2493e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // a more appropriate interface.) 25052cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy void GetFiles(vector<File *> *vec); 25152cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy 2523e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Clear VEC and fill it with pointers to the StackFrameEntry 2533e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // objects that have been added to this module. (Since this is 2543e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // effectively a copy of the stack frame entry list, this is mostly 2553e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // useful for testing; other uses should probably get 2563e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // a more appropriate interface.) 257e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org void GetStackFrameEntries(vector<StackFrameEntry *> *vec) const; 2583e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 25952cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Find those files in this module that are actually referred to by 26052cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // functions' line number data, and assign them source id numbers. 26152cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Set the source id numbers for all other files --- unused by the 26252cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // source line data --- to -1. We do this before writing out the 26352cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // symbol file, at which point we omit any unused files. 26452cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy void AssignSourceIds(); 26552cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy 26652cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // Call AssignSourceIds, and write this module to STREAM in the 26752cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // breakpad symbol format. Return true if all goes well, or false if 26852cb2c6f4235dfaa3760ef37fe7082e9e99b0ebdjimblandy // an error occurs. This method writes out: 269d4a212a099b5c658a7e8a9b9df1dd6ff62e2b470jimblandy@gmail.com // - a header based on the values given to the constructor, 27006e17f8d31507e3993609a9495dcaac02d96b4adted.mielczarek@gmail.com // If symbol_data is not ONLY_CFI then: 2718d54c7509234e9a4918046c12dcb138489f06990thestig@chromium.org // - the source files added via FindFile, 2728d54c7509234e9a4918046c12dcb138489f06990thestig@chromium.org // - the functions added via AddFunctions, each with its lines, 2738d54c7509234e9a4918046c12dcb138489f06990thestig@chromium.org // - all public records, 27406e17f8d31507e3993609a9495dcaac02d96b4adted.mielczarek@gmail.com // If symbol_data is not NO_CFI then: 27506e17f8d31507e3993609a9495dcaac02d96b4adted.mielczarek@gmail.com // - all CFI records. 276d4a212a099b5c658a7e8a9b9df1dd6ff62e2b470jimblandy@gmail.com // Addresses in the output are all relative to the load address 277d4a212a099b5c658a7e8a9b9df1dd6ff62e2b470jimblandy@gmail.com // established by SetLoadAddress. 27806e17f8d31507e3993609a9495dcaac02d96b4adted.mielczarek@gmail.com bool Write(std::ostream &stream, SymbolData symbol_data); 279eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 280e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org string name() const { return name_; } 281e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org string os() const { return os_; } 282e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org string architecture() const { return architecture_; } 283e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org string identifier() const { return id_; } 284e6d9e3c9ded44086b8648d633ab0676adc659bd5rsesek@chromium.org 28525b512d64dc9ec959d646151cf0cdc403ea0c335jimblandy private: 286eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Report an error that has occurred writing the symbol file, using 287eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // errno to find the appropriate cause. Return false. 288eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com static bool ReportError(); 289eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 2903e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI' 2913e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // records, without a final newline. Return true if all goes well; 2923e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // if an error occurs, return false, and leave errno set. 2933ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek static bool WriteRuleMap(const RuleMap &rule_map, std::ostream &stream); 2943e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 295eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Module header entries. 296eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com string name_, os_, architecture_, id_; 297eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 298eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The module's nominal load address. Addresses for functions and 299eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // lines are absolute, assuming the module is loaded at this 300eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // address. 301eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com Address load_address_; 302eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 303eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // Relation for maps whose keys are strings shared with some other 304eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // structure. 305eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com struct CompareStringPtrs { 306fae8ab29eecce4508c3a563a9bcd9c489e53fd71ted.mielczarek@gmail.com bool operator()(const string *x, const string *y) const { return *x < *y; } 307eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com }; 308eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 309eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // A map from filenames to File structures. The map's keys are 310eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // pointers to the Files' names. 311eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com typedef map<const string *, File *, CompareStringPtrs> FileByNameMap; 312bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 313bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // A set containing Function structures, sorted by address. 314a2d5da4831bf53acd23cd7bc6e08818f4d02efffdmaclach typedef set<Function *, FunctionCompare> FunctionSet; 315eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 316bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // A set containing Extern structures, sorted by address. 317bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek typedef set<Extern *, ExternCompare> ExternSet; 318bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 319eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // The module owns all the files and functions that have been added 320eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // to it; destroying the module frees the Files and Functions these 321eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com // point to. 322a2d5da4831bf53acd23cd7bc6e08818f4d02efffdmaclach FileByNameMap files_; // This module's source files. 3234ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach FunctionSet functions_; // This module's functions. 3243e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy 3253e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // The module owns all the call frame info entries that have been 3263e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy // added to it. 3273e768ed9c01a244cdb1bc0d6aec34fb25821fbccjimblandy vector<StackFrameEntry *> stack_frame_entries_; 328bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek 329bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // The module owns all the externs that have been added to it; 330bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek // destroying the module frees the Externs these point to. 331bf25801d837b8fc496bf9c3a34eac525d8a3d8aeted.mielczarek ExternSet externs_; 332eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com}; 333eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 3348d54c7509234e9a4918046c12dcb138489f06990thestig@chromium.org} // namespace google_breakpad 335eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com 336eab03fdb72a77dfd71db028e6e5676e734bdc443jimblandy@gmail.com#endif // COMMON_LINUX_MODULE_H__ 337