mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-22 05:33:32 +02:00
* Added breakpad support for Linux.
This commit is contained in:
186
thirdparty/breakpad/common/dwarf/dwarf2diehandler.cc
vendored
Normal file
186
thirdparty/breakpad/common/dwarf/dwarf2diehandler.cc
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright (c) 2010 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
|
||||
|
||||
// dwarf2diehandler.cc: Implement the dwarf2reader::DieDispatcher class.
|
||||
// See dwarf2diehandler.h for details.
|
||||
|
||||
#include "common/dwarf/dwarf2diehandler.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace dwarf2reader {
|
||||
|
||||
DIEDispatcher::~DIEDispatcher() {
|
||||
while (!die_handlers_.empty()) {
|
||||
HandlerStack &entry = die_handlers_.top();
|
||||
if (entry.handler_ != root_handler_)
|
||||
delete entry.handler_;
|
||||
die_handlers_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool DIEDispatcher::StartCompilationUnit(uint64 offset, uint8 address_size,
|
||||
uint8 offset_size, uint64 cu_length,
|
||||
uint8 dwarf_version) {
|
||||
return root_handler_->StartCompilationUnit(offset, address_size,
|
||||
offset_size, cu_length,
|
||||
dwarf_version);
|
||||
}
|
||||
|
||||
bool DIEDispatcher::StartDIE(uint64 offset, enum DwarfTag tag,
|
||||
const AttributeList& attrs) {
|
||||
// The stack entry for the parent of this DIE, if there is one.
|
||||
HandlerStack *parent = die_handlers_.empty() ? NULL : &die_handlers_.top();
|
||||
|
||||
// Does this call indicate that we're done receiving the parent's
|
||||
// attributes' values? If so, call its EndAttributes member function.
|
||||
if (parent && parent->handler_ && !parent->reported_attributes_end_) {
|
||||
parent->reported_attributes_end_ = true;
|
||||
if (!parent->handler_->EndAttributes()) {
|
||||
// Finish off this handler now. and edit *PARENT to indicate that
|
||||
// we don't want to visit any of the children.
|
||||
parent->handler_->Finish();
|
||||
if (parent->handler_ != root_handler_)
|
||||
delete parent->handler_;
|
||||
parent->handler_ = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a handler for this DIE.
|
||||
DIEHandler *handler;
|
||||
if (parent) {
|
||||
if (parent->handler_)
|
||||
// Ask the parent to find a handler.
|
||||
handler = parent->handler_->FindChildHandler(offset, tag, attrs);
|
||||
else
|
||||
// No parent handler means we're not interested in any of our
|
||||
// children.
|
||||
handler = NULL;
|
||||
} else {
|
||||
// This is the root DIE. For a non-root DIE, the parent's handler
|
||||
// decides whether to visit it, but the root DIE has no parent
|
||||
// handler, so we have a special method on the root DIE handler
|
||||
// itself to decide.
|
||||
if (root_handler_->StartRootDIE(offset, tag, attrs))
|
||||
handler = root_handler_;
|
||||
else
|
||||
handler = NULL;
|
||||
}
|
||||
|
||||
// Push a handler stack entry for this new handler. As an
|
||||
// optimization, we don't push NULL-handler entries on top of other
|
||||
// NULL-handler entries; we just let the oldest such entry stand for
|
||||
// the whole subtree.
|
||||
if (handler || !parent || parent->handler_) {
|
||||
HandlerStack entry;
|
||||
entry.offset_ = offset;
|
||||
entry.handler_ = handler;
|
||||
entry.reported_attributes_end_ = false;
|
||||
die_handlers_.push(entry);
|
||||
}
|
||||
|
||||
return handler != NULL;
|
||||
}
|
||||
|
||||
void DIEDispatcher::EndDIE(uint64 offset) {
|
||||
assert(!die_handlers_.empty());
|
||||
HandlerStack *entry = &die_handlers_.top();
|
||||
if (entry->handler_) {
|
||||
// This entry had better be the handler for this DIE.
|
||||
assert(entry->offset_ == offset);
|
||||
// If a DIE has no children, this EndDIE call indicates that we're
|
||||
// done receiving its attributes' values.
|
||||
if (!entry->reported_attributes_end_)
|
||||
entry->handler_->EndAttributes(); // Ignore return value: no children.
|
||||
entry->handler_->Finish();
|
||||
if (entry->handler_ != root_handler_)
|
||||
delete entry->handler_;
|
||||
} else {
|
||||
// If this DIE is within a tree we're ignoring, then don't pop the
|
||||
// handler stack: that entry stands for the whole tree.
|
||||
if (entry->offset_ != offset)
|
||||
return;
|
||||
}
|
||||
die_handlers_.pop();
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeUnsigned(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data) {
|
||||
HandlerStack ¤t = die_handlers_.top();
|
||||
// This had better be an attribute of the DIE we were meant to handle.
|
||||
assert(offset == current.offset_);
|
||||
current.handler_->ProcessAttributeUnsigned(attr, form, data);
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeSigned(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
int64 data) {
|
||||
HandlerStack ¤t = die_handlers_.top();
|
||||
// This had better be an attribute of the DIE we were meant to handle.
|
||||
assert(offset == current.offset_);
|
||||
current.handler_->ProcessAttributeSigned(attr, form, data);
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeReference(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data) {
|
||||
HandlerStack ¤t = die_handlers_.top();
|
||||
// This had better be an attribute of the DIE we were meant to handle.
|
||||
assert(offset == current.offset_);
|
||||
current.handler_->ProcessAttributeReference(attr, form, data);
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const char* data,
|
||||
uint64 len) {
|
||||
HandlerStack ¤t = die_handlers_.top();
|
||||
// This had better be an attribute of the DIE we were meant to handle.
|
||||
assert(offset == current.offset_);
|
||||
current.handler_->ProcessAttributeBuffer(attr, form, data, len);
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string& data) {
|
||||
HandlerStack ¤t = die_handlers_.top();
|
||||
// This had better be an attribute of the DIE we were meant to handle.
|
||||
assert(offset == current.offset_);
|
||||
current.handler_->ProcessAttributeString(attr, form, data);
|
||||
}
|
||||
|
||||
} // namespace dwarf2reader
|
Reference in New Issue
Block a user