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-06-02 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