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