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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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. All Rights Reserved.
michael@0 4 //
michael@0 5 // Redistribution and use in source and binary forms, with or without
michael@0 6 // modification, are permitted provided that the following conditions are
michael@0 7 // met:
michael@0 8 //
michael@0 9 // * Redistributions of source code must retain the above copyright
michael@0 10 // notice, this list of conditions and the following disclaimer.
michael@0 11 // * Redistributions in binary form must reproduce the above
michael@0 12 // copyright notice, this list of conditions and the following disclaimer
michael@0 13 // in the documentation and/or other materials provided with the
michael@0 14 // distribution.
michael@0 15 // * Neither the name of Google Inc. nor the names of its
michael@0 16 // contributors may be used to endorse or promote products derived from
michael@0 17 // this software without specific prior written permission.
michael@0 18 //
michael@0 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 30
michael@0 31 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
michael@0 32
michael@0 33 // stabs_reader.h: Define StabsReader, a parser for STABS debugging
michael@0 34 // information. A description of the STABS debugging format can be
michael@0 35 // found at:
michael@0 36 //
michael@0 37 // http://sourceware.org/gdb/current/onlinedocs/stabs_toc.html
michael@0 38 //
michael@0 39 // The comments here assume you understand the format.
michael@0 40 //
michael@0 41 // This parser can handle big-endian and little-endian data, and the symbol
michael@0 42 // values may be either 32 or 64 bits long. It handles both STABS in
michael@0 43 // sections (as used on Linux) and STABS appearing directly in an
michael@0 44 // a.out-like symbol table (as used in Darwin OS X Mach-O files).
michael@0 45
michael@0 46 #ifndef COMMON_STABS_READER_H__
michael@0 47 #define COMMON_STABS_READER_H__
michael@0 48
michael@0 49 #include <stddef.h>
michael@0 50 #include <stdint.h>
michael@0 51
michael@0 52 #ifdef HAVE_CONFIG_H
michael@0 53 #include <config.h>
michael@0 54 #endif
michael@0 55
michael@0 56 #ifdef HAVE_A_OUT_H
michael@0 57 #include <a.out.h>
michael@0 58 #endif
michael@0 59 #ifdef HAVE_MACH_O_NLIST_H
michael@0 60 #include <mach-o/nlist.h>
michael@0 61 #endif
michael@0 62
michael@0 63 #include <string>
michael@0 64 #include <vector>
michael@0 65
michael@0 66 #include "common/byte_cursor.h"
michael@0 67 #include "common/using_std_string.h"
michael@0 68
michael@0 69 namespace google_breakpad {
michael@0 70
michael@0 71 class StabsHandler;
michael@0 72
michael@0 73 class StabsReader {
michael@0 74 public:
michael@0 75 // Create a reader for the STABS debug information whose .stab section is
michael@0 76 // being traversed by ITERATOR, and whose .stabstr section is referred to
michael@0 77 // by STRINGS. The reader will call the member functions of HANDLER to
michael@0 78 // report the information it finds, when the reader's 'Process' member
michael@0 79 // function is called.
michael@0 80 //
michael@0 81 // BIG_ENDIAN should be true if the entries in the .stab section are in
michael@0 82 // big-endian form, or false if they are in little-endian form.
michael@0 83 //
michael@0 84 // VALUE_SIZE should be either 4 or 8, indicating the size of the 'value'
michael@0 85 // field in each entry in bytes.
michael@0 86 //
michael@0 87 // UNITIZED should be true if the STABS data is stored in units with
michael@0 88 // N_UNDF headers. This is usually the case for STABS stored in sections,
michael@0 89 // like .stab/.stabstr, and usually not the case for STABS stored in the
michael@0 90 // actual symbol table; UNITIZED should be true when parsing Linux stabs,
michael@0 91 // false when parsing Mac OS X STABS. For details, see:
michael@0 92 // http://sourceware.org/gdb/current/onlinedocs/stabs/Stab-Section-Basics.html
michael@0 93 //
michael@0 94 // Note that, in ELF, the .stabstr section should be found using the
michael@0 95 // 'sh_link' field of the .stab section header, not by name.
michael@0 96 StabsReader(const uint8_t *stab, size_t stab_size,
michael@0 97 const uint8_t *stabstr, size_t stabstr_size,
michael@0 98 bool big_endian, size_t value_size, bool unitized,
michael@0 99 StabsHandler *handler);
michael@0 100
michael@0 101 // Process the STABS data, calling the handler's member functions to
michael@0 102 // report what we find. While the handler functions return true,
michael@0 103 // continue to process until we reach the end of the section. If we
michael@0 104 // processed the entire section and all handlers returned true,
michael@0 105 // return true. If any handler returned false, return false.
michael@0 106 //
michael@0 107 // This is only meant to be called once per StabsReader instance;
michael@0 108 // resuming a prior processing pass that stopped abruptly isn't supported.
michael@0 109 bool Process();
michael@0 110
michael@0 111 private:
michael@0 112
michael@0 113 // An class for walking arrays of STABS entries. This isolates the main
michael@0 114 // STABS reader from the exact format (size; endianness) of the entries
michael@0 115 // themselves.
michael@0 116 class EntryIterator {
michael@0 117 public:
michael@0 118 // The contents of a STABS entry, adjusted for the host's endianness,
michael@0 119 // word size, 'struct nlist' layout, and so on.
michael@0 120 struct Entry {
michael@0 121 // True if this iterator has reached the end of the entry array. When
michael@0 122 // this is set, the other members of this structure are not valid.
michael@0 123 bool at_end;
michael@0 124
michael@0 125 // The number of this entry within the list.
michael@0 126 size_t index;
michael@0 127
michael@0 128 // The current entry's name offset. This is the offset within the
michael@0 129 // current compilation unit's strings, as establish by the N_UNDF entries.
michael@0 130 size_t name_offset;
michael@0 131
michael@0 132 // The current entry's type, 'other' field, descriptor, and value.
michael@0 133 unsigned char type;
michael@0 134 unsigned char other;
michael@0 135 short descriptor;
michael@0 136 uint64_t value;
michael@0 137 };
michael@0 138
michael@0 139 // Create a EntryIterator walking the entries in BUFFER. Treat the
michael@0 140 // entries as big-endian if BIG_ENDIAN is true, as little-endian
michael@0 141 // otherwise. Assume each entry has a 'value' field whose size is
michael@0 142 // VALUE_SIZE.
michael@0 143 //
michael@0 144 // This would not be terribly clean to extend to other format variations,
michael@0 145 // but it's enough to handle Linux and Mac, and we'd like STABS to die
michael@0 146 // anyway.
michael@0 147 //
michael@0 148 // For the record: on Linux, STABS entry values are always 32 bits,
michael@0 149 // regardless of the architecture address size (don't ask me why); on
michael@0 150 // Mac, they are 32 or 64 bits long. Oddly, the section header's entry
michael@0 151 // size for a Linux ELF .stab section varies according to the ELF class
michael@0 152 // from 12 to 20 even as the actual entries remain unchanged.
michael@0 153 EntryIterator(const ByteBuffer *buffer, bool big_endian, size_t value_size);
michael@0 154
michael@0 155 // Move to the next entry. This function's behavior is undefined if
michael@0 156 // at_end() is true when it is called.
michael@0 157 EntryIterator &operator++() { Fetch(); entry_.index++; return *this; }
michael@0 158
michael@0 159 // Dereferencing this iterator produces a reference to an Entry structure
michael@0 160 // that holds the current entry's values. The entry is owned by this
michael@0 161 // EntryIterator, and will be invalidated at the next call to operator++.
michael@0 162 const Entry &operator*() const { return entry_; }
michael@0 163 const Entry *operator->() const { return &entry_; }
michael@0 164
michael@0 165 private:
michael@0 166 // Read the STABS entry at cursor_, and set entry_ appropriately.
michael@0 167 void Fetch();
michael@0 168
michael@0 169 // The size of entries' value field, in bytes.
michael@0 170 size_t value_size_;
michael@0 171
michael@0 172 // A byte cursor traversing buffer_.
michael@0 173 ByteCursor cursor_;
michael@0 174
michael@0 175 // Values for the entry this iterator refers to.
michael@0 176 Entry entry_;
michael@0 177 };
michael@0 178
michael@0 179 // A source line, saved to be reported later.
michael@0 180 struct Line {
michael@0 181 uint64_t address;
michael@0 182 const char *filename;
michael@0 183 int number;
michael@0 184 };
michael@0 185
michael@0 186 // Return the name of the current symbol.
michael@0 187 const char *SymbolString();
michael@0 188
michael@0 189 // Process a compilation unit starting at symbol_. Return true
michael@0 190 // to continue processing, or false to abort.
michael@0 191 bool ProcessCompilationUnit();
michael@0 192
michael@0 193 // Process a function in current_source_file_ starting at symbol_.
michael@0 194 // Return true to continue processing, or false to abort.
michael@0 195 bool ProcessFunction();
michael@0 196
michael@0 197 // Process an exported function symbol.
michael@0 198 // Return true to continue processing, or false to abort.
michael@0 199 bool ProcessExtern();
michael@0 200
michael@0 201 // The STABS entries being parsed.
michael@0 202 ByteBuffer entries_;
michael@0 203
michael@0 204 // The string section to which the entries refer.
michael@0 205 ByteBuffer strings_;
michael@0 206
michael@0 207 // The iterator walking the STABS entries.
michael@0 208 EntryIterator iterator_;
michael@0 209
michael@0 210 // True if the data is "unitized"; see the explanation in the comment for
michael@0 211 // StabsReader::StabsReader.
michael@0 212 bool unitized_;
michael@0 213
michael@0 214 StabsHandler *handler_;
michael@0 215
michael@0 216 // The offset of the current compilation unit's strings within stabstr_.
michael@0 217 size_t string_offset_;
michael@0 218
michael@0 219 // The value string_offset_ should have for the next compilation unit,
michael@0 220 // as established by N_UNDF entries.
michael@0 221 size_t next_cu_string_offset_;
michael@0 222
michael@0 223 // The current source file name.
michael@0 224 const char *current_source_file_;
michael@0 225
michael@0 226 // Mac OS X STABS place SLINE records before functions; we accumulate a
michael@0 227 // vector of these until we see the FUN record, and then report them
michael@0 228 // after the StartFunction call.
michael@0 229 std::vector<Line> queued_lines_;
michael@0 230 };
michael@0 231
michael@0 232 // Consumer-provided callback structure for the STABS reader. Clients
michael@0 233 // of the STABS reader provide an instance of this structure. The
michael@0 234 // reader then invokes the member functions of that instance to report
michael@0 235 // the information it finds.
michael@0 236 //
michael@0 237 // The default definitions of the member functions do nothing, and return
michael@0 238 // true so processing will continue.
michael@0 239 class StabsHandler {
michael@0 240 public:
michael@0 241 StabsHandler() { }
michael@0 242 virtual ~StabsHandler() { }
michael@0 243
michael@0 244 // Some general notes about the handler callback functions:
michael@0 245
michael@0 246 // Processing proceeds until the end of the .stabs section, or until
michael@0 247 // one of these functions returns false.
michael@0 248
michael@0 249 // The addresses given are as reported in the STABS info, without
michael@0 250 // regard for whether the module may be loaded at different
michael@0 251 // addresses at different times (a shared library, say). When
michael@0 252 // processing STABS from an ELF shared library, the addresses given
michael@0 253 // all assume the library is loaded at its nominal load address.
michael@0 254 // They are *not* offsets from the nominal load address. If you
michael@0 255 // want offsets, you must subtract off the library's nominal load
michael@0 256 // address.
michael@0 257
michael@0 258 // The arguments to these functions named FILENAME are all
michael@0 259 // references to strings stored in the .stabstr section. Because
michael@0 260 // both the Linux and Solaris linkers factor out duplicate strings
michael@0 261 // from the .stabstr section, the consumer can assume that if two
michael@0 262 // FILENAME values are different addresses, they represent different
michael@0 263 // file names.
michael@0 264 //
michael@0 265 // Thus, it's safe to use (say) std::map<char *, ...>, which does
michael@0 266 // string address comparisons, not string content comparisons.
michael@0 267 // Since all the strings are in same array of characters --- the
michael@0 268 // .stabstr section --- comparing their addresses produces
michael@0 269 // predictable, if not lexicographically meaningful, results.
michael@0 270
michael@0 271 // Begin processing a compilation unit whose main source file is
michael@0 272 // named FILENAME, and whose base address is ADDRESS. If
michael@0 273 // BUILD_DIRECTORY is non-NULL, it is the name of the build
michael@0 274 // directory in which the compilation occurred.
michael@0 275 virtual bool StartCompilationUnit(const char *filename, uint64_t address,
michael@0 276 const char *build_directory) {
michael@0 277 return true;
michael@0 278 }
michael@0 279
michael@0 280 // Finish processing the compilation unit. If ADDRESS is non-zero,
michael@0 281 // it is the ending address of the compilation unit. If ADDRESS is
michael@0 282 // zero, then the compilation unit's ending address is not
michael@0 283 // available, and the consumer must infer it by other means.
michael@0 284 virtual bool EndCompilationUnit(uint64_t address) { return true; }
michael@0 285
michael@0 286 // Begin processing a function named NAME, whose starting address is
michael@0 287 // ADDRESS. This function belongs to the compilation unit that was
michael@0 288 // most recently started but not ended.
michael@0 289 //
michael@0 290 // Note that, unlike filenames, NAME is not a pointer into the
michael@0 291 // .stabstr section; this is because the name as it appears in the
michael@0 292 // STABS data is followed by type information. The value passed to
michael@0 293 // StartFunction is the function name alone.
michael@0 294 //
michael@0 295 // In languages that use name mangling, like C++, NAME is mangled.
michael@0 296 virtual bool StartFunction(const string &name, uint64_t address) {
michael@0 297 return true;
michael@0 298 }
michael@0 299
michael@0 300 // Finish processing the function. If ADDRESS is non-zero, it is
michael@0 301 // the ending address for the function. If ADDRESS is zero, then
michael@0 302 // the function's ending address is not available, and the consumer
michael@0 303 // must infer it by other means.
michael@0 304 virtual bool EndFunction(uint64_t address) { return true; }
michael@0 305
michael@0 306 // Report that the code at ADDRESS is attributable to line NUMBER of
michael@0 307 // the source file named FILENAME. The caller must infer the ending
michael@0 308 // address of the line.
michael@0 309 virtual bool Line(uint64_t address, const char *filename, int number) {
michael@0 310 return true;
michael@0 311 }
michael@0 312
michael@0 313 // Report that an exported function NAME is present at ADDRESS.
michael@0 314 // The size of the function is unknown.
michael@0 315 virtual bool Extern(const string &name, uint64_t address) {
michael@0 316 return true;
michael@0 317 }
michael@0 318
michael@0 319 // Report a warning. FORMAT is a printf-like format string,
michael@0 320 // specifying how to format the subsequent arguments.
michael@0 321 virtual void Warning(const char *format, ...) = 0;
michael@0 322 };
michael@0 323
michael@0 324 } // namespace google_breakpad
michael@0 325
michael@0 326 #endif // COMMON_STABS_READER_H__

mercurial