Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 | // module.h: Define google_breakpad::Module. A Module holds debugging |
michael@0 | 35 | // information, and can write that information out as a Breakpad |
michael@0 | 36 | // symbol file. |
michael@0 | 37 | |
michael@0 | 38 | #ifndef COMMON_LINUX_MODULE_H__ |
michael@0 | 39 | #define COMMON_LINUX_MODULE_H__ |
michael@0 | 40 | |
michael@0 | 41 | #include <iostream> |
michael@0 | 42 | #include <map> |
michael@0 | 43 | #include <set> |
michael@0 | 44 | #include <string> |
michael@0 | 45 | #include <vector> |
michael@0 | 46 | |
michael@0 | 47 | #include <assert.h> |
michael@0 | 48 | #include <stdlib.h> |
michael@0 | 49 | #include <stdio.h> |
michael@0 | 50 | |
michael@0 | 51 | #include "common/symbol_data.h" |
michael@0 | 52 | #include "common/using_std_string.h" |
michael@0 | 53 | #include "common/unique_string.h" |
michael@0 | 54 | #include "google_breakpad/common/breakpad_types.h" |
michael@0 | 55 | |
michael@0 | 56 | namespace google_breakpad { |
michael@0 | 57 | |
michael@0 | 58 | using std::set; |
michael@0 | 59 | using std::vector; |
michael@0 | 60 | using std::map; |
michael@0 | 61 | |
michael@0 | 62 | // A Module represents the contents of a module, and supports methods |
michael@0 | 63 | // for adding information produced by parsing STABS or DWARF data |
michael@0 | 64 | // --- possibly both from the same file --- and then writing out the |
michael@0 | 65 | // unified contents as a Breakpad-format symbol file. |
michael@0 | 66 | class Module { |
michael@0 | 67 | public: |
michael@0 | 68 | // The type of addresses and sizes in a symbol table. |
michael@0 | 69 | typedef uint64_t Address; |
michael@0 | 70 | struct File; |
michael@0 | 71 | struct Function; |
michael@0 | 72 | struct Line; |
michael@0 | 73 | struct Extern; |
michael@0 | 74 | |
michael@0 | 75 | // Addresses appearing in File, Function, and Line structures are |
michael@0 | 76 | // absolute, not relative to the the module's load address. That |
michael@0 | 77 | // is, if the module were loaded at its nominal load address, the |
michael@0 | 78 | // addresses would be correct. |
michael@0 | 79 | |
michael@0 | 80 | // A source file. |
michael@0 | 81 | struct File { |
michael@0 | 82 | // The name of the source file. |
michael@0 | 83 | string name; |
michael@0 | 84 | |
michael@0 | 85 | // The file's source id. The Write member function clears this |
michael@0 | 86 | // field and assigns source ids a fresh, so any value placed here |
michael@0 | 87 | // before calling Write will be lost. |
michael@0 | 88 | int source_id; |
michael@0 | 89 | }; |
michael@0 | 90 | |
michael@0 | 91 | // A function. |
michael@0 | 92 | struct Function { |
michael@0 | 93 | // For sorting by address. (Not style-guide compliant, but it's |
michael@0 | 94 | // stupid not to put this in the struct.) |
michael@0 | 95 | static bool CompareByAddress(const Function *x, const Function *y) { |
michael@0 | 96 | return x->address < y->address; |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | // The function's name. |
michael@0 | 100 | string name; |
michael@0 | 101 | |
michael@0 | 102 | // The start address and length of the function's code. |
michael@0 | 103 | Address address, size; |
michael@0 | 104 | |
michael@0 | 105 | // The function's parameter size. |
michael@0 | 106 | Address parameter_size; |
michael@0 | 107 | |
michael@0 | 108 | // Source lines belonging to this function, sorted by increasing |
michael@0 | 109 | // address. |
michael@0 | 110 | vector<Line> lines; |
michael@0 | 111 | }; |
michael@0 | 112 | |
michael@0 | 113 | // A source line. |
michael@0 | 114 | struct Line { |
michael@0 | 115 | // For sorting by address. (Not style-guide compliant, but it's |
michael@0 | 116 | // stupid not to put this in the struct.) |
michael@0 | 117 | static bool CompareByAddress(const Module::Line &x, const Module::Line &y) { |
michael@0 | 118 | return x.address < y.address; |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | Address address, size; // The address and size of the line's code. |
michael@0 | 122 | File *file; // The source file. |
michael@0 | 123 | int number; // The source line number. |
michael@0 | 124 | }; |
michael@0 | 125 | |
michael@0 | 126 | // An exported symbol. |
michael@0 | 127 | struct Extern { |
michael@0 | 128 | Address address; |
michael@0 | 129 | string name; |
michael@0 | 130 | }; |
michael@0 | 131 | |
michael@0 | 132 | // Representation of an expression. This can either be a postfix |
michael@0 | 133 | // expression, in which case it is stored as a string, or a simple |
michael@0 | 134 | // expression of the form (identifier + imm) or *(identifier + imm). |
michael@0 | 135 | // It can also be invalid (denoting "no value"). |
michael@0 | 136 | enum ExprHow { |
michael@0 | 137 | kExprInvalid = 1, |
michael@0 | 138 | kExprPostfix, |
michael@0 | 139 | kExprSimple, |
michael@0 | 140 | kExprSimpleMem |
michael@0 | 141 | }; |
michael@0 | 142 | struct Expr { |
michael@0 | 143 | // Construct a simple-form expression |
michael@0 | 144 | Expr(const UniqueString* ident, long offset, bool deref) { |
michael@0 | 145 | if (ident == ustr__empty()) { |
michael@0 | 146 | Expr(); |
michael@0 | 147 | } else { |
michael@0 | 148 | postfix_ = ""; |
michael@0 | 149 | ident_ = ident; |
michael@0 | 150 | offset_ = offset; |
michael@0 | 151 | how_ = deref ? kExprSimpleMem : kExprSimple; |
michael@0 | 152 | } |
michael@0 | 153 | } |
michael@0 | 154 | // Construct an expression from a postfix string |
michael@0 | 155 | Expr(string postfix) { |
michael@0 | 156 | if (postfix.empty()) { |
michael@0 | 157 | Expr(); |
michael@0 | 158 | } else { |
michael@0 | 159 | postfix_ = postfix; |
michael@0 | 160 | ident_ = NULL; |
michael@0 | 161 | offset_ = 0; |
michael@0 | 162 | how_ = kExprPostfix; |
michael@0 | 163 | } |
michael@0 | 164 | } |
michael@0 | 165 | // Construct an invalid expression |
michael@0 | 166 | Expr() { |
michael@0 | 167 | postfix_ = ""; |
michael@0 | 168 | ident_ = NULL; |
michael@0 | 169 | offset_ = 0; |
michael@0 | 170 | how_ = kExprInvalid; |
michael@0 | 171 | } |
michael@0 | 172 | bool isExprInvalid() const { return how_ == kExprInvalid; } |
michael@0 | 173 | |
michael@0 | 174 | // Return the postfix expression string, either directly, |
michael@0 | 175 | // if this is a postfix expression, or by synthesising it |
michael@0 | 176 | // for a simple expression. |
michael@0 | 177 | string getExprPostfix() const { |
michael@0 | 178 | switch (how_) { |
michael@0 | 179 | case kExprPostfix: |
michael@0 | 180 | return postfix_; |
michael@0 | 181 | case kExprSimple: |
michael@0 | 182 | case kExprSimpleMem: { |
michael@0 | 183 | char buf[40]; |
michael@0 | 184 | sprintf(buf, " %ld %c%s", labs(offset_), offset_ < 0 ? '-' : '+', |
michael@0 | 185 | how_ == kExprSimple ? "" : " ^"); |
michael@0 | 186 | return string(FromUniqueString(ident_)) + string(buf); |
michael@0 | 187 | } |
michael@0 | 188 | case kExprInvalid: |
michael@0 | 189 | default: |
michael@0 | 190 | assert(0 && "getExprPostfix: invalid Module::Expr type"); |
michael@0 | 191 | return "Expr::genExprPostfix: kExprInvalid"; |
michael@0 | 192 | } |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | bool operator==(const Expr& other) const { |
michael@0 | 196 | return how_ == other.how_ && |
michael@0 | 197 | ident_ == other.ident_ && |
michael@0 | 198 | offset_ == other.offset_ && |
michael@0 | 199 | postfix_ == other.postfix_; |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | // Returns an Expr which evaluates to |this| + |delta| |
michael@0 | 203 | Expr add_delta(long delta) { |
michael@0 | 204 | if (delta == 0) { |
michael@0 | 205 | return *this; |
michael@0 | 206 | } |
michael@0 | 207 | // If it's a simple form expression of the form "identifier + offset", |
michael@0 | 208 | // simply add |delta| on to |offset|. In the other two possible |
michael@0 | 209 | // cases: |
michael@0 | 210 | // *(identifier + offset) |
michael@0 | 211 | // completely arbitrary postfix expression string |
michael@0 | 212 | // the only option is to "downgrade" it to a postfix expression and add |
michael@0 | 213 | // "+/- delta" at the end of the string, since the result can't be |
michael@0 | 214 | // represented in the simple form. |
michael@0 | 215 | switch (how_) { |
michael@0 | 216 | case kExprSimpleMem: |
michael@0 | 217 | case kExprPostfix: { |
michael@0 | 218 | char buf[40]; |
michael@0 | 219 | sprintf(buf, " %ld %c", labs(delta), delta < 0 ? '-' : '+'); |
michael@0 | 220 | return Expr(getExprPostfix() + string(buf)); |
michael@0 | 221 | } |
michael@0 | 222 | case kExprSimple: |
michael@0 | 223 | return Expr(ident_, offset_ + delta, false); |
michael@0 | 224 | case kExprInvalid: |
michael@0 | 225 | default: |
michael@0 | 226 | assert(0 && "add_delta: invalid Module::Expr type"); |
michael@0 | 227 | // Invalid inputs produce an invalid result |
michael@0 | 228 | return Expr(); |
michael@0 | 229 | } |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | // Returns an Expr which evaluates to *|this| |
michael@0 | 233 | Expr deref() { |
michael@0 | 234 | // In the simplest case, a kExprSimple can be changed into a |
michael@0 | 235 | // kExprSimpleMem. In all other cases it has to be dumped as a |
michael@0 | 236 | // postfix string, and " ^" added at the end. |
michael@0 | 237 | switch (how_) { |
michael@0 | 238 | case kExprSimple: { |
michael@0 | 239 | Expr t = *this; |
michael@0 | 240 | t.how_ = kExprSimpleMem; |
michael@0 | 241 | return t; |
michael@0 | 242 | } |
michael@0 | 243 | case kExprSimpleMem: |
michael@0 | 244 | case kExprPostfix: { |
michael@0 | 245 | return Expr(getExprPostfix() + " ^"); |
michael@0 | 246 | } |
michael@0 | 247 | case kExprInvalid: |
michael@0 | 248 | default: |
michael@0 | 249 | assert(0 && "deref: invalid Module::Expr type"); |
michael@0 | 250 | // Invalid inputs produce an invalid result |
michael@0 | 251 | return Expr(); |
michael@0 | 252 | } |
michael@0 | 253 | } |
michael@0 | 254 | |
michael@0 | 255 | // The identifier that gives the starting value for simple expressions. |
michael@0 | 256 | const UniqueString* ident_; |
michael@0 | 257 | // The offset to add for simple expressions. |
michael@0 | 258 | long offset_; |
michael@0 | 259 | // The Postfix expression string to evaluate for non-simple expressions. |
michael@0 | 260 | string postfix_; |
michael@0 | 261 | // The operation expressed by this expression. |
michael@0 | 262 | ExprHow how_; |
michael@0 | 263 | |
michael@0 | 264 | friend std::ostream& operator<<(std::ostream& stream, const Expr& expr); |
michael@0 | 265 | }; |
michael@0 | 266 | |
michael@0 | 267 | // A map from register names to expressions that recover |
michael@0 | 268 | // their values. This can represent a complete set of rules to |
michael@0 | 269 | // follow at some address, or a set of changes to be applied to an |
michael@0 | 270 | // extant set of rules. |
michael@0 | 271 | typedef map<const UniqueString*, Expr> RuleMap; |
michael@0 | 272 | |
michael@0 | 273 | // A map from addresses to RuleMaps, representing changes that take |
michael@0 | 274 | // effect at given addresses. |
michael@0 | 275 | typedef map<Address, RuleMap> RuleChangeMap; |
michael@0 | 276 | |
michael@0 | 277 | // A range of 'STACK CFI' stack walking information. An instance of |
michael@0 | 278 | // this structure corresponds to a 'STACK CFI INIT' record and the |
michael@0 | 279 | // subsequent 'STACK CFI' records that fall within its range. |
michael@0 | 280 | struct StackFrameEntry { |
michael@0 | 281 | // The starting address and number of bytes of machine code this |
michael@0 | 282 | // entry covers. |
michael@0 | 283 | Address address, size; |
michael@0 | 284 | |
michael@0 | 285 | // The initial register recovery rules, in force at the starting |
michael@0 | 286 | // address. |
michael@0 | 287 | RuleMap initial_rules; |
michael@0 | 288 | |
michael@0 | 289 | // A map from addresses to rule changes. To find the rules in |
michael@0 | 290 | // force at a given address, start with initial_rules, and then |
michael@0 | 291 | // apply the changes given in this map for all addresses up to and |
michael@0 | 292 | // including the address you're interested in. |
michael@0 | 293 | RuleChangeMap rule_changes; |
michael@0 | 294 | }; |
michael@0 | 295 | |
michael@0 | 296 | struct FunctionCompare { |
michael@0 | 297 | bool operator() (const Function *lhs, |
michael@0 | 298 | const Function *rhs) const { |
michael@0 | 299 | if (lhs->address == rhs->address) |
michael@0 | 300 | return lhs->name < rhs->name; |
michael@0 | 301 | return lhs->address < rhs->address; |
michael@0 | 302 | } |
michael@0 | 303 | }; |
michael@0 | 304 | |
michael@0 | 305 | struct ExternCompare { |
michael@0 | 306 | bool operator() (const Extern *lhs, |
michael@0 | 307 | const Extern *rhs) const { |
michael@0 | 308 | return lhs->address < rhs->address; |
michael@0 | 309 | } |
michael@0 | 310 | }; |
michael@0 | 311 | |
michael@0 | 312 | struct StackFrameEntryCompare { |
michael@0 | 313 | bool operator() (const StackFrameEntry* lhs, |
michael@0 | 314 | const StackFrameEntry* rhs) const { |
michael@0 | 315 | return lhs->address < rhs->address; |
michael@0 | 316 | } |
michael@0 | 317 | }; |
michael@0 | 318 | |
michael@0 | 319 | // Create a new module with the given name, operating system, |
michael@0 | 320 | // architecture, and ID string. |
michael@0 | 321 | Module(const string &name, const string &os, const string &architecture, |
michael@0 | 322 | const string &id); |
michael@0 | 323 | ~Module(); |
michael@0 | 324 | |
michael@0 | 325 | // Set the module's load address to LOAD_ADDRESS; addresses given |
michael@0 | 326 | // for functions and lines will be written to the Breakpad symbol |
michael@0 | 327 | // file as offsets from this address. Construction initializes this |
michael@0 | 328 | // module's load address to zero: addresses written to the symbol |
michael@0 | 329 | // file will be the same as they appear in the Function, Line, and |
michael@0 | 330 | // StackFrameEntry structures. |
michael@0 | 331 | // |
michael@0 | 332 | // Note that this member function has no effect on addresses stored |
michael@0 | 333 | // in the data added to this module; the Write member function |
michael@0 | 334 | // simply subtracts off the load address from addresses before it |
michael@0 | 335 | // prints them. Only the last load address given before calling |
michael@0 | 336 | // Write is used. |
michael@0 | 337 | void SetLoadAddress(Address load_address); |
michael@0 | 338 | |
michael@0 | 339 | // Add FUNCTION to the module. FUNCTION's name must not be empty. |
michael@0 | 340 | // This module owns all Function objects added with this function: |
michael@0 | 341 | // destroying the module destroys them as well. |
michael@0 | 342 | void AddFunction(Function *function); |
michael@0 | 343 | |
michael@0 | 344 | // Add all the functions in [BEGIN,END) to the module. |
michael@0 | 345 | // This module owns all Function objects added with this function: |
michael@0 | 346 | // destroying the module destroys them as well. |
michael@0 | 347 | void AddFunctions(vector<Function *>::iterator begin, |
michael@0 | 348 | vector<Function *>::iterator end); |
michael@0 | 349 | |
michael@0 | 350 | // Add STACK_FRAME_ENTRY to the module. |
michael@0 | 351 | // This module owns all StackFrameEntry objects added with this |
michael@0 | 352 | // function: destroying the module destroys them as well. |
michael@0 | 353 | void AddStackFrameEntry(StackFrameEntry *stack_frame_entry); |
michael@0 | 354 | |
michael@0 | 355 | // Add PUBLIC to the module. |
michael@0 | 356 | // This module owns all Extern objects added with this function: |
michael@0 | 357 | // destroying the module destroys them as well. |
michael@0 | 358 | void AddExtern(Extern *ext); |
michael@0 | 359 | |
michael@0 | 360 | // If this module has a file named NAME, return a pointer to it. If |
michael@0 | 361 | // it has none, then create one and return a pointer to the new |
michael@0 | 362 | // file. This module owns all File objects created using these |
michael@0 | 363 | // functions; destroying the module destroys them as well. |
michael@0 | 364 | File *FindFile(const string &name); |
michael@0 | 365 | File *FindFile(const char *name); |
michael@0 | 366 | |
michael@0 | 367 | // If this module has a file named NAME, return a pointer to it. |
michael@0 | 368 | // Otherwise, return NULL. |
michael@0 | 369 | File *FindExistingFile(const string &name); |
michael@0 | 370 | |
michael@0 | 371 | // Insert pointers to the functions added to this module at I in |
michael@0 | 372 | // VEC. The pointed-to Functions are still owned by this module. |
michael@0 | 373 | // (Since this is effectively a copy of the function list, this is |
michael@0 | 374 | // mostly useful for testing; other uses should probably get a more |
michael@0 | 375 | // appropriate interface.) |
michael@0 | 376 | void GetFunctions(vector<Function *> *vec, vector<Function *>::iterator i); |
michael@0 | 377 | |
michael@0 | 378 | // If this module has a function at ADDRESS, return a pointer to it. |
michael@0 | 379 | // Otherwise, return NULL. |
michael@0 | 380 | Function* FindFunctionByAddress(Address address); |
michael@0 | 381 | |
michael@0 | 382 | // Insert pointers to the externs added to this module at I in |
michael@0 | 383 | // VEC. The pointed-to Externs are still owned by this module. |
michael@0 | 384 | // (Since this is effectively a copy of the extern list, this is |
michael@0 | 385 | // mostly useful for testing; other uses should probably get a more |
michael@0 | 386 | // appropriate interface.) |
michael@0 | 387 | void GetExterns(vector<Extern *> *vec, vector<Extern *>::iterator i); |
michael@0 | 388 | |
michael@0 | 389 | // If this module has an extern whose base address is less than ADDRESS, |
michael@0 | 390 | // return a pointer to it. Otherwise, return NULL. |
michael@0 | 391 | Extern* FindExternByAddress(Address address); |
michael@0 | 392 | |
michael@0 | 393 | // Clear VEC and fill it with pointers to the Files added to this |
michael@0 | 394 | // module, sorted by name. The pointed-to Files are still owned by |
michael@0 | 395 | // this module. (Since this is effectively a copy of the file list, |
michael@0 | 396 | // this is mostly useful for testing; other uses should probably get |
michael@0 | 397 | // a more appropriate interface.) |
michael@0 | 398 | void GetFiles(vector<File *> *vec); |
michael@0 | 399 | |
michael@0 | 400 | // Clear VEC and fill it with pointers to the StackFrameEntry |
michael@0 | 401 | // objects that have been added to this module. (Since this is |
michael@0 | 402 | // effectively a copy of the stack frame entry list, this is mostly |
michael@0 | 403 | // useful for testing; other uses should probably get |
michael@0 | 404 | // a more appropriate interface.) |
michael@0 | 405 | void GetStackFrameEntries(vector<StackFrameEntry *> *vec); |
michael@0 | 406 | |
michael@0 | 407 | // If this module has a StackFrameEntry whose address range covers |
michael@0 | 408 | // ADDRESS, return it. Otherwise return NULL. |
michael@0 | 409 | StackFrameEntry* FindStackFrameEntryByAddress(Address address); |
michael@0 | 410 | |
michael@0 | 411 | // Find those files in this module that are actually referred to by |
michael@0 | 412 | // functions' line number data, and assign them source id numbers. |
michael@0 | 413 | // Set the source id numbers for all other files --- unused by the |
michael@0 | 414 | // source line data --- to -1. We do this before writing out the |
michael@0 | 415 | // symbol file, at which point we omit any unused files. |
michael@0 | 416 | void AssignSourceIds(); |
michael@0 | 417 | |
michael@0 | 418 | // Call AssignSourceIds, and write this module to STREAM in the |
michael@0 | 419 | // breakpad symbol format. Return true if all goes well, or false if |
michael@0 | 420 | // an error occurs. This method writes out: |
michael@0 | 421 | // - a header based on the values given to the constructor, |
michael@0 | 422 | // If symbol_data is not ONLY_CFI then: |
michael@0 | 423 | // - the source files added via FindFile, |
michael@0 | 424 | // - the functions added via AddFunctions, each with its lines, |
michael@0 | 425 | // - all public records, |
michael@0 | 426 | // If symbol_data is not NO_CFI then: |
michael@0 | 427 | // - all CFI records. |
michael@0 | 428 | // Addresses in the output are all relative to the load address |
michael@0 | 429 | // established by SetLoadAddress. |
michael@0 | 430 | bool Write(std::ostream &stream, SymbolData symbol_data); |
michael@0 | 431 | |
michael@0 | 432 | private: |
michael@0 | 433 | // Report an error that has occurred writing the symbol file, using |
michael@0 | 434 | // errno to find the appropriate cause. Return false. |
michael@0 | 435 | static bool ReportError(); |
michael@0 | 436 | |
michael@0 | 437 | // Write RULE_MAP to STREAM, in the form appropriate for 'STACK CFI' |
michael@0 | 438 | // records, without a final newline. Return true if all goes well; |
michael@0 | 439 | // if an error occurs, return false, and leave errno set. |
michael@0 | 440 | static bool WriteRuleMap(const RuleMap &rule_map, std::ostream &stream); |
michael@0 | 441 | |
michael@0 | 442 | // Module header entries. |
michael@0 | 443 | string name_, os_, architecture_, id_; |
michael@0 | 444 | |
michael@0 | 445 | // The module's nominal load address. Addresses for functions and |
michael@0 | 446 | // lines are absolute, assuming the module is loaded at this |
michael@0 | 447 | // address. |
michael@0 | 448 | Address load_address_; |
michael@0 | 449 | |
michael@0 | 450 | // Relation for maps whose keys are strings shared with some other |
michael@0 | 451 | // structure. |
michael@0 | 452 | struct CompareStringPtrs { |
michael@0 | 453 | bool operator()(const string *x, const string *y) const { return *x < *y; } |
michael@0 | 454 | }; |
michael@0 | 455 | |
michael@0 | 456 | // A map from filenames to File structures. The map's keys are |
michael@0 | 457 | // pointers to the Files' names. |
michael@0 | 458 | typedef map<const string *, File *, CompareStringPtrs> FileByNameMap; |
michael@0 | 459 | |
michael@0 | 460 | // A set containing Function structures, sorted by address. |
michael@0 | 461 | typedef set<Function *, FunctionCompare> FunctionSet; |
michael@0 | 462 | |
michael@0 | 463 | // A set containing Extern structures, sorted by address. |
michael@0 | 464 | typedef set<Extern *, ExternCompare> ExternSet; |
michael@0 | 465 | |
michael@0 | 466 | // A set containing StackFrameEntry structures, sorted by address. |
michael@0 | 467 | typedef set<StackFrameEntry*, StackFrameEntryCompare> StackFrameEntrySet; |
michael@0 | 468 | |
michael@0 | 469 | // The module owns all the files and functions that have been added |
michael@0 | 470 | // to it; destroying the module frees the Files and Functions these |
michael@0 | 471 | // point to. |
michael@0 | 472 | FileByNameMap files_; // This module's source files. |
michael@0 | 473 | FunctionSet functions_; // This module's functions. |
michael@0 | 474 | |
michael@0 | 475 | // The module owns all the call frame info entries that have been |
michael@0 | 476 | // added to it. |
michael@0 | 477 | StackFrameEntrySet stack_frame_entries_; |
michael@0 | 478 | |
michael@0 | 479 | // The module owns all the externs that have been added to it; |
michael@0 | 480 | // destroying the module frees the Externs these point to. |
michael@0 | 481 | ExternSet externs_; |
michael@0 | 482 | }; |
michael@0 | 483 | |
michael@0 | 484 | } // namespace google_breakpad |
michael@0 | 485 | |
michael@0 | 486 | #endif // COMMON_LINUX_MODULE_H__ |