toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2diehandler.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 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
    31 // dwarf2diehandler.cc: Implement the dwarf2reader::DieDispatcher class.
    32 // See dwarf2diehandler.h for details.
    34 #include <assert.h>
    36 #include <string>
    38 #include "common/dwarf/dwarf2diehandler.h"
    39 #include "common/using_std_string.h"
    41 namespace dwarf2reader {
    43 DIEDispatcher::~DIEDispatcher() {
    44   while (!die_handlers_.empty()) {
    45     HandlerStack &entry = die_handlers_.top();
    46     if (entry.handler_ != root_handler_)
    47       delete entry.handler_;
    48     die_handlers_.pop();
    49   }
    50 }
    52 bool DIEDispatcher::StartCompilationUnit(uint64 offset, uint8 address_size,
    53                                          uint8 offset_size, uint64 cu_length,
    54                                          uint8 dwarf_version) {
    55   return root_handler_->StartCompilationUnit(offset, address_size,
    56                                              offset_size, cu_length,
    57                                              dwarf_version);
    58 }
    60 bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag) {
    61   // The stack entry for the parent of this DIE, if there is one.
    62   HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top();
    64   // Does this call indicate that we're done receiving the parent's
    65   // attributes' values?  If so, call its EndAttributes member function.
    66   if (parent && parent->handler_ && !parent->reported_attributes_end_) {
    67     parent->reported_attributes_end_ = true;
    68     if (!parent->handler_->EndAttributes()) {
    69       // Finish off this handler now. and edit *PARENT to indicate that
    70       // we don't want to visit any of the children.
    71       parent->handler_->Finish();
    72       if (parent->handler_ != root_handler_)
    73         delete parent->handler_;
    74       parent->handler_ = NULL;
    75       return false;
    76     }
    77   }
    79   // Find a handler for this DIE.
    80   DIEHandler *handler;
    81   if (parent) {
    82     if (parent->handler_)
    83       // Ask the parent to find a handler.
    84       handler = parent->handler_->FindChildHandler(offset, tag);
    85     else
    86       // No parent handler means we're not interested in any of our
    87       // children.
    88       handler = NULL;
    89   } else {
    90     // This is the root DIE.  For a non-root DIE, the parent's handler
    91     // decides whether to visit it, but the root DIE has no parent
    92     // handler, so we have a special method on the root DIE handler
    93     // itself to decide.
    94     if (root_handler_->StartRootDIE(offset, tag))
    95       handler = root_handler_;
    96     else
    97       handler = NULL;
    98   }
   100   // Push a handler stack entry for this new handler. As an
   101   // optimization, we don't push NULL-handler entries on top of other
   102   // NULL-handler entries; we just let the oldest such entry stand for
   103   // the whole subtree.
   104   if (handler || !parent || parent->handler_) {
   105     HandlerStack entry;
   106     entry.offset_ = offset;
   107     entry.handler_ = handler;
   108     entry.reported_attributes_end_ = false;
   109     die_handlers_.push(entry);
   110   }
   112   return handler != NULL;
   113 }
   115 void DIEDispatcher::EndDIE(uint64 offset) {
   116   assert(!die_handlers_.empty());
   117   HandlerStack *entry = &die_handlers_.top();
   118   if (entry->handler_) {
   119     // This entry had better be the handler for this DIE.
   120     assert(entry->offset_ == offset);
   121     // If a DIE has no children, this EndDIE call indicates that we're
   122     // done receiving its attributes' values.
   123     if (!entry->reported_attributes_end_)
   124       entry->handler_->EndAttributes(); // Ignore return value: no children.
   125     entry->handler_->Finish();
   126     if (entry->handler_ != root_handler_)
   127       delete entry->handler_;
   128   } else {
   129     // If this DIE is within a tree we're ignoring, then don't pop the
   130     // handler stack: that entry stands for the whole tree.
   131     if (entry->offset_ != offset)
   132       return;
   133   }
   134   die_handlers_.pop();
   135 }
   137 void DIEDispatcher::ProcessAttributeUnsigned(uint64 offset,
   138                                              enum DwarfAttribute attr,
   139                                              enum DwarfForm form,
   140                                              uint64 data) {
   141   HandlerStack &current = die_handlers_.top();
   142   // This had better be an attribute of the DIE we were meant to handle.
   143   assert(offset == current.offset_);
   144   current.handler_->ProcessAttributeUnsigned(attr, form, data);
   145 }
   147 void DIEDispatcher::ProcessAttributeSigned(uint64 offset,
   148                                            enum DwarfAttribute attr,
   149                                            enum DwarfForm form,
   150                                            int64 data) {
   151   HandlerStack &current = die_handlers_.top();
   152   // This had better be an attribute of the DIE we were meant to handle.
   153   assert(offset == current.offset_);
   154   current.handler_->ProcessAttributeSigned(attr, form, data);
   155 }
   157 void DIEDispatcher::ProcessAttributeReference(uint64 offset,
   158                                               enum DwarfAttribute attr,
   159                                               enum DwarfForm form,
   160                                               uint64 data) {
   161   HandlerStack &current = die_handlers_.top();
   162   // This had better be an attribute of the DIE we were meant to handle.
   163   assert(offset == current.offset_);
   164   current.handler_->ProcessAttributeReference(attr, form, data);
   165 }
   167 void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
   168                                            enum DwarfAttribute attr,
   169                                            enum DwarfForm form,
   170                                            const char* data,
   171                                            uint64 len) {
   172   HandlerStack &current = die_handlers_.top();
   173   // This had better be an attribute of the DIE we were meant to handle.
   174   assert(offset == current.offset_);
   175   current.handler_->ProcessAttributeBuffer(attr, form, data, len);
   176 }
   178 void DIEDispatcher::ProcessAttributeString(uint64 offset,
   179                                            enum DwarfAttribute attr,
   180                                            enum DwarfForm form,
   181                                            const string& data) {
   182   HandlerStack &current = die_handlers_.top();
   183   // This had better be an attribute of the DIE we were meant to handle.
   184   assert(offset == current.offset_);
   185   current.handler_->ProcessAttributeString(attr, form, data);
   186 }
   188 void DIEDispatcher::ProcessAttributeSignature(uint64 offset,
   189                                               enum DwarfAttribute attr,
   190                                               enum DwarfForm form,
   191                                               uint64 signature) {
   192   HandlerStack &current = die_handlers_.top();
   193   // This had better be an attribute of the DIE we were meant to handle.
   194   assert(offset == current.offset_);
   195   current.handler_->ProcessAttributeSignature(attr, form, signature);
   196 }
   198 } // namespace dwarf2reader

mercurial