toolkit/crashreporter/google-breakpad/src/common/dwarf/functioninfo.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2010 Google Inc. All Rights Reserved.
     2 //
     3 // Redistribution and use in source and binary forms, with or without
     4 // modification, are permitted provided that the following conditions are
     5 // met:
     6 //
     7 //     * Redistributions of source code must retain the above copyright
     8 // notice, this list of conditions and the following disclaimer.
     9 //     * Redistributions in binary form must reproduce the above
    10 // copyright notice, this list of conditions and the following disclaimer
    11 // in the documentation and/or other materials provided with the
    12 // distribution.
    13 //     * Neither the name of Google Inc. nor the names of its
    14 // contributors may be used to endorse or promote products derived from
    15 // this software without specific prior written permission.
    16 //
    17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29 // This is a client for the dwarf2reader to extract function and line
    30 // information from the debug info.
    32 #include <assert.h>
    33 #include <limits.h>
    34 #include <stdio.h>
    36 #include <map>
    37 #include <queue>
    38 #include <vector>
    39 #include <memory>
    41 #include "common/dwarf/functioninfo.h"
    42 #include "common/dwarf/bytereader.h"
    43 #include "common/using_std_string.h"
    45 namespace dwarf2reader {
    47 CULineInfoHandler::CULineInfoHandler(std::vector<SourceFileInfo>* files,
    48                                      std::vector<string>* dirs,
    49                                      LineMap* linemap):linemap_(linemap),
    50                                                        files_(files),
    51                                                        dirs_(dirs) {
    52   // The dirs and files are 1 indexed, so just make sure we put
    53   // nothing in the 0 vector.
    54   assert(dirs->size() == 0);
    55   assert(files->size() == 0);
    56   dirs->push_back("");
    57   SourceFileInfo s;
    58   s.name = "";
    59   s.lowpc = ULLONG_MAX;
    60   files->push_back(s);
    61 }
    63 void CULineInfoHandler::DefineDir(const string& name, uint32 dir_num) {
    64   // These should never come out of order, actually
    65   assert(dir_num == dirs_->size());
    66   dirs_->push_back(name);
    67 }
    69 void CULineInfoHandler::DefineFile(const string& name,
    70                                    int32 file_num, uint32 dir_num,
    71                                    uint64 mod_time, uint64 length) {
    72   assert(dir_num >= 0);
    73   assert(dir_num < dirs_->size());
    75   // These should never come out of order, actually.
    76   if (file_num == (int32)files_->size() || file_num == -1) {
    77     string dir = dirs_->at(dir_num);
    79     SourceFileInfo s;
    80     s.lowpc = ULLONG_MAX;
    82     if (dir == "") {
    83       s.name = name;
    84     } else {
    85       s.name = dir + "/" + name;
    86     }
    88     files_->push_back(s);
    89   } else {
    90     fprintf(stderr, "error in DefineFile");
    91   }
    92 }
    94 void CULineInfoHandler::AddLine(uint64 address, uint64 length, uint32 file_num,
    95                                 uint32 line_num, uint32 column_num) {
    96   if (file_num < files_->size()) {
    97     linemap_->insert(
    98         std::make_pair(address,
    99                        std::make_pair(files_->at(file_num).name.c_str(),
   100                                       line_num)));
   102     if(address < files_->at(file_num).lowpc) {
   103       files_->at(file_num).lowpc = address;
   104     }
   105   } else {
   106     fprintf(stderr,"error in AddLine");
   107   }
   108 }
   110 bool CUFunctionInfoHandler::StartCompilationUnit(uint64 offset,
   111                                                  uint8 address_size,
   112                                                  uint8 offset_size,
   113                                                  uint64 cu_length,
   114                                                  uint8 dwarf_version) {
   115   current_compilation_unit_offset_ = offset;
   116   return true;
   117 }
   120 // For function info, we only care about subprograms and inlined
   121 // subroutines. For line info, the DW_AT_stmt_list lives in the
   122 // compile unit tag.
   124 bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag) {
   125   switch (tag) {
   126     case DW_TAG_subprogram:
   127     case DW_TAG_inlined_subroutine: {
   128       current_function_info_ = new FunctionInfo;
   129       current_function_info_->lowpc = current_function_info_->highpc = 0;
   130       current_function_info_->name = "";
   131       current_function_info_->line = 0;
   132       current_function_info_->file = "";
   133       offset_to_funcinfo_->insert(std::make_pair(offset,
   134                                                  current_function_info_));
   135     };
   136       // FALLTHROUGH
   137     case DW_TAG_compile_unit:
   138       return true;
   139     default:
   140       return false;
   141   }
   142   return false;
   143 }
   145 // Only care about the name attribute for functions
   147 void CUFunctionInfoHandler::ProcessAttributeString(uint64 offset,
   148                                                    enum DwarfAttribute attr,
   149                                                    enum DwarfForm form,
   150                                                    const string &data) {
   151   if (current_function_info_) {
   152     if (attr == DW_AT_name)
   153       current_function_info_->name = data;
   154     else if(attr == DW_AT_MIPS_linkage_name)
   155       current_function_info_->mangled_name = data;
   156   }
   157 }
   159 void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
   160                                                      enum DwarfAttribute attr,
   161                                                      enum DwarfForm form,
   162                                                      uint64 data) {
   163   if (attr == DW_AT_stmt_list) {
   164     SectionMap::const_iterator iter = sections_.find("__debug_line");
   165     assert(iter != sections_.end());
   167     // this should be a scoped_ptr but we dont' use boost :-(
   168     std::auto_ptr<LineInfo> lireader(new LineInfo(iter->second.first + data,
   169                                                   iter->second.second  - data,
   170                                                   reader_, linehandler_));
   171     lireader->Start();
   172   } else if (current_function_info_) {
   173     switch (attr) {
   174       case DW_AT_low_pc:
   175         current_function_info_->lowpc = data;
   176         break;
   177       case DW_AT_high_pc:
   178         current_function_info_->highpc = data;
   179         break;
   180       case DW_AT_decl_line:
   181         current_function_info_->line = data;
   182         break;
   183       case DW_AT_decl_file:
   184         current_function_info_->file = files_->at(data).name;
   185         break;
   186       default:
   187         break;
   188     }
   189   }
   190 }
   192 void CUFunctionInfoHandler::ProcessAttributeReference(uint64 offset,
   193                                                       enum DwarfAttribute attr,
   194                                                       enum DwarfForm form,
   195                                                       uint64 data) {
   196   if (current_function_info_) {
   197     switch (attr) {
   198       case DW_AT_specification: {
   199         // Some functions have a "specification" attribute
   200         // which means they were defined elsewhere. The name
   201         // attribute is not repeated, and must be taken from
   202         // the specification DIE. Here we'll assume that
   203         // any DIE referenced in this manner will already have
   204         // been seen, but that's not really required by the spec.
   205         FunctionMap::iterator iter = offset_to_funcinfo_->find(data);
   206         if (iter != offset_to_funcinfo_->end()) {
   207           current_function_info_->name = iter->second->name;
   208           current_function_info_->mangled_name = iter->second->mangled_name;
   209         } else {
   210           // If you hit this, this code probably needs to be rewritten.
   211           fprintf(stderr, "Error: DW_AT_specification was seen before the referenced DIE! (Looking for DIE at offset %08llx, in DIE at offset %08llx)\n", data, offset);
   212         }
   213         break;
   214       }
   215       default:
   216         break;
   217     }
   218   }
   219 }
   221 void CUFunctionInfoHandler::EndDIE(uint64 offset) {
   222   if (current_function_info_ && current_function_info_->lowpc)
   223     address_to_funcinfo_->insert(std::make_pair(current_function_info_->lowpc,
   224                                                 current_function_info_));
   225 }
   227 }  // namespace dwarf2reader

mercurial