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 | // Copyright (c) 2010 Google Inc. |
michael@0 | 2 | // All rights reserved. |
michael@0 | 3 | // |
michael@0 | 4 | // Redistribution and use in source and binary forms, with or without |
michael@0 | 5 | // modification, are permitted provided that the following conditions are |
michael@0 | 6 | // met: |
michael@0 | 7 | // |
michael@0 | 8 | // * Redistributions of source code must retain the above copyright |
michael@0 | 9 | // notice, this list of conditions and the following disclaimer. |
michael@0 | 10 | // * Redistributions in binary form must reproduce the above |
michael@0 | 11 | // copyright notice, this list of conditions and the following disclaimer |
michael@0 | 12 | // in the documentation and/or other materials provided with the |
michael@0 | 13 | // distribution. |
michael@0 | 14 | // * Neither the name of Google Inc. nor the names of its |
michael@0 | 15 | // contributors may be used to endorse or promote products derived from |
michael@0 | 16 | // this software without specific prior written permission. |
michael@0 | 17 | // |
michael@0 | 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
michael@0 | 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@0 | 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@0 | 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
michael@0 | 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
michael@0 | 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 29 | |
michael@0 | 30 | // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> |
michael@0 | 31 | |
michael@0 | 32 | // dump_stabs.cc --- implement the StabsToModule class. |
michael@0 | 33 | |
michael@0 | 34 | #include <assert.h> |
michael@0 | 35 | #include <cxxabi.h> |
michael@0 | 36 | #include <stdarg.h> |
michael@0 | 37 | #include <stdio.h> |
michael@0 | 38 | |
michael@0 | 39 | #include <algorithm> |
michael@0 | 40 | |
michael@0 | 41 | #include "common/stabs_to_module.h" |
michael@0 | 42 | #include "common/using_std_string.h" |
michael@0 | 43 | |
michael@0 | 44 | namespace google_breakpad { |
michael@0 | 45 | |
michael@0 | 46 | // Demangle using abi call. |
michael@0 | 47 | // Older GCC may not support it. |
michael@0 | 48 | static string Demangle(const string &mangled) { |
michael@0 | 49 | int status = 0; |
michael@0 | 50 | char *demangled = abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status); |
michael@0 | 51 | if (status == 0 && demangled != NULL) { |
michael@0 | 52 | string str(demangled); |
michael@0 | 53 | free(demangled); |
michael@0 | 54 | return str; |
michael@0 | 55 | } |
michael@0 | 56 | return string(mangled); |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | StabsToModule::~StabsToModule() { |
michael@0 | 60 | // Free any functions we've accumulated but not added to the module. |
michael@0 | 61 | for (vector<Module::Function *>::const_iterator func_it = functions_.begin(); |
michael@0 | 62 | func_it != functions_.end(); func_it++) |
michael@0 | 63 | delete *func_it; |
michael@0 | 64 | // Free any function that we're currently within. |
michael@0 | 65 | delete current_function_; |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | bool StabsToModule::StartCompilationUnit(const char *name, uint64_t address, |
michael@0 | 69 | const char *build_directory) { |
michael@0 | 70 | assert(!in_compilation_unit_); |
michael@0 | 71 | in_compilation_unit_ = true; |
michael@0 | 72 | current_source_file_name_ = name; |
michael@0 | 73 | current_source_file_ = module_->FindFile(name); |
michael@0 | 74 | comp_unit_base_address_ = address; |
michael@0 | 75 | boundaries_.push_back(static_cast<Module::Address>(address)); |
michael@0 | 76 | return true; |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | bool StabsToModule::EndCompilationUnit(uint64_t address) { |
michael@0 | 80 | assert(in_compilation_unit_); |
michael@0 | 81 | in_compilation_unit_ = false; |
michael@0 | 82 | comp_unit_base_address_ = 0; |
michael@0 | 83 | current_source_file_ = NULL; |
michael@0 | 84 | current_source_file_name_ = NULL; |
michael@0 | 85 | if (address) |
michael@0 | 86 | boundaries_.push_back(static_cast<Module::Address>(address)); |
michael@0 | 87 | return true; |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | bool StabsToModule::StartFunction(const string &name, |
michael@0 | 91 | uint64_t address) { |
michael@0 | 92 | assert(!current_function_); |
michael@0 | 93 | Module::Function *f = new Module::Function; |
michael@0 | 94 | f->name = Demangle(name); |
michael@0 | 95 | f->address = address; |
michael@0 | 96 | f->size = 0; // We compute this in StabsToModule::Finalize(). |
michael@0 | 97 | f->parameter_size = 0; // We don't provide this information. |
michael@0 | 98 | current_function_ = f; |
michael@0 | 99 | boundaries_.push_back(static_cast<Module::Address>(address)); |
michael@0 | 100 | return true; |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | bool StabsToModule::EndFunction(uint64_t address) { |
michael@0 | 104 | assert(current_function_); |
michael@0 | 105 | // Functions in this compilation unit should have address bigger |
michael@0 | 106 | // than the compilation unit's starting address. There may be a lot |
michael@0 | 107 | // of duplicated entries for functions in the STABS data. We will |
michael@0 | 108 | // count on the Module to remove the duplicates. |
michael@0 | 109 | if (current_function_->address >= comp_unit_base_address_) |
michael@0 | 110 | functions_.push_back(current_function_); |
michael@0 | 111 | else |
michael@0 | 112 | delete current_function_; |
michael@0 | 113 | current_function_ = NULL; |
michael@0 | 114 | if (address) |
michael@0 | 115 | boundaries_.push_back(static_cast<Module::Address>(address)); |
michael@0 | 116 | return true; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | bool StabsToModule::Line(uint64_t address, const char *name, int number) { |
michael@0 | 120 | assert(current_function_); |
michael@0 | 121 | assert(current_source_file_); |
michael@0 | 122 | if (name != current_source_file_name_) { |
michael@0 | 123 | current_source_file_ = module_->FindFile(name); |
michael@0 | 124 | current_source_file_name_ = name; |
michael@0 | 125 | } |
michael@0 | 126 | Module::Line line; |
michael@0 | 127 | line.address = address; |
michael@0 | 128 | line.size = 0; // We compute this in StabsToModule::Finalize(). |
michael@0 | 129 | line.file = current_source_file_; |
michael@0 | 130 | line.number = number; |
michael@0 | 131 | current_function_->lines.push_back(line); |
michael@0 | 132 | return true; |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | bool StabsToModule::Extern(const string &name, uint64_t address) { |
michael@0 | 136 | Module::Extern *ext = new Module::Extern; |
michael@0 | 137 | // Older libstdc++ demangle implementations can crash on unexpected |
michael@0 | 138 | // input, so be careful about what gets passed in. |
michael@0 | 139 | if (name.compare(0, 3, "__Z") == 0) { |
michael@0 | 140 | ext->name = Demangle(name.substr(1)); |
michael@0 | 141 | } else if (name[0] == '_') { |
michael@0 | 142 | ext->name = name.substr(1); |
michael@0 | 143 | } else { |
michael@0 | 144 | ext->name = name; |
michael@0 | 145 | } |
michael@0 | 146 | ext->address = address; |
michael@0 | 147 | module_->AddExtern(ext); |
michael@0 | 148 | return true; |
michael@0 | 149 | } |
michael@0 | 150 | |
michael@0 | 151 | void StabsToModule::Warning(const char *format, ...) { |
michael@0 | 152 | va_list args; |
michael@0 | 153 | va_start(args, format); |
michael@0 | 154 | vfprintf(stderr, format, args); |
michael@0 | 155 | va_end(args); |
michael@0 | 156 | } |
michael@0 | 157 | |
michael@0 | 158 | void StabsToModule::Finalize() { |
michael@0 | 159 | // Sort our boundary list, so we can search it quickly. |
michael@0 | 160 | sort(boundaries_.begin(), boundaries_.end()); |
michael@0 | 161 | // Sort all functions by address, just for neatness. |
michael@0 | 162 | sort(functions_.begin(), functions_.end(), |
michael@0 | 163 | Module::Function::CompareByAddress); |
michael@0 | 164 | |
michael@0 | 165 | for (vector<Module::Function *>::const_iterator func_it = functions_.begin(); |
michael@0 | 166 | func_it != functions_.end(); |
michael@0 | 167 | func_it++) { |
michael@0 | 168 | Module::Function *f = *func_it; |
michael@0 | 169 | // Compute the function f's size. |
michael@0 | 170 | vector<Module::Address>::const_iterator boundary |
michael@0 | 171 | = std::upper_bound(boundaries_.begin(), boundaries_.end(), f->address); |
michael@0 | 172 | if (boundary != boundaries_.end()) |
michael@0 | 173 | f->size = *boundary - f->address; |
michael@0 | 174 | else |
michael@0 | 175 | // If this is the last function in the module, and the STABS |
michael@0 | 176 | // reader was unable to give us its ending address, then assign |
michael@0 | 177 | // it a bogus, very large value. This will happen at most once |
michael@0 | 178 | // per module: since we've added all functions' addresses to the |
michael@0 | 179 | // boundary table, only one can be the last. |
michael@0 | 180 | f->size = kFallbackSize; |
michael@0 | 181 | |
michael@0 | 182 | // Compute sizes for each of the function f's lines --- if it has any. |
michael@0 | 183 | if (!f->lines.empty()) { |
michael@0 | 184 | stable_sort(f->lines.begin(), f->lines.end(), |
michael@0 | 185 | Module::Line::CompareByAddress); |
michael@0 | 186 | vector<Module::Line>::iterator last_line = f->lines.end() - 1; |
michael@0 | 187 | for (vector<Module::Line>::iterator line_it = f->lines.begin(); |
michael@0 | 188 | line_it != last_line; line_it++) |
michael@0 | 189 | line_it[0].size = line_it[1].address - line_it[0].address; |
michael@0 | 190 | // Compute the size of the last line from f's end address. |
michael@0 | 191 | last_line->size = (f->address + f->size) - last_line->address; |
michael@0 | 192 | } |
michael@0 | 193 | } |
michael@0 | 194 | // Now that everything has a size, add our functions to the module, and |
michael@0 | 195 | // dispose of our private list. |
michael@0 | 196 | module_->AddFunctions(functions_.begin(), functions_.end()); |
michael@0 | 197 | functions_.clear(); |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | } // namespace google_breakpad |