aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf_cu_to_module.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-24 21:18:44 +0000
committerthestig@chromium.org <thestig@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-04-24 21:18:44 +0000
commitf7566bd447f628d77152dc28fb70ab232c342b86 (patch)
treea092b168c9b64f59a72f62ba9680bc4a0d0dcb8a /src/common/dwarf_cu_to_module.cc
parentFix Clang warning regarding null pointer argument. (diff)
downloadbreakpad-f7566bd447f628d77152dc28fb70ab232c342b86.tar.xz
Add an option to not handle DWARF inter-compilation unit references in Linux dump_syms.
This saves a lot of memory for dump_syms. Review URL: https://breakpad.appspot.com/565002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1163 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/dwarf_cu_to_module.cc')
-rw-r--r--src/common/dwarf_cu_to_module.cc98
1 files changed, 72 insertions, 26 deletions
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index a8b0a29b..9f892290 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -91,7 +91,7 @@ struct DwarfCUToModule::Specification {
// An abstract origin -- base definition of an inline function.
struct AbstractOrigin {
AbstractOrigin() : name() {}
- AbstractOrigin(const string& name) : name(name) {}
+ explicit AbstractOrigin(const string& name) : name(name) {}
string name;
};
@@ -128,14 +128,43 @@ struct DwarfCUToModule::FilePrivate {
AbstractOriginByOffset origins;
};
-DwarfCUToModule::FileContext::FileContext(const string &filename_arg,
- Module *module_arg)
- : filename(filename_arg), module(module_arg) {
- file_private = new FilePrivate();
+DwarfCUToModule::FileContext::FileContext(const string &filename,
+ Module *module,
+ bool handle_inter_cu_refs)
+ : filename_(filename),
+ module_(module),
+ handle_inter_cu_refs_(handle_inter_cu_refs) {
+ file_private_ = new FilePrivate();
}
DwarfCUToModule::FileContext::~FileContext() {
- delete file_private;
+ delete file_private_;
+}
+
+void DwarfCUToModule::FileContext::AddSectionToSectionMap(
+ const string& name, const char* contents, uint64 length) {
+ section_map_[name] = std::make_pair(contents, length);
+}
+
+void DwarfCUToModule::FileContext::ClearSectionMapForTest() {
+ section_map_.clear();
+}
+
+const dwarf2reader::SectionMap&
+DwarfCUToModule::FileContext::section_map() const {
+ return section_map_;
+}
+
+void DwarfCUToModule::FileContext::ClearSpecifications() {
+ if (!handle_inter_cu_refs_)
+ file_private_->specifications.clear();
+}
+
+bool DwarfCUToModule::FileContext::IsUnhandledInterCUReference(
+ uint64 offset, uint64 compilation_unit_start) const {
+ if (handle_inter_cu_refs_)
+ return false;
+ return offset < compilation_unit_start;
}
// Information global to the particular compilation unit we're
@@ -145,11 +174,13 @@ struct DwarfCUToModule::CUContext {
CUContext(FileContext *file_context_arg, WarningReporter *reporter_arg)
: file_context(file_context_arg),
reporter(reporter_arg),
- language(Language::CPlusPlus) { }
+ language(Language::CPlusPlus) {}
+
~CUContext() {
for (vector<Module::Function *>::iterator it = functions.begin();
- it != functions.end(); it++)
+ it != functions.end(); ++it) {
delete *it;
+ }
};
// The DWARF-bearing file into which this CU was incorporated.
@@ -276,14 +307,19 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
uint64 data) {
switch (attr) {
case dwarf2reader::DW_AT_specification: {
+ FileContext *file_context = cu_context_->file_context;
+ if (file_context->IsUnhandledInterCUReference(
+ data, cu_context_->reporter->cu_offset())) {
+ cu_context_->reporter->UnhandledInterCUReference(offset_, data);
+ break;
+ }
// Find the Specification to which this attribute refers, and
// set specification_ appropriately. We could do more processing
// here, but it's better to leave the real work to our
// EndAttribute member function, at which point we know we have
// seen all the DIE's attributes.
- FileContext *file_context = cu_context_->file_context;
- SpecificationByOffset *specifications
- = &file_context->file_private->specifications;
+ SpecificationByOffset *specifications =
+ &file_context->file_private_->specifications;
SpecificationByOffset::iterator spec = specifications->find(data);
if (spec != specifications->end()) {
specification_ = &spec->second;
@@ -303,7 +339,7 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
string DwarfCUToModule::GenericDIEHandler::AddStringToPool(const string &str) {
pair<set<string>::iterator, bool> result =
- cu_context_->file_context->file_private->common_strings.insert(str);
+ cu_context_->file_context->file_private_->common_strings.insert(str);
return *result.first;
}
@@ -365,15 +401,14 @@ string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
// If this DIE was marked as a declaration, record its names in the
// specification table.
if (declaration_) {
- FileContext *file_context = cu_context_->file_context;
Specification spec;
- if (qualified_name)
+ if (qualified_name) {
spec.qualified_name = *qualified_name;
- else {
+ } else {
spec.enclosing_name = *enclosing_name;
spec.unqualified_name = *unqualified_name;
}
- file_context->file_private->specifications[offset_] = spec;
+ cu_context_->file_context->file_private_->specifications[offset_] = spec;
}
if (qualified_name)
@@ -457,10 +492,10 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeReference(
enum DwarfAttribute attr,
enum DwarfForm form,
uint64 data) {
- switch(attr) {
+ switch (attr) {
case dwarf2reader::DW_AT_abstract_origin: {
const AbstractOriginByOffset& origins =
- cu_context_->file_context->file_private->origins;
+ cu_context_->file_context->file_private_->origins;
AbstractOriginByOffset::const_iterator origin = origins.find(data);
if (origin != origins.end()) {
abstract_origin_ = &(origin->second);
@@ -516,7 +551,7 @@ void DwarfCUToModule::FuncHandler::Finish() {
}
} else if (inline_) {
AbstractOrigin origin(name_);
- cu_context_->file_context->file_private->origins[offset_] = origin;
+ cu_context_->file_context->file_private_->origins[offset_] = origin;
}
}
@@ -628,10 +663,19 @@ void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) {
filename_.c_str(), offset);
}
+void DwarfCUToModule::WarningReporter::UnhandledInterCUReference(
+ uint64 offset, uint64 target) {
+ CUHeading();
+ fprintf(stderr, "%s: warning: the DIE at offset 0x%llx has a "
+ "DW_FORM_ref_addr attribute with an inter-CU reference to "
+ "0x%llx, but inter-CU reference handling is turned off.\n",
+ filename_.c_str(), offset, target);
+}
+
DwarfCUToModule::DwarfCUToModule(FileContext *file_context,
LineToModuleHandler *line_reader,
WarningReporter *reporter)
- : line_reader_(line_reader), has_source_line_info_(false) {
+ : line_reader_(line_reader), has_source_line_info_(false) {
cu_context_ = new CUContext(file_context, reporter);
child_context_ = new DIEContext();
}
@@ -723,7 +767,7 @@ void DwarfCUToModule::SetLanguage(DwarfLanguage language) {
// Objective C and Objective C++ seem to create entries for
// methods whose DW_AT_name values are already fully-qualified:
// "-[Classname method:]". These appear at the top level.
- //
+ //
// DWARF data for C should never include namespaces or functions
// nested in struct types, but if it ever does, then C++'s
// notation is probably not a bad choice for that.
@@ -741,7 +785,7 @@ void DwarfCUToModule::SetLanguage(DwarfLanguage language) {
void DwarfCUToModule::ReadSourceLines(uint64 offset) {
const dwarf2reader::SectionMap &section_map
- = cu_context_->file_context->section_map;
+ = cu_context_->file_context->section_map();
dwarf2reader::SectionMap::const_iterator map_entry
= section_map.find(".debug_line");
// Mac OS X puts DWARF data in sections whose names begin with "__"
@@ -759,7 +803,7 @@ void DwarfCUToModule::ReadSourceLines(uint64 offset) {
return;
}
line_reader_->ReadProgram(section_start + offset, section_length - offset,
- cu_context_->file_context->module, &lines_);
+ cu_context_->file_context->module_, &lines_);
}
namespace {
@@ -926,7 +970,7 @@ void DwarfCUToModule::AssignLinesToFunctions() {
// both func and line begin after CURRENT. The next transition
// is the start of the next function or next line, whichever
// is earliest.
- assert (func || line);
+ assert(func || line);
if (func && line)
next_transition = std::min(func->address, line->address);
else if (func)
@@ -984,12 +1028,14 @@ void DwarfCUToModule::Finish() {
// Add our functions, which now have source lines assigned to them,
// to module_.
- cu_context_->file_context->module->AddFunctions(functions->begin(),
- functions->end());
+ cu_context_->file_context->module_->AddFunctions(functions->begin(),
+ functions->end());
// Ownership of the function objects has shifted from cu_context to
// the Module.
functions->clear();
+
+ cu_context_->file_context->ClearSpecifications();
}
bool DwarfCUToModule::StartCompilationUnit(uint64 offset,