LCOV - app.info - toolkit/crashreporter/google-breakpad/src/common/stabs_to_module.cc

LCOV - code coverage report
| Current view: | directory - toolkit/crashreporter/google-breakpad/src/common - stabs_to_module.cc (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 88 | 0 | 0.0 %
| Date: | 2012-04-07 | Functions: | 10 | 0 | 0.0 %

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

Generated by: LCOV version 1.7