mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-22 21:54:00 +02:00
* Updated breakpad to latest version.
This commit is contained in:
@@ -176,11 +176,21 @@ void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
|
||||
void DIEDispatcher::ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string& data) {
|
||||
const std::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);
|
||||
}
|
||||
|
||||
void DIEDispatcher::ProcessAttributeSignature(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 signature) {
|
||||
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_->ProcessAttributeSignature(attr, form, signature);
|
||||
}
|
||||
|
||||
} // namespace dwarf2reader
|
||||
|
@@ -208,7 +208,10 @@ class DIEHandler {
|
||||
uint64 len) { }
|
||||
virtual void ProcessAttributeString(enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string& data) { }
|
||||
const std::string& data) { }
|
||||
virtual void ProcessAttributeSignature(enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 signture) { }
|
||||
|
||||
// Once we have reported all the DIE's attributes' values, we call
|
||||
// this member function. If it returns false, we skip all the DIE's
|
||||
@@ -313,7 +316,11 @@ class DIEDispatcher: public Dwarf2Handler {
|
||||
void ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string &data);
|
||||
const std::string &data);
|
||||
void ProcessAttributeSignature(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 signature);
|
||||
void EndDIE(uint64 offset);
|
||||
|
||||
private:
|
||||
@@ -347,7 +354,7 @@ class DIEDispatcher: public Dwarf2Handler {
|
||||
// - When we decide to ignore a subtree, we only push an entry on
|
||||
// the stack for the root of the tree being ignored, rather than
|
||||
// pushing lots of stack entries with handler_ set to NULL.
|
||||
stack<HandlerStack> die_handlers_;
|
||||
std::stack<HandlerStack> die_handlers_;
|
||||
|
||||
// The root handler. We don't push it on die_handlers_ until we
|
||||
// actually get the StartDIE call for the root.
|
||||
|
@@ -32,10 +32,16 @@
|
||||
|
||||
// dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher.
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "breakpad_googletest_includes.h"
|
||||
|
||||
#include "common/dwarf/dwarf2diehandler.h"
|
||||
|
||||
using std::make_pair;
|
||||
using std::string;
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::ContainerEq;
|
||||
using ::testing::ElementsAreArray;
|
||||
@@ -65,6 +71,8 @@ class MockDIEHandler: public DIEHandler {
|
||||
void(DwarfAttribute, DwarfForm, const char *, uint64));
|
||||
MOCK_METHOD3(ProcessAttributeString,
|
||||
void(DwarfAttribute, DwarfForm, const string &));
|
||||
MOCK_METHOD3(ProcessAttributeSignature,
|
||||
void(DwarfAttribute, DwarfForm, uint64));
|
||||
MOCK_METHOD0(EndAttributes, bool());
|
||||
MOCK_METHOD3(FindChildHandler, DIEHandler *(uint64, DwarfTag,
|
||||
const AttributeList &));
|
||||
@@ -83,6 +91,8 @@ class MockRootDIEHandler: public RootDIEHandler {
|
||||
void(DwarfAttribute, DwarfForm, const char *, uint64));
|
||||
MOCK_METHOD3(ProcessAttributeString,
|
||||
void(DwarfAttribute, DwarfForm, const string &));
|
||||
MOCK_METHOD3(ProcessAttributeSignature,
|
||||
void(DwarfAttribute, DwarfForm, uint64));
|
||||
MOCK_METHOD0(EndAttributes, bool());
|
||||
MOCK_METHOD3(FindChildHandler, DIEHandler *(uint64, DwarfTag,
|
||||
const AttributeList &));
|
||||
@@ -238,6 +248,11 @@ TEST(Dwarf2DIEHandler, PassAttributeValues) {
|
||||
(DwarfForm) 0x15762fec,
|
||||
StrEq(str)))
|
||||
.WillOnce(Return());
|
||||
EXPECT_CALL(mock_root_handler,
|
||||
ProcessAttributeSignature((DwarfAttribute) 0x58790d72,
|
||||
(DwarfForm) 0x4159f138,
|
||||
0x94682463613e6a5fULL))
|
||||
.WillOnce(Return());
|
||||
EXPECT_CALL(mock_root_handler, EndAttributes())
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(mock_root_handler, FindChildHandler(_, _, _))
|
||||
@@ -279,6 +294,10 @@ TEST(Dwarf2DIEHandler, PassAttributeValues) {
|
||||
(DwarfAttribute) 0x310ed065,
|
||||
(DwarfForm) 0x15762fec,
|
||||
str);
|
||||
die_dispatcher.ProcessAttributeSignature(0xe2222da01e29f2a9LL,
|
||||
(DwarfAttribute) 0x58790d72,
|
||||
(DwarfForm) 0x4159f138,
|
||||
0x94682463613e6a5fULL);
|
||||
|
||||
// Finish the root DIE (and thus the CU).
|
||||
die_dispatcher.EndDIE(0xe2222da01e29f2a9LL);
|
||||
|
@@ -143,7 +143,13 @@ enum DwarfForm {
|
||||
DW_FORM_ref4 = 0x13,
|
||||
DW_FORM_ref8 = 0x14,
|
||||
DW_FORM_ref_udata = 0x15,
|
||||
DW_FORM_indirect = 0x16
|
||||
DW_FORM_indirect = 0x16,
|
||||
|
||||
// Added in DWARF 4:
|
||||
DW_FORM_sec_offset = 0x17,
|
||||
DW_FORM_exprloc = 0x18,
|
||||
DW_FORM_flag_present = 0x19,
|
||||
DW_FORM_ref_sig8 = 0x20
|
||||
};
|
||||
|
||||
// Attribute names and codes
|
||||
|
123
thirdparty/breakpad/common/dwarf/dwarf2reader.cc
vendored
123
thirdparty/breakpad/common/dwarf/dwarf2reader.cc
vendored
@@ -39,6 +39,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <utility>
|
||||
|
||||
@@ -74,7 +75,7 @@ void CompilationUnit::ReadAbbrevs() {
|
||||
iter = sections_.find("__debug_abbrev");
|
||||
assert(iter != sections_.end());
|
||||
|
||||
abbrevs_ = new vector<Abbrev>;
|
||||
abbrevs_ = new std::vector<Abbrev>;
|
||||
abbrevs_->resize(1);
|
||||
|
||||
// The only way to check whether we are reading over the end of the
|
||||
@@ -121,7 +122,7 @@ void CompilationUnit::ReadAbbrevs() {
|
||||
const enum DwarfAttribute name =
|
||||
static_cast<enum DwarfAttribute>(nametemp);
|
||||
const enum DwarfForm form = static_cast<enum DwarfForm>(formtemp);
|
||||
abbrev.attributes.push_back(make_pair(name, form));
|
||||
abbrev.attributes.push_back(std::make_pair(name, form));
|
||||
}
|
||||
assert(abbrev.number == abbrevs_->size());
|
||||
abbrevs_->push_back(abbrev);
|
||||
@@ -150,41 +151,35 @@ const char* CompilationUnit::SkipAttribute(const char* start,
|
||||
&len));
|
||||
start += len;
|
||||
return SkipAttribute(start, form);
|
||||
break;
|
||||
|
||||
case DW_FORM_flag_present:
|
||||
return start;
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_flag:
|
||||
case DW_FORM_ref1:
|
||||
return start + 1;
|
||||
break;
|
||||
case DW_FORM_ref2:
|
||||
case DW_FORM_data2:
|
||||
return start + 2;
|
||||
break;
|
||||
case DW_FORM_ref4:
|
||||
case DW_FORM_data4:
|
||||
return start + 4;
|
||||
break;
|
||||
case DW_FORM_ref8:
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_ref_sig8:
|
||||
return start + 8;
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
return start + strlen(start) + 1;
|
||||
break;
|
||||
case DW_FORM_udata:
|
||||
case DW_FORM_ref_udata:
|
||||
reader_->ReadUnsignedLEB128(start, &len);
|
||||
return start + len;
|
||||
break;
|
||||
|
||||
case DW_FORM_sdata:
|
||||
reader_->ReadSignedLEB128(start, &len);
|
||||
return start + len;
|
||||
break;
|
||||
case DW_FORM_addr:
|
||||
return start + reader_->AddressSize();
|
||||
break;
|
||||
case DW_FORM_ref_addr:
|
||||
// DWARF2 and 3 differ on whether ref_addr is address size or
|
||||
// offset size.
|
||||
@@ -194,27 +189,21 @@ const char* CompilationUnit::SkipAttribute(const char* start,
|
||||
} else if (header_.version == 3) {
|
||||
return start + reader_->OffsetSize();
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_FORM_block1:
|
||||
return start + 1 + reader_->ReadOneByte(start);
|
||||
break;
|
||||
case DW_FORM_block2:
|
||||
return start + 2 + reader_->ReadTwoBytes(start);
|
||||
break;
|
||||
case DW_FORM_block4:
|
||||
return start + 4 + reader_->ReadFourBytes(start);
|
||||
break;
|
||||
case DW_FORM_block: {
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_exprloc: {
|
||||
uint64 size = reader_->ReadUnsignedLEB128(start, &len);
|
||||
return start + size + len;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_strp:
|
||||
return start + reader_->OffsetSize();
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unhandled form type");
|
||||
case DW_FORM_sec_offset:
|
||||
return start + reader_->OffsetSize();
|
||||
}
|
||||
fprintf(stderr,"Unhandled form type");
|
||||
return NULL;
|
||||
@@ -326,85 +315,78 @@ const char* CompilationUnit::ProcessAttribute(
|
||||
&len));
|
||||
start += len;
|
||||
return ProcessAttribute(dieoffset, start, attr, form);
|
||||
break;
|
||||
|
||||
case DW_FORM_flag_present:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1);
|
||||
return start;
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_flag:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadOneByte(start));
|
||||
return start + 1;
|
||||
break;
|
||||
case DW_FORM_data2:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadTwoBytes(start));
|
||||
return start + 2;
|
||||
break;
|
||||
case DW_FORM_data4:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadFourBytes(start));
|
||||
return start + 4;
|
||||
break;
|
||||
case DW_FORM_data8:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadEightBytes(start));
|
||||
return start + 8;
|
||||
break;
|
||||
case DW_FORM_string: {
|
||||
const char* str = start;
|
||||
handler_->ProcessAttributeString(dieoffset, attr, form,
|
||||
str);
|
||||
return start + strlen(str) + 1;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_udata:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadUnsignedLEB128(start,
|
||||
&len));
|
||||
return start + len;
|
||||
break;
|
||||
|
||||
case DW_FORM_sdata:
|
||||
handler_->ProcessAttributeSigned(dieoffset, attr, form,
|
||||
reader_->ReadSignedLEB128(start, &len));
|
||||
return start + len;
|
||||
break;
|
||||
case DW_FORM_addr:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadAddress(start));
|
||||
return start + reader_->AddressSize();
|
||||
break;
|
||||
case DW_FORM_sec_offset:
|
||||
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
|
||||
reader_->ReadOffset(start));
|
||||
return start + reader_->OffsetSize();
|
||||
|
||||
case DW_FORM_ref1:
|
||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||
reader_->ReadOneByte(start)
|
||||
+ offset_from_section_start_);
|
||||
return start + 1;
|
||||
break;
|
||||
case DW_FORM_ref2:
|
||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||
reader_->ReadTwoBytes(start)
|
||||
+ offset_from_section_start_);
|
||||
return start + 2;
|
||||
break;
|
||||
case DW_FORM_ref4:
|
||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||
reader_->ReadFourBytes(start)
|
||||
+ offset_from_section_start_);
|
||||
return start + 4;
|
||||
break;
|
||||
case DW_FORM_ref8:
|
||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||
reader_->ReadEightBytes(start)
|
||||
+ offset_from_section_start_);
|
||||
return start + 8;
|
||||
break;
|
||||
case DW_FORM_ref_udata:
|
||||
handler_->ProcessAttributeReference(dieoffset, attr, form,
|
||||
reader_->ReadUnsignedLEB128(start,
|
||||
&len)
|
||||
+ offset_from_section_start_);
|
||||
return start + len;
|
||||
break;
|
||||
case DW_FORM_ref_addr:
|
||||
// DWARF2 and 3 differ on whether ref_addr is address size or
|
||||
// offset size.
|
||||
@@ -419,35 +401,36 @@ const char* CompilationUnit::ProcessAttribute(
|
||||
return start + reader_->OffsetSize();
|
||||
}
|
||||
break;
|
||||
case DW_FORM_ref_sig8:
|
||||
handler_->ProcessAttributeSignature(dieoffset, attr, form,
|
||||
reader_->ReadEightBytes(start));
|
||||
return start + 8;
|
||||
|
||||
case DW_FORM_block1: {
|
||||
uint64 datalen = reader_->ReadOneByte(start);
|
||||
handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 1,
|
||||
datalen);
|
||||
datalen);
|
||||
return start + 1 + datalen;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_block2: {
|
||||
uint64 datalen = reader_->ReadTwoBytes(start);
|
||||
handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 2,
|
||||
datalen);
|
||||
datalen);
|
||||
return start + 2 + datalen;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_block4: {
|
||||
uint64 datalen = reader_->ReadFourBytes(start);
|
||||
handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + 4,
|
||||
datalen);
|
||||
datalen);
|
||||
return start + 4 + datalen;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_block: {
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_exprloc: {
|
||||
uint64 datalen = reader_->ReadUnsignedLEB128(start, &len);
|
||||
handler_->ProcessAttributeBuffer(dieoffset, attr, form, start + len,
|
||||
datalen);
|
||||
datalen);
|
||||
return start + datalen + len;
|
||||
}
|
||||
break;
|
||||
case DW_FORM_strp: {
|
||||
assert(string_buffer_ != NULL);
|
||||
|
||||
@@ -459,11 +442,8 @@ const char* CompilationUnit::ProcessAttribute(
|
||||
str);
|
||||
return start + reader_->OffsetSize();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unhandled form type");
|
||||
}
|
||||
fprintf(stderr, "Unhandled form type");
|
||||
fprintf(stderr, "Unhandled form type\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -493,7 +473,7 @@ void CompilationUnit::ProcessDIEs() {
|
||||
else
|
||||
lengthstart += 4;
|
||||
|
||||
stack<uint64> die_stack;
|
||||
std::stack<uint64> die_stack;
|
||||
|
||||
while (dieptr < (lengthstart + header_.length)) {
|
||||
// We give the user the absolute offset from the beginning of
|
||||
@@ -583,7 +563,7 @@ void LineInfo::ReadHeader() {
|
||||
header_.opcode_base = reader_->ReadOneByte(lineptr);
|
||||
lineptr += 1;
|
||||
|
||||
header_.std_opcode_lengths = new vector<unsigned char>;
|
||||
header_.std_opcode_lengths = new std::vector<unsigned char>;
|
||||
header_.std_opcode_lengths->resize(header_.opcode_base + 1);
|
||||
(*header_.std_opcode_lengths)[0] = 0;
|
||||
for (int i = 1; i < header_.opcode_base; i++) {
|
||||
@@ -1024,7 +1004,7 @@ class CallFrameInfo::RegisterRule: public CallFrameInfo::Rule {
|
||||
// Rule: EXPRESSION evaluates to the address at which the register is saved.
|
||||
class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
|
||||
public:
|
||||
explicit ExpressionRule(const string &expression)
|
||||
explicit ExpressionRule(const std::string &expression)
|
||||
: expression_(expression) { }
|
||||
~ExpressionRule() { }
|
||||
bool Handle(Handler *handler, uint64 address, int reg) const {
|
||||
@@ -1038,13 +1018,13 @@ class CallFrameInfo::ExpressionRule: public CallFrameInfo::Rule {
|
||||
}
|
||||
Rule *Copy() const { return new ExpressionRule(*this); }
|
||||
private:
|
||||
string expression_;
|
||||
std::string expression_;
|
||||
};
|
||||
|
||||
// Rule: EXPRESSION evaluates to the address at which the register is saved.
|
||||
class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
|
||||
public:
|
||||
explicit ValExpressionRule(const string &expression)
|
||||
explicit ValExpressionRule(const std::string &expression)
|
||||
: expression_(expression) { }
|
||||
~ValExpressionRule() { }
|
||||
bool Handle(Handler *handler, uint64 address, int reg) const {
|
||||
@@ -1059,7 +1039,7 @@ class CallFrameInfo::ValExpressionRule: public CallFrameInfo::Rule {
|
||||
}
|
||||
Rule *Copy() const { return new ValExpressionRule(*this); }
|
||||
private:
|
||||
string expression_;
|
||||
std::string expression_;
|
||||
};
|
||||
|
||||
// A map from register numbers to rules.
|
||||
@@ -1096,7 +1076,7 @@ class CallFrameInfo::RuleMap {
|
||||
|
||||
private:
|
||||
// A map from register numbers to Rules.
|
||||
typedef map<int, Rule *> RuleByNumber;
|
||||
typedef std::map<int, Rule *> RuleByNumber;
|
||||
|
||||
// Remove all register rules and clear cfa_rule_.
|
||||
void Clear();
|
||||
@@ -1240,7 +1220,7 @@ class CallFrameInfo::State {
|
||||
unsigned register_number; // A register number.
|
||||
uint64 offset; // An offset or address.
|
||||
long signed_offset; // A signed offset.
|
||||
string expression; // A DWARF expression.
|
||||
std::string expression; // A DWARF expression.
|
||||
};
|
||||
|
||||
// Parse CFI instruction operands from STATE's instruction stream as
|
||||
@@ -1341,7 +1321,7 @@ class CallFrameInfo::State {
|
||||
|
||||
// A stack of saved states, for DW_CFA_remember_state and
|
||||
// DW_CFA_restore_state.
|
||||
stack<RuleMap> saved_rules_;
|
||||
std::stack<RuleMap> saved_rules_;
|
||||
};
|
||||
|
||||
bool CallFrameInfo::State::InterpretCIE(const CIE &cie) {
|
||||
@@ -1427,7 +1407,7 @@ bool CallFrameInfo::State::ParseOperands(const char *format,
|
||||
if (len > bytes_left || expression_length > bytes_left - len)
|
||||
return ReportIncomplete();
|
||||
cursor_ += len;
|
||||
operands->expression = string(cursor_, expression_length);
|
||||
operands->expression = std::string(cursor_, expression_length);
|
||||
cursor_ += expression_length;
|
||||
break;
|
||||
}
|
||||
@@ -1877,20 +1857,14 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
|
||||
cie->version = reader_->ReadOneByte(cursor);
|
||||
cursor++;
|
||||
|
||||
// If we don't recognize the version, we can't parse any more fields
|
||||
// of the CIE. For DWARF CFI, we handle versions 1 through 3 (there
|
||||
// was never a version 2 of CFI data). For .eh_frame, we handle only
|
||||
// version 1.
|
||||
if (eh_frame_) {
|
||||
if (cie->version != 1) {
|
||||
reporter_->UnrecognizedVersion(cie->offset, cie->version);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (cie->version < 1 || cie->version > 3) {
|
||||
reporter_->UnrecognizedVersion(cie->offset, cie->version);
|
||||
return false;
|
||||
}
|
||||
// If we don't recognize the version, we can't parse any more fields of the
|
||||
// CIE. For DWARF CFI, we handle versions 1 through 3 (there was never a
|
||||
// version 2 of CFI data). For .eh_frame, we handle versions 1 and 3 as well;
|
||||
// the difference between those versions seems to be the same as for
|
||||
// .debug_frame.
|
||||
if (cie->version < 1 || cie->version > 3) {
|
||||
reporter_->UnrecognizedVersion(cie->offset, cie->version);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *augmentation_start = cursor;
|
||||
@@ -1898,7 +1872,8 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
|
||||
memchr(augmentation_start, '\0', cie->end - augmentation_start);
|
||||
if (! augmentation_end) return ReportIncomplete(cie);
|
||||
cursor = static_cast<const char *>(augmentation_end);
|
||||
cie->augmentation = string(augmentation_start, cursor - augmentation_start);
|
||||
cie->augmentation = std::string(augmentation_start,
|
||||
cursor - augmentation_start);
|
||||
// Skip the terminating '\0'.
|
||||
cursor++;
|
||||
|
||||
@@ -2285,7 +2260,7 @@ void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
|
||||
}
|
||||
|
||||
void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
|
||||
const string &aug) {
|
||||
const std::string &aug) {
|
||||
fprintf(stderr,
|
||||
"%s: CFI frame description entry at offset 0x%llx in '%s':"
|
||||
" CIE specifies unrecognized augmentation: '%s'\n",
|
||||
|
44
thirdparty/breakpad/common/dwarf/dwarf2reader.h
vendored
44
thirdparty/breakpad/common/dwarf/dwarf2reader.h
vendored
@@ -50,8 +50,6 @@
|
||||
#include "common/dwarf/dwarf2enums.h"
|
||||
#include "common/dwarf/types.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace dwarf2reader {
|
||||
struct LineStateMachine;
|
||||
class Dwarf2Handler;
|
||||
@@ -59,8 +57,9 @@ class LineInfoHandler;
|
||||
|
||||
// This maps from a string naming a section to a pair containing a
|
||||
// the data for the section, and the size of the section.
|
||||
typedef map<string, pair<const char*, uint64> > SectionMap;
|
||||
typedef list<pair<enum DwarfAttribute, enum DwarfForm> > AttributeList;
|
||||
typedef std::map<std::string, std::pair<const char*, uint64> > SectionMap;
|
||||
typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> >
|
||||
AttributeList;
|
||||
typedef AttributeList::iterator AttributeIterator;
|
||||
typedef AttributeList::const_iterator ConstAttributeIterator;
|
||||
|
||||
@@ -75,7 +74,7 @@ struct LineInfoHeader {
|
||||
uint8 opcode_base;
|
||||
// Use a pointer so that signalsafe_addr2line is able to use this structure
|
||||
// without heap allocation problem.
|
||||
vector<unsigned char> *std_opcode_lengths;
|
||||
std::vector<unsigned char> *std_opcode_lengths;
|
||||
};
|
||||
|
||||
class LineInfo {
|
||||
@@ -157,7 +156,7 @@ class LineInfoHandler {
|
||||
|
||||
// Called when we define a directory. NAME is the directory name,
|
||||
// DIR_NUM is the directory number
|
||||
virtual void DefineDir(const string& name, uint32 dir_num) { }
|
||||
virtual void DefineDir(const std::string& name, uint32 dir_num) { }
|
||||
|
||||
// Called when we define a filename. NAME is the filename, FILE_NUM
|
||||
// is the file number which is -1 if the file index is the next
|
||||
@@ -166,7 +165,7 @@ class LineInfoHandler {
|
||||
// directory index for the directory name of this file, MOD_TIME is
|
||||
// the modification time of the file, and LENGTH is the length of
|
||||
// the file
|
||||
virtual void DefineFile(const string& name, int32 file_num,
|
||||
virtual void DefineFile(const std::string& name, int32 file_num,
|
||||
uint32 dir_num, uint64 mod_time,
|
||||
uint64 length) { }
|
||||
|
||||
@@ -313,7 +312,7 @@ class CompilationUnit {
|
||||
// Set of DWARF2/3 abbreviations for this compilation unit. Indexed
|
||||
// by abbreviation number, which means that abbrevs_[0] is not
|
||||
// valid.
|
||||
vector<Abbrev>* abbrevs_;
|
||||
std::vector<Abbrev>* abbrevs_;
|
||||
|
||||
// String section buffer and length, if we have a string section.
|
||||
// This is here to avoid doing a section lookup for strings in
|
||||
@@ -392,7 +391,16 @@ class Dwarf2Handler {
|
||||
virtual void ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string& data) { }
|
||||
const std::string& data) { }
|
||||
|
||||
// Called when we have an attribute whose value is the 64-bit signature
|
||||
// of a type unit in the .debug_types section. OFFSET is the offset of
|
||||
// the DIE whose attribute we're reporting. ATTR and FORM are the
|
||||
// attribute's name and form. SIGNATURE is the type unit's signature.
|
||||
virtual void ProcessAttributeSignature(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 signature) { }
|
||||
|
||||
// Called when finished processing the DIE at OFFSET.
|
||||
// Because DWARF2/3 specifies a tree of DIEs, you may get starts
|
||||
@@ -691,7 +699,7 @@ class CallFrameInfo {
|
||||
// A common information entry (CIE).
|
||||
struct CIE: public Entry {
|
||||
uint8 version; // CFI data version number
|
||||
string augmentation; // vendor format extension markers
|
||||
std::string augmentation; // vendor format extension markers
|
||||
uint64 code_alignment_factor; // scale for code address adjustments
|
||||
int data_alignment_factor; // scale for stack pointer adjustments
|
||||
unsigned return_address_register; // which register holds the return addr
|
||||
@@ -825,7 +833,7 @@ class CallFrameInfo::Handler {
|
||||
// process a given FDE, the parser reiterates the appropriate CIE's
|
||||
// contents at the beginning of the FDE's rules.
|
||||
virtual bool Entry(size_t offset, uint64 address, uint64 length,
|
||||
uint8 version, const string &augmentation,
|
||||
uint8 version, const std::string &augmentation,
|
||||
unsigned return_address) = 0;
|
||||
|
||||
// When the Entry function returns true, the parser calls these
|
||||
@@ -874,13 +882,13 @@ class CallFrameInfo::Handler {
|
||||
// At ADDRESS, the DWARF expression EXPRESSION yields the address at
|
||||
// which REG was saved.
|
||||
virtual bool ExpressionRule(uint64 address, int reg,
|
||||
const string &expression) = 0;
|
||||
const std::string &expression) = 0;
|
||||
|
||||
// At ADDRESS, the DWARF expression EXPRESSION yields the caller's
|
||||
// value for REG. (This rule doesn't provide an address at which the
|
||||
// register's value is saved.)
|
||||
virtual bool ValExpressionRule(uint64 address, int reg,
|
||||
const string &expression) = 0;
|
||||
const std::string &expression) = 0;
|
||||
|
||||
// Indicate that the rules for the address range reported by the
|
||||
// last call to Entry are complete. End should return true if
|
||||
@@ -957,8 +965,8 @@ class CallFrameInfo::Reporter {
|
||||
// in a Mach-O section named __debug_frame. If we support
|
||||
// Linux-style exception handling data, we could be reading an
|
||||
// .eh_frame section.
|
||||
Reporter(const string &filename,
|
||||
const string §ion = ".debug_frame")
|
||||
Reporter(const std::string &filename,
|
||||
const std::string §ion = ".debug_frame")
|
||||
: filename_(filename), section_(section) { }
|
||||
virtual ~Reporter() { }
|
||||
|
||||
@@ -990,7 +998,7 @@ class CallFrameInfo::Reporter {
|
||||
// which we don't recognize. We cannot parse DWARF CFI if it uses
|
||||
// augmentations we don't recognize.
|
||||
virtual void UnrecognizedAugmentation(uint64 offset,
|
||||
const string &augmentation);
|
||||
const std::string &augmentation);
|
||||
|
||||
// The pointer encoding ENCODING, specified by the CIE at OFFSET, is not
|
||||
// a valid encoding.
|
||||
@@ -1031,10 +1039,10 @@ class CallFrameInfo::Reporter {
|
||||
|
||||
protected:
|
||||
// The name of the file whose CFI we're reading.
|
||||
string filename_;
|
||||
std::string filename_;
|
||||
|
||||
// The name of the CFI section in that file.
|
||||
string section_;
|
||||
std::string section_;
|
||||
};
|
||||
|
||||
} // namespace dwarf2reader
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// The '.eh_frame' format, used by the Linux C++ ABI for exception
|
||||
@@ -75,6 +76,7 @@ using dwarf2reader::ENDIANNESS_LITTLE;
|
||||
using dwarf2reader::ByteReader;
|
||||
using dwarf2reader::CallFrameInfo;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using testing::InSequence;
|
||||
using testing::Return;
|
||||
|
486
thirdparty/breakpad/common/dwarf/dwarf2reader_die_unittest.cc
vendored
Normal file
486
thirdparty/breakpad/common/dwarf/dwarf2reader_die_unittest.cc
vendored
Normal file
@@ -0,0 +1,486 @@
|
||||
// Copyright (c) 2012, 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>
|
||||
|
||||
// dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "breakpad_googletest_includes.h"
|
||||
#include "common/dwarf/bytereader-inl.h"
|
||||
#include "common/dwarf/dwarf2reader_test_common.h"
|
||||
#include "common/dwarf/dwarf2reader.h"
|
||||
#include "google_breakpad/common/breakpad_types.h"
|
||||
|
||||
using google_breakpad::test_assembler::Endianness;
|
||||
using google_breakpad::test_assembler::Label;
|
||||
using google_breakpad::test_assembler::Section;
|
||||
using google_breakpad::test_assembler::kBigEndian;
|
||||
using google_breakpad::test_assembler::kLittleEndian;
|
||||
|
||||
using dwarf2reader::AttributeList;
|
||||
using dwarf2reader::ByteReader;
|
||||
using dwarf2reader::CompilationUnit;
|
||||
using dwarf2reader::Dwarf2Handler;
|
||||
using dwarf2reader::DwarfAttribute;
|
||||
using dwarf2reader::DwarfForm;
|
||||
using dwarf2reader::DwarfHasChild;
|
||||
using dwarf2reader::DwarfTag;
|
||||
using dwarf2reader::ENDIANNESS_BIG;
|
||||
using dwarf2reader::ENDIANNESS_LITTLE;
|
||||
using dwarf2reader::SectionMap;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using testing::InSequence;
|
||||
using testing::Pointee;
|
||||
using testing::Return;
|
||||
using testing::Sequence;
|
||||
using testing::Test;
|
||||
using testing::TestWithParam;
|
||||
using testing::_;
|
||||
|
||||
class MockDwarf2Handler: public Dwarf2Handler {
|
||||
public:
|
||||
MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size,
|
||||
uint8 offset_size, uint64 cu_length,
|
||||
uint8 dwarf_version));
|
||||
MOCK_METHOD3(StartDIE, bool(uint64 offset, enum DwarfTag tag,
|
||||
const AttributeList& attrs));
|
||||
MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset,
|
||||
DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data));
|
||||
MOCK_METHOD4(ProcessAttributeSigned, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
int64 data));
|
||||
MOCK_METHOD4(ProcessAttributeReference, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 data));
|
||||
MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const char* data,
|
||||
uint64 len));
|
||||
MOCK_METHOD4(ProcessAttributeString, void(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const std::string& data));
|
||||
MOCK_METHOD4(ProcessAttributeSignature, void(uint64 offset,
|
||||
DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
uint64 signature));
|
||||
MOCK_METHOD1(EndDIE, void(uint64 offset));
|
||||
};
|
||||
|
||||
struct DIEFixture {
|
||||
|
||||
DIEFixture() {
|
||||
// Fix the initial offset of the .debug_info and .debug_abbrev sections.
|
||||
info.start() = 0;
|
||||
abbrevs.start() = 0;
|
||||
|
||||
// Default expectations for the data handler.
|
||||
EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, StartDIE(_, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, _, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, ProcessAttributeString(_, _, _, _)).Times(0);
|
||||
EXPECT_CALL(handler, EndDIE(_)).Times(0);
|
||||
}
|
||||
|
||||
// Return a reference to a section map whose .debug_info section refers
|
||||
// to |info|, and whose .debug_abbrev section refers to |abbrevs|. This
|
||||
// function returns a reference to the same SectionMap each time; new
|
||||
// calls wipe out maps established by earlier calls.
|
||||
const SectionMap &MakeSectionMap() {
|
||||
// Copy the sections' contents into strings that will live as long as
|
||||
// the map itself.
|
||||
assert(info.GetContents(&info_contents));
|
||||
assert(abbrevs.GetContents(&abbrevs_contents));
|
||||
section_map.clear();
|
||||
section_map[".debug_info"].first = info_contents.data();
|
||||
section_map[".debug_info"].second = info_contents.size();
|
||||
section_map[".debug_abbrev"].first = abbrevs_contents.data();
|
||||
section_map[".debug_abbrev"].second = abbrevs_contents.size();
|
||||
return section_map;
|
||||
}
|
||||
|
||||
TestCompilationUnit info;
|
||||
TestAbbrevTable abbrevs;
|
||||
MockDwarf2Handler handler;
|
||||
string abbrevs_contents, info_contents;
|
||||
SectionMap section_map;
|
||||
};
|
||||
|
||||
struct DwarfHeaderParams {
|
||||
DwarfHeaderParams(Endianness endianness, size_t format_size,
|
||||
int version, size_t address_size)
|
||||
: endianness(endianness), format_size(format_size),
|
||||
version(version), address_size(address_size) { }
|
||||
Endianness endianness;
|
||||
size_t format_size; // 4-byte or 8-byte DWARF offsets
|
||||
int version;
|
||||
size_t address_size;
|
||||
};
|
||||
|
||||
class DwarfHeader: public DIEFixture,
|
||||
public TestWithParam<DwarfHeaderParams> { };
|
||||
|
||||
TEST_P(DwarfHeader, Header) {
|
||||
Label abbrev_table = abbrevs.Here();
|
||||
abbrevs.Abbrev(1, dwarf2reader::DW_TAG_compile_unit,
|
||||
dwarf2reader::DW_children_yes)
|
||||
.Attribute(dwarf2reader::DW_AT_name, dwarf2reader::DW_FORM_string)
|
||||
.EndAbbrev()
|
||||
.EndTable();
|
||||
|
||||
info.set_format_size(GetParam().format_size);
|
||||
info.set_endianness(GetParam().endianness);
|
||||
|
||||
info.Header(GetParam().version, abbrev_table, GetParam().address_size)
|
||||
.ULEB128(1) // DW_TAG_compile_unit, with children
|
||||
.AppendCString("sam") // DW_AT_name, DW_FORM_string
|
||||
.D8(0); // end of children
|
||||
info.Finish();
|
||||
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(handler,
|
||||
StartCompilationUnit(0, GetParam().address_size,
|
||||
GetParam().format_size, _,
|
||||
GetParam().version))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit, _))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name,
|
||||
dwarf2reader::DW_FORM_string,
|
||||
"sam"))
|
||||
.WillOnce(Return());
|
||||
EXPECT_CALL(handler, EndDIE(_))
|
||||
.WillOnce(Return());
|
||||
}
|
||||
|
||||
ByteReader byte_reader(GetParam().endianness == kLittleEndian ?
|
||||
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
|
||||
CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler);
|
||||
EXPECT_EQ(parser.Start(), info_contents.size());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HeaderVariants, DwarfHeader,
|
||||
::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 8)));
|
||||
|
||||
struct DwarfFormsFixture: public DIEFixture {
|
||||
// Start a compilation unit, as directed by |params|, containing one
|
||||
// childless DIE of the given tag, with one attribute of the given name
|
||||
// and form. The 'info' fixture member is left just after the abbrev
|
||||
// code, waiting for the attribute value to be appended.
|
||||
void StartSingleAttributeDIE(const DwarfHeaderParams ¶ms,
|
||||
DwarfTag tag, DwarfAttribute name,
|
||||
DwarfForm form) {
|
||||
// Create the abbreviation table.
|
||||
Label abbrev_table = abbrevs.Here();
|
||||
abbrevs.Abbrev(1, tag, dwarf2reader::DW_children_no)
|
||||
.Attribute(name, form)
|
||||
.EndAbbrev()
|
||||
.EndTable();
|
||||
|
||||
// Create the compilation unit, up to the attribute value.
|
||||
info.set_format_size(params.format_size);
|
||||
info.set_endianness(params.endianness);
|
||||
info.Header(params.version, abbrev_table, params.address_size)
|
||||
.ULEB128(1); // abbrev code
|
||||
}
|
||||
|
||||
// Set up handler to expect a compilation unit matching |params|,
|
||||
// containing one childless DIE of the given tag, in the sequence s. Stop
|
||||
// just before the expectations.
|
||||
void ExpectBeginCompilationUnit(const DwarfHeaderParams ¶ms,
|
||||
DwarfTag tag, uint64 offset=0) {
|
||||
EXPECT_CALL(handler,
|
||||
StartCompilationUnit(offset, params.address_size,
|
||||
params.format_size, _,
|
||||
params.version))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, StartDIE(_, tag, _))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return(true));
|
||||
}
|
||||
|
||||
void ExpectEndCompilationUnit() {
|
||||
EXPECT_CALL(handler, EndDIE(_))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
}
|
||||
|
||||
void ParseCompilationUnit(const DwarfHeaderParams ¶ms, uint64 offset=0) {
|
||||
ByteReader byte_reader(params.endianness == kLittleEndian ?
|
||||
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
|
||||
CompilationUnit parser(MakeSectionMap(), offset, &byte_reader, &handler);
|
||||
EXPECT_EQ(offset + parser.Start(), info_contents.size());
|
||||
}
|
||||
|
||||
// The sequence to which the fixture's methods append expectations.
|
||||
Sequence s;
|
||||
};
|
||||
|
||||
struct DwarfForms: public DwarfFormsFixture,
|
||||
public TestWithParam<DwarfHeaderParams> { };
|
||||
|
||||
TEST_P(DwarfForms, addr) {
|
||||
StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit,
|
||||
dwarf2reader::DW_AT_low_pc,
|
||||
dwarf2reader::DW_FORM_addr);
|
||||
u_int64_t value;
|
||||
if (GetParam().address_size == 4) {
|
||||
value = 0xc8e9ffcc;
|
||||
info.D32(value);
|
||||
} else {
|
||||
value = 0xe942517fc2768564ULL;
|
||||
info.D64(value);
|
||||
}
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), dwarf2reader::DW_TAG_compile_unit);
|
||||
EXPECT_CALL(handler, ProcessAttributeUnsigned(_, dwarf2reader::DW_AT_low_pc,
|
||||
dwarf2reader::DW_FORM_addr,
|
||||
value))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, block2_empty) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
|
||||
(DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2);
|
||||
info.D16(0);
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2,
|
||||
_, 0))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, block2) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
|
||||
(DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2);
|
||||
unsigned char data[258];
|
||||
memset(data, '*', sizeof(data));
|
||||
info.D16(sizeof(data))
|
||||
.Append(data, sizeof(data));
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
|
||||
dwarf2reader::DW_FORM_block2,
|
||||
Pointee('*'), 258))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, flag_present) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x3e449ac2,
|
||||
(DwarfAttribute) 0x359d1972,
|
||||
dwarf2reader::DW_FORM_flag_present);
|
||||
// DW_FORM_flag_present occupies no space in the DIE.
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x3e449ac2);
|
||||
EXPECT_CALL(handler,
|
||||
ProcessAttributeUnsigned(_, (DwarfAttribute) 0x359d1972,
|
||||
dwarf2reader::DW_FORM_flag_present,
|
||||
1))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, sec_offset) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689,
|
||||
(DwarfAttribute) 0xa060bfd1,
|
||||
dwarf2reader::DW_FORM_sec_offset);
|
||||
u_int64_t value;
|
||||
if (GetParam().format_size == 4) {
|
||||
value = 0xacc9c388;
|
||||
info.D32(value);
|
||||
} else {
|
||||
value = 0xcffe5696ffe3ed0aULL;
|
||||
info.D64(value);
|
||||
}
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x1d971689);
|
||||
EXPECT_CALL(handler, ProcessAttributeUnsigned(_, (DwarfAttribute) 0xa060bfd1,
|
||||
dwarf2reader::DW_FORM_sec_offset,
|
||||
value))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, exprloc) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0xb6d167bb,
|
||||
(DwarfAttribute) 0xba3ae5cb,
|
||||
dwarf2reader::DW_FORM_exprloc);
|
||||
info.ULEB128(29)
|
||||
.Append(29, 173);
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0xb6d167bb);
|
||||
EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xba3ae5cb,
|
||||
dwarf2reader::DW_FORM_exprloc,
|
||||
Pointee(173), 29))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
TEST_P(DwarfForms, ref_sig8) {
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b,
|
||||
(DwarfAttribute) 0xd708d908,
|
||||
dwarf2reader::DW_FORM_ref_sig8);
|
||||
info.D64(0xf72fa0cb6ddcf9d6ULL);
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b);
|
||||
EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908,
|
||||
dwarf2reader::DW_FORM_ref_sig8,
|
||||
0xf72fa0cb6ddcf9d6ULL))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam());
|
||||
}
|
||||
|
||||
// A value passed to ProcessAttributeSignature is just an absolute number,
|
||||
// not an offset within the compilation unit as most of the other
|
||||
// DW_FORM_ref forms are. Check that the reader doesn't try to apply any
|
||||
// offset to the signature, by reading it from a compilation unit that does
|
||||
// not start at the beginning of the section.
|
||||
TEST_P(DwarfForms, ref_sig8_not_first) {
|
||||
info.Append(98, '*');
|
||||
StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b,
|
||||
(DwarfAttribute) 0xd708d908,
|
||||
dwarf2reader::DW_FORM_ref_sig8);
|
||||
info.D64(0xf72fa0cb6ddcf9d6ULL);
|
||||
info.Finish();
|
||||
|
||||
ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b, 98);
|
||||
EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908,
|
||||
dwarf2reader::DW_FORM_ref_sig8,
|
||||
0xf72fa0cb6ddcf9d6ULL))
|
||||
.InSequence(s)
|
||||
.WillOnce(Return());
|
||||
ExpectEndCompilationUnit();
|
||||
|
||||
ParseCompilationUnit(GetParam(), 98);
|
||||
}
|
||||
|
||||
// Tests for the other attribute forms could go here.
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
HeaderVariants, DwarfForms,
|
||||
::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kLittleEndian, 8, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 4, 4, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 2, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 3, 8),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 4),
|
||||
DwarfHeaderParams(kBigEndian, 8, 4, 8)));
|
149
thirdparty/breakpad/common/dwarf/dwarf2reader_test_common.h
vendored
Normal file
149
thirdparty/breakpad/common/dwarf/dwarf2reader_test_common.h
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
// -*- mode: c++ -*-
|
||||
|
||||
// Copyright (c) 2012, 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>
|
||||
|
||||
// dwarf2reader_test_common.h: Define TestCompilationUnit and
|
||||
// TestAbbrevTable, classes for creating properly (and improperly)
|
||||
// formatted DWARF compilation unit data for unit tests.
|
||||
|
||||
#ifndef COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
||||
#define COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
||||
|
||||
#include "common/test_assembler.h"
|
||||
#include "common/dwarf/dwarf2enums.h"
|
||||
|
||||
// A subclass of test_assembler::Section, specialized for constructing
|
||||
// DWARF compilation units.
|
||||
class TestCompilationUnit: public google_breakpad::test_assembler::Section {
|
||||
public:
|
||||
typedef dwarf2reader::DwarfTag DwarfTag;
|
||||
typedef dwarf2reader::DwarfAttribute DwarfAttribute;
|
||||
typedef dwarf2reader::DwarfForm DwarfForm;
|
||||
typedef google_breakpad::test_assembler::Label Label;
|
||||
|
||||
// Set the section's DWARF format size (the 32-bit DWARF format or the
|
||||
// 64-bit DWARF format, for lengths and section offsets --- not the
|
||||
// address size) to format_size.
|
||||
void set_format_size(size_t format_size) {
|
||||
assert(format_size == 4 || format_size == 8);
|
||||
format_size_ = format_size;
|
||||
}
|
||||
|
||||
// Append a DWARF section offset value, of the appropriate size for this
|
||||
// compilation unit.
|
||||
template<typename T>
|
||||
void SectionOffset(T offset) {
|
||||
if (format_size_ == 4)
|
||||
D32(offset);
|
||||
else
|
||||
D64(offset);
|
||||
}
|
||||
|
||||
// Append a DWARF compilation unit header to the section, with the given
|
||||
// DWARF version, abbrev table offset, and address size.
|
||||
TestCompilationUnit &Header(int version, const Label &abbrev_offset,
|
||||
size_t address_size) {
|
||||
if (format_size_ == 4) {
|
||||
D32(length_);
|
||||
} else {
|
||||
D32(0xffffffff);
|
||||
D64(length_);
|
||||
}
|
||||
post_length_offset_ = Size();
|
||||
D16(version);
|
||||
SectionOffset(abbrev_offset);
|
||||
D8(address_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Mark the end of this header's DIEs.
|
||||
TestCompilationUnit &Finish() {
|
||||
length_ = Size() - post_length_offset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// The DWARF format size for this compilation unit.
|
||||
size_t format_size_;
|
||||
|
||||
// The offset of the point in the compilation unit header immediately
|
||||
// after the initial length field.
|
||||
u_int64_t post_length_offset_;
|
||||
|
||||
// The length of the compilation unit, not including the initial length field.
|
||||
Label length_;
|
||||
};
|
||||
|
||||
// A subclass of test_assembler::Section specialized for constructing DWARF
|
||||
// abbreviation tables.
|
||||
class TestAbbrevTable: public google_breakpad::test_assembler::Section {
|
||||
public:
|
||||
typedef dwarf2reader::DwarfTag DwarfTag;
|
||||
typedef dwarf2reader::DwarfAttribute DwarfAttribute;
|
||||
typedef dwarf2reader::DwarfForm DwarfForm;
|
||||
typedef dwarf2reader::DwarfHasChild DwarfHasChild;
|
||||
typedef google_breakpad::test_assembler::Label Label;
|
||||
|
||||
// Start a new abbreviation table entry for abbreviation code |code|,
|
||||
// encoding a DIE whose tag is |tag|, and which has children if and only
|
||||
// if |has_children| is true.
|
||||
TestAbbrevTable &Abbrev(int code, DwarfTag tag, DwarfHasChild has_children) {
|
||||
assert(code != 0);
|
||||
ULEB128(code);
|
||||
ULEB128(static_cast<unsigned>(tag));
|
||||
D8(static_cast<unsigned>(has_children));
|
||||
return *this;
|
||||
};
|
||||
|
||||
// Add an attribute to the current abbreviation code whose name is |name|
|
||||
// and whose form is |form|.
|
||||
TestAbbrevTable &Attribute(DwarfAttribute name, DwarfForm form) {
|
||||
ULEB128(static_cast<unsigned>(name));
|
||||
ULEB128(static_cast<unsigned>(form));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Finish the current abbreviation code.
|
||||
TestAbbrevTable &EndAbbrev() {
|
||||
ULEB128(0);
|
||||
ULEB128(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Finish the current abbreviation table.
|
||||
TestAbbrevTable &EndTable() {
|
||||
ULEB128(0);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COMMON_DWARF_DWARF2READER_TEST_COMMON_H__
|
31
thirdparty/breakpad/common/dwarf/functioninfo.cc
vendored
31
thirdparty/breakpad/common/dwarf/functioninfo.cc
vendored
@@ -45,8 +45,8 @@
|
||||
|
||||
namespace dwarf2reader {
|
||||
|
||||
CULineInfoHandler::CULineInfoHandler(vector<SourceFileInfo>* files,
|
||||
vector<string>* dirs,
|
||||
CULineInfoHandler::CULineInfoHandler(std::vector<SourceFileInfo>* files,
|
||||
std::vector<std::string>* dirs,
|
||||
LineMap* linemap):linemap_(linemap),
|
||||
files_(files),
|
||||
dirs_(dirs) {
|
||||
@@ -61,13 +61,13 @@ CULineInfoHandler::CULineInfoHandler(vector<SourceFileInfo>* files,
|
||||
files->push_back(s);
|
||||
}
|
||||
|
||||
void CULineInfoHandler::DefineDir(const string& name, uint32 dir_num) {
|
||||
void CULineInfoHandler::DefineDir(const std::string& name, uint32 dir_num) {
|
||||
// These should never come out of order, actually
|
||||
assert(dir_num == dirs_->size());
|
||||
dirs_->push_back(name);
|
||||
}
|
||||
|
||||
void CULineInfoHandler::DefineFile(const string& name,
|
||||
void CULineInfoHandler::DefineFile(const std::string& name,
|
||||
int32 file_num, uint32 dir_num,
|
||||
uint64 mod_time, uint64 length) {
|
||||
assert(dir_num >= 0);
|
||||
@@ -75,7 +75,7 @@ void CULineInfoHandler::DefineFile(const string& name,
|
||||
|
||||
// These should never come out of order, actually.
|
||||
if (file_num == (int32)files_->size() || file_num == -1) {
|
||||
string dir = dirs_->at(dir_num);
|
||||
std::string dir = dirs_->at(dir_num);
|
||||
|
||||
SourceFileInfo s;
|
||||
s.lowpc = ULLONG_MAX;
|
||||
@@ -95,8 +95,10 @@ void CULineInfoHandler::DefineFile(const string& name,
|
||||
void CULineInfoHandler::AddLine(uint64 address, uint64 length, uint32 file_num,
|
||||
uint32 line_num, uint32 column_num) {
|
||||
if (file_num < files_->size()) {
|
||||
linemap_->insert(make_pair(address, make_pair(files_->at(file_num).name.c_str(),
|
||||
line_num)));
|
||||
linemap_->insert(
|
||||
std::make_pair(address,
|
||||
std::make_pair(files_->at(file_num).name.c_str(),
|
||||
line_num)));
|
||||
|
||||
if(address < files_->at(file_num).lowpc) {
|
||||
files_->at(file_num).lowpc = address;
|
||||
@@ -130,7 +132,8 @@ bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag,
|
||||
current_function_info_->name = "";
|
||||
current_function_info_->line = 0;
|
||||
current_function_info_->file = "";
|
||||
offset_to_funcinfo_->insert(make_pair(offset, current_function_info_));
|
||||
offset_to_funcinfo_->insert(std::make_pair(offset,
|
||||
current_function_info_));
|
||||
};
|
||||
// FALLTHROUGH
|
||||
case DW_TAG_compile_unit:
|
||||
@@ -146,7 +149,7 @@ bool CUFunctionInfoHandler::StartDIE(uint64 offset, enum DwarfTag tag,
|
||||
void CUFunctionInfoHandler::ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string &data) {
|
||||
const std::string &data) {
|
||||
if (current_function_info_) {
|
||||
if (attr == DW_AT_name)
|
||||
current_function_info_->name = data;
|
||||
@@ -164,9 +167,9 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
|
||||
assert(iter != sections_.end());
|
||||
|
||||
// this should be a scoped_ptr but we dont' use boost :-(
|
||||
auto_ptr<LineInfo> lireader(new LineInfo(iter->second.first + data,
|
||||
iter->second.second - data,
|
||||
reader_, linehandler_));
|
||||
std::auto_ptr<LineInfo> lireader(new LineInfo(iter->second.first + data,
|
||||
iter->second.second - data,
|
||||
reader_, linehandler_));
|
||||
lireader->Start();
|
||||
} else if (current_function_info_) {
|
||||
switch (attr) {
|
||||
@@ -219,8 +222,8 @@ void CUFunctionInfoHandler::ProcessAttributeReference(uint64 offset,
|
||||
|
||||
void CUFunctionInfoHandler::EndDIE(uint64 offset) {
|
||||
if (current_function_info_ && current_function_info_->lowpc)
|
||||
address_to_funcinfo_->insert(make_pair(current_function_info_->lowpc,
|
||||
current_function_info_));
|
||||
address_to_funcinfo_->insert(std::make_pair(current_function_info_->lowpc,
|
||||
current_function_info_));
|
||||
}
|
||||
|
||||
} // namespace dwarf2reader
|
||||
|
34
thirdparty/breakpad/common/dwarf/functioninfo.h
vendored
34
thirdparty/breakpad/common/dwarf/functioninfo.h
vendored
@@ -46,11 +46,11 @@ namespace dwarf2reader {
|
||||
|
||||
struct FunctionInfo {
|
||||
// Name of the function
|
||||
string name;
|
||||
std::string name;
|
||||
// Mangled name of the function
|
||||
string mangled_name;
|
||||
std::string mangled_name;
|
||||
// File containing this function
|
||||
string file;
|
||||
std::string file;
|
||||
// Line number for start of function.
|
||||
uint32 line;
|
||||
// Beginning address for this function
|
||||
@@ -61,13 +61,13 @@ struct FunctionInfo {
|
||||
|
||||
struct SourceFileInfo {
|
||||
// Name of the source file name
|
||||
string name;
|
||||
std::string name;
|
||||
// Low address of source file name
|
||||
uint64 lowpc;
|
||||
};
|
||||
|
||||
typedef map<uint64, FunctionInfo*> FunctionMap;
|
||||
typedef map<uint64, pair<string, uint32> > LineMap;
|
||||
typedef std::map<uint64, FunctionInfo*> FunctionMap;
|
||||
typedef std::map<uint64, std::pair<std::string, uint32> > LineMap;
|
||||
|
||||
// This class is a basic line info handler that fills in the dirs,
|
||||
// file, and linemap passed into it with the data produced from the
|
||||
@@ -76,18 +76,18 @@ class CULineInfoHandler: public LineInfoHandler {
|
||||
public:
|
||||
|
||||
//
|
||||
CULineInfoHandler(vector<SourceFileInfo>* files,
|
||||
vector<string>* dirs,
|
||||
CULineInfoHandler(std::vector<SourceFileInfo>* files,
|
||||
std::vector<std::string>* dirs,
|
||||
LineMap* linemap);
|
||||
virtual ~CULineInfoHandler() { }
|
||||
|
||||
// Called when we define a directory. We just place NAME into dirs_
|
||||
// at position DIR_NUM.
|
||||
virtual void DefineDir(const string& name, uint32 dir_num);
|
||||
virtual void DefineDir(const std::string& name, uint32 dir_num);
|
||||
|
||||
// Called when we define a filename. We just place
|
||||
// concat(dirs_[DIR_NUM], NAME) into files_ at position FILE_NUM.
|
||||
virtual void DefineFile(const string& name, int32 file_num,
|
||||
virtual void DefineFile(const std::string& name, int32 file_num,
|
||||
uint32 dir_num, uint64 mod_time, uint64 length);
|
||||
|
||||
|
||||
@@ -102,14 +102,14 @@ class CULineInfoHandler: public LineInfoHandler {
|
||||
|
||||
private:
|
||||
LineMap* linemap_;
|
||||
vector<SourceFileInfo>* files_;
|
||||
vector<string>* dirs_;
|
||||
std::vector<SourceFileInfo>* files_;
|
||||
std::vector<std::string>* dirs_;
|
||||
};
|
||||
|
||||
class CUFunctionInfoHandler: public Dwarf2Handler {
|
||||
public:
|
||||
CUFunctionInfoHandler(vector<SourceFileInfo>* files,
|
||||
vector<string>* dirs,
|
||||
CUFunctionInfoHandler(std::vector<SourceFileInfo>* files,
|
||||
std::vector<std::string>* dirs,
|
||||
LineMap* linemap,
|
||||
FunctionMap* offset_to_funcinfo,
|
||||
FunctionMap* address_to_funcinfo,
|
||||
@@ -163,7 +163,7 @@ class CUFunctionInfoHandler: public Dwarf2Handler {
|
||||
virtual void ProcessAttributeString(uint64 offset,
|
||||
enum DwarfAttribute attr,
|
||||
enum DwarfForm form,
|
||||
const string& data);
|
||||
const std::string& data);
|
||||
|
||||
// Called when finished processing the DIE at OFFSET.
|
||||
// Because DWARF2/3 specifies a tree of DIEs, you may get starts
|
||||
@@ -172,8 +172,8 @@ class CUFunctionInfoHandler: public Dwarf2Handler {
|
||||
virtual void EndDIE(uint64 offset);
|
||||
|
||||
private:
|
||||
vector<SourceFileInfo>* files_;
|
||||
vector<string>* dirs_;
|
||||
std::vector<SourceFileInfo>* files_;
|
||||
std::vector<std::string>* dirs_;
|
||||
LineMap* linemap_;
|
||||
FunctionMap* offset_to_funcinfo_;
|
||||
FunctionMap* address_to_funcinfo_;
|
||||
|
2
thirdparty/breakpad/common/dwarf/types.h
vendored
2
thirdparty/breakpad/common/dwarf/types.h
vendored
@@ -33,6 +33,8 @@
|
||||
#ifndef _COMMON_DWARF_TYPES_H__
|
||||
#define _COMMON_DWARF_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef signed char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
|
Reference in New Issue
Block a user