|
@@ -1,1199 +0,0 @@
|
|
|
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
-From: Samuel Attard <[email protected]>
|
|
|
-Date: Thu, 2 Sep 2021 22:58:02 +0000
|
|
|
-Subject: Revert "Add INLINE and INLINE_ORIGIN records to symbol file."
|
|
|
-
|
|
|
-This reverts commit 4f5b814790301e7b8252535e0732bee11f4bb801.
|
|
|
-
|
|
|
-diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
|
|
|
-index c51514b7575c2e961aaae3ff883be00d80e3ec15..d129fba4fde3227d191b18bfcb2f23dbb58904c7 100644
|
|
|
---- a/src/common/dwarf_cu_to_module.cc
|
|
|
-+++ b/src/common/dwarf_cu_to_module.cc
|
|
|
-@@ -44,7 +44,6 @@
|
|
|
- #include <stdio.h>
|
|
|
-
|
|
|
- #include <algorithm>
|
|
|
--#include <memory>
|
|
|
- #include <numeric>
|
|
|
- #include <utility>
|
|
|
-
|
|
|
-@@ -59,7 +58,6 @@ using std::map;
|
|
|
- using std::pair;
|
|
|
- using std::sort;
|
|
|
- using std::vector;
|
|
|
--using std::unique_ptr;
|
|
|
-
|
|
|
- // Data provided by a DWARF specification DIE.
|
|
|
- //
|
|
|
-@@ -100,71 +98,6 @@ struct AbstractOrigin {
|
|
|
-
|
|
|
- typedef map<uint64_t, AbstractOrigin> AbstractOriginByOffset;
|
|
|
-
|
|
|
--using InlineOriginByOffset = map<uint64_t, Module::InlineOrigin*>;
|
|
|
--
|
|
|
--class InlineOriginMap {
|
|
|
-- public:
|
|
|
-- Module::InlineOrigin* GetOrCreateInlineOrigin(uint64_t offset,
|
|
|
-- const string& name) {
|
|
|
-- uint64_t specification_offset = references_[offset];
|
|
|
-- if (inline_origins_.find(specification_offset) != inline_origins_.end()) {
|
|
|
-- if (inline_origins_[specification_offset]->name == "<name omitted>") {
|
|
|
-- inline_origins_[specification_offset]->name = name;
|
|
|
-- }
|
|
|
-- return inline_origins_[specification_offset];
|
|
|
-- }
|
|
|
-- inline_origins_[specification_offset] = new Module::InlineOrigin(name);
|
|
|
-- return inline_origins_[specification_offset];
|
|
|
-- }
|
|
|
--
|
|
|
-- // offset is the offset of a DW_TAG_subprogram. specification_offset is the
|
|
|
-- // value of its DW_AT_specification or equals to offset if DW_AT_specification
|
|
|
-- // doesn't exist in that DIE.
|
|
|
-- void SetReference(uint64_t offset, uint64_t specification_offset) {
|
|
|
-- // If we haven't seen this doesn't exist in reference map, always add it.
|
|
|
-- if (references_.find(offset) == references_.end()) {
|
|
|
-- references_[offset] = specification_offset;
|
|
|
-- return;
|
|
|
-- }
|
|
|
-- // If offset equals specification_offset and offset exists in references_,
|
|
|
-- // there is no need to update the references_ map. This early return is
|
|
|
-- // necessary because the call to erase in following if will remove the entry
|
|
|
-- // of specification_offset in inline_origins_.
|
|
|
-- // If specification_offset equals to references_[offset], it might be
|
|
|
-- // duplicate debug info.
|
|
|
-- if (offset == specification_offset ||
|
|
|
-- specification_offset == references_[offset])
|
|
|
-- return;
|
|
|
--
|
|
|
-- // Fix up mapping in inline_origins_.
|
|
|
-- auto remove = inline_origins_.find(references_[offset]);
|
|
|
-- if (remove != inline_origins_.end()) {
|
|
|
-- inline_origins_[specification_offset] = remove->second;
|
|
|
-- inline_origins_.erase(remove);
|
|
|
-- }
|
|
|
-- references_[offset] = specification_offset;
|
|
|
-- }
|
|
|
--
|
|
|
-- void AssignFilesToInlineOrigins(vector<uint64_t>& inline_origin_offsets,
|
|
|
-- Module::File* file) {
|
|
|
-- for (uint64_t offset : inline_origin_offsets)
|
|
|
-- if (references_.find(offset) != references_.end()) {
|
|
|
-- auto origin = inline_origins_.find(references_[offset]);
|
|
|
-- if (origin != inline_origins_.end())
|
|
|
-- origin->second->file = file;
|
|
|
-- }
|
|
|
-- }
|
|
|
--
|
|
|
-- private:
|
|
|
-- // A map from a DW_TAG_subprogram's offset to the DW_TAG_subprogram.
|
|
|
-- InlineOriginByOffset inline_origins_;
|
|
|
--
|
|
|
-- // A map from a DW_TAG_subprogram's offset to the offset of its specification
|
|
|
-- // or abstract origin subprogram. The set of values in this map should always
|
|
|
-- // be the same set of keys in inline_origins_.
|
|
|
-- map<uint64_t, uint64_t> references_;
|
|
|
--};
|
|
|
--
|
|
|
- // Data global to the DWARF-bearing file that is private to the
|
|
|
- // DWARF-to-Module process.
|
|
|
- struct DwarfCUToModule::FilePrivate {
|
|
|
-@@ -197,8 +130,6 @@ struct DwarfCUToModule::FilePrivate {
|
|
|
- // Keep a list of forward references from DW_AT_abstract_origin and
|
|
|
- // DW_AT_specification attributes so names can be fixed up.
|
|
|
- std::map<uint64_t, Module::Function*> forward_ref_die_to_func;
|
|
|
--
|
|
|
-- InlineOriginMap inline_origin_map;
|
|
|
- };
|
|
|
-
|
|
|
- DwarfCUToModule::FileContext::FileContext(const string& filename,
|
|
|
-@@ -341,9 +272,6 @@ struct DwarfCUToModule::CUContext {
|
|
|
-
|
|
|
- // A map of function pointers to the its forward specification DIE's offset.
|
|
|
- map<Module::Function*, uint64_t> spec_function_offsets;
|
|
|
--
|
|
|
-- // From file index to vector of subprogram's offset in this CU.
|
|
|
-- map<uint64_t, vector<uint64_t>> inline_origins;
|
|
|
- };
|
|
|
-
|
|
|
- // Information about the context of a particular DIE. This is for
|
|
|
-@@ -376,8 +304,7 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler {
|
|
|
- offset_(offset),
|
|
|
- declaration_(false),
|
|
|
- specification_(NULL),
|
|
|
-- abstract_origin_(NULL),
|
|
|
-- forward_ref_die_offset_(0), specification_offset_(0) { }
|
|
|
-+ forward_ref_die_offset_(0) { }
|
|
|
-
|
|
|
- // Derived classes' ProcessAttributeUnsigned can defer to this to
|
|
|
- // handle DW_AT_declaration, or simply not override it.
|
|
|
-@@ -429,19 +356,11 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler {
|
|
|
- // Otherwise, this is NULL.
|
|
|
- Specification* specification_;
|
|
|
-
|
|
|
-- // If this DIE has a DW_AT_abstract_origin attribute, this is the
|
|
|
-- // AbstractOrigin structure for the DIE the attribute refers to.
|
|
|
-- // Otherwise, this is NULL.
|
|
|
-- const AbstractOrigin* abstract_origin_;
|
|
|
--
|
|
|
- // If this DIE has a DW_AT_specification or DW_AT_abstract_origin and it is a
|
|
|
- // forward reference, no Specification will be available. Track the reference
|
|
|
- // to be fixed up when the DIE is parsed.
|
|
|
- uint64_t forward_ref_die_offset_;
|
|
|
-
|
|
|
-- // The root offset of Specification or abstract origin.
|
|
|
-- uint64_t specification_offset_;
|
|
|
--
|
|
|
- // The value of the DW_AT_name attribute, or the empty string if the
|
|
|
- // DIE has no such attribute.
|
|
|
- string name_attribute_;
|
|
|
-@@ -493,21 +412,6 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
|
|
|
- } else {
|
|
|
- cu_context_->reporter->UnknownSpecification(offset_, data);
|
|
|
- }
|
|
|
-- specification_offset_ = data;
|
|
|
-- break;
|
|
|
-- }
|
|
|
-- case DW_AT_abstract_origin: {
|
|
|
-- const AbstractOriginByOffset& origins =
|
|
|
-- cu_context_->file_context->file_private_->origins;
|
|
|
-- AbstractOriginByOffset::const_iterator origin = origins.find(data);
|
|
|
-- if (origin != origins.end()) {
|
|
|
-- abstract_origin_ = &(origin->second);
|
|
|
-- } else if (data > offset_) {
|
|
|
-- forward_ref_die_offset_ = data;
|
|
|
-- } else {
|
|
|
-- cu_context_->reporter->UnknownAbstractOrigin(offset_, data);
|
|
|
-- }
|
|
|
-- specification_offset_ = data;
|
|
|
- break;
|
|
|
- }
|
|
|
- default: break;
|
|
|
-@@ -615,163 +519,6 @@ string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
|
|
|
- return return_value;
|
|
|
- }
|
|
|
-
|
|
|
--static bool IsEmptyRange(const vector<Module::Range>& ranges) {
|
|
|
-- uint64_t size = accumulate(ranges.cbegin(), ranges.cend(), 0,
|
|
|
-- [](uint64_t total, Module::Range entry) {
|
|
|
-- return total + entry.size;
|
|
|
-- }
|
|
|
-- );
|
|
|
--
|
|
|
-- return size == 0;
|
|
|
--}
|
|
|
--
|
|
|
--
|
|
|
--// A handler for DW_TAG_inlined_subroutine DIEs.
|
|
|
--class DwarfCUToModule::InlineHandler : public GenericDIEHandler {
|
|
|
-- public:
|
|
|
-- InlineHandler(CUContext* cu_context,
|
|
|
-- DIEContext* parent_context,
|
|
|
-- uint64_t offset,
|
|
|
-- int inline_nest_level,
|
|
|
-- vector<unique_ptr<Module::Inline>>& inlines)
|
|
|
-- : GenericDIEHandler(cu_context, parent_context, offset),
|
|
|
-- low_pc_(0),
|
|
|
-- high_pc_(0),
|
|
|
-- high_pc_form_(DW_FORM_addr),
|
|
|
-- ranges_form_(DW_FORM_sec_offset),
|
|
|
-- ranges_data_(0),
|
|
|
-- call_site_line_(0),
|
|
|
-- inline_nest_level_(inline_nest_level),
|
|
|
-- inlines_(inlines) {}
|
|
|
--
|
|
|
-- void ProcessAttributeUnsigned(enum DwarfAttribute attr,
|
|
|
-- enum DwarfForm form,
|
|
|
-- uint64_t data);
|
|
|
-- DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag);
|
|
|
-- bool EndAttributes();
|
|
|
-- void Finish();
|
|
|
--
|
|
|
-- private:
|
|
|
-- // The fully-qualified name, as derived from name_attribute_,
|
|
|
-- // specification_, parent_context_. Computed in EndAttributes.
|
|
|
-- string name_;
|
|
|
-- uint64_t low_pc_; // DW_AT_low_pc
|
|
|
-- uint64_t high_pc_; // DW_AT_high_pc
|
|
|
-- DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address.
|
|
|
-- DwarfForm ranges_form_; // DW_FORM_sec_offset or DW_FORM_rnglistx
|
|
|
-- uint64_t ranges_data_; // DW_AT_ranges
|
|
|
-- int call_site_line_;
|
|
|
-- int inline_nest_level_;
|
|
|
-- // A vector of inlines in the same nest level. It's owned by its parent
|
|
|
-- // function/inline. At Finish(), add this inline into the vector.
|
|
|
-- vector<unique_ptr<Module::Inline>>& inlines_;
|
|
|
-- // A vector of child inlines.
|
|
|
-- vector<unique_ptr<Module::Inline>> child_inlines_;
|
|
|
--};
|
|
|
--
|
|
|
--void DwarfCUToModule::InlineHandler::ProcessAttributeUnsigned(
|
|
|
-- enum DwarfAttribute attr,
|
|
|
-- enum DwarfForm form,
|
|
|
-- uint64_t data) {
|
|
|
-- switch (attr) {
|
|
|
-- case DW_AT_low_pc:
|
|
|
-- low_pc_ = data;
|
|
|
-- break;
|
|
|
-- case DW_AT_high_pc:
|
|
|
-- high_pc_form_ = form;
|
|
|
-- high_pc_ = data;
|
|
|
-- break;
|
|
|
-- case DW_AT_ranges:
|
|
|
-- ranges_data_ = data;
|
|
|
-- ranges_form_ = form;
|
|
|
-- break;
|
|
|
-- case DW_AT_call_line:
|
|
|
-- call_site_line_ = data;
|
|
|
-- break;
|
|
|
-- default:
|
|
|
-- GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data);
|
|
|
-- break;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--DIEHandler* DwarfCUToModule::InlineHandler::FindChildHandler(
|
|
|
-- uint64_t offset,
|
|
|
-- enum DwarfTag tag) {
|
|
|
-- switch (tag) {
|
|
|
-- case DW_TAG_inlined_subroutine:
|
|
|
-- return new InlineHandler(cu_context_, new DIEContext(), offset,
|
|
|
-- inline_nest_level_ + 1, child_inlines_);
|
|
|
-- default:
|
|
|
-- return NULL;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--bool DwarfCUToModule::InlineHandler::EndAttributes() {
|
|
|
-- if (abstract_origin_)
|
|
|
-- name_ = abstract_origin_->name;
|
|
|
-- if (name_.empty()) {
|
|
|
-- // We haven't seen the abstract origin yet, which might appears later and we
|
|
|
-- // will fix the name after calling
|
|
|
-- // InlineOriginMap::GetOrCreateInlineOrigin with right name.
|
|
|
-- name_ = "<name omitted>";
|
|
|
-- }
|
|
|
-- return true;
|
|
|
--}
|
|
|
--
|
|
|
--void DwarfCUToModule::InlineHandler::Finish() {
|
|
|
-- vector<Module::Range> ranges;
|
|
|
--
|
|
|
-- if (low_pc_ && high_pc_) {
|
|
|
-- if (high_pc_form_ != DW_FORM_addr &&
|
|
|
-- high_pc_form_ != DW_FORM_GNU_addr_index &&
|
|
|
-- high_pc_form_ != DW_FORM_addrx &&
|
|
|
-- high_pc_form_ != DW_FORM_addrx1 &&
|
|
|
-- high_pc_form_ != DW_FORM_addrx2 &&
|
|
|
-- high_pc_form_ != DW_FORM_addrx3 &&
|
|
|
-- high_pc_form_ != DW_FORM_addrx4) {
|
|
|
-- high_pc_ += low_pc_;
|
|
|
-- }
|
|
|
--
|
|
|
-- Module::Range range(low_pc_, high_pc_ - low_pc_);
|
|
|
-- ranges.push_back(range);
|
|
|
-- } else {
|
|
|
-- RangesHandler* ranges_handler = cu_context_->ranges_handler;
|
|
|
-- if (ranges_handler) {
|
|
|
-- RangeListReader::CURangesInfo cu_info;
|
|
|
-- if (cu_context_->AssembleRangeListInfo(&cu_info)) {
|
|
|
-- if (!ranges_handler->ReadRanges(ranges_form_, ranges_data_,
|
|
|
-- &cu_info, &ranges)) {
|
|
|
-- ranges.clear();
|
|
|
-- cu_context_->reporter->MalformedRangeList(ranges_data_);
|
|
|
-- }
|
|
|
-- } else {
|
|
|
-- cu_context_->reporter->MissingRanges();
|
|
|
-- }
|
|
|
-- }
|
|
|
-- }
|
|
|
--
|
|
|
-- // Malformed DWARF may omit the name, but all Module::Functions must
|
|
|
-- // have names.
|
|
|
-- // If we have a forward reference to a DW_AT_specification or
|
|
|
-- // DW_AT_abstract_origin, then don't warn, the name will be fixed up
|
|
|
-- // later
|
|
|
-- if (name_.empty() && forward_ref_die_offset_ == 0)
|
|
|
-- cu_context_->reporter->UnnamedFunction(offset_);
|
|
|
--
|
|
|
-- // Every DW_TAG_inlined_subroutine should have a DW_AT_abstract_origin.
|
|
|
-- assert(specification_offset_ != 0);
|
|
|
--
|
|
|
-- cu_context_->file_context->file_private_->inline_origin_map.SetReference(
|
|
|
-- specification_offset_, specification_offset_);
|
|
|
-- Module::InlineOrigin* origin =
|
|
|
-- cu_context_->file_context->file_private_->inline_origin_map
|
|
|
-- .GetOrCreateInlineOrigin(specification_offset_, name_);
|
|
|
-- unique_ptr<Module::Inline> in(
|
|
|
-- new Module::Inline(origin, ranges, call_site_line_, inline_nest_level_,
|
|
|
-- std::move(child_inlines_)));
|
|
|
-- inlines_.push_back(std::move(in));
|
|
|
--}
|
|
|
--
|
|
|
- // A handler class for DW_TAG_subprogram DIEs.
|
|
|
- class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
|
|
|
- public:
|
|
|
-@@ -780,7 +527,7 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
|
|
|
- : GenericDIEHandler(cu_context, parent_context, offset),
|
|
|
- low_pc_(0), high_pc_(0), high_pc_form_(DW_FORM_addr),
|
|
|
- ranges_form_(DW_FORM_sec_offset), ranges_data_(0),
|
|
|
-- decl_file_data_(UINT64_MAX), inline_(false) { }
|
|
|
-+ abstract_origin_(NULL), inline_(false) { }
|
|
|
-
|
|
|
- void ProcessAttributeUnsigned(enum DwarfAttribute attr,
|
|
|
- enum DwarfForm form,
|
|
|
-@@ -788,7 +535,10 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
|
|
|
- void ProcessAttributeSigned(enum DwarfAttribute attr,
|
|
|
- enum DwarfForm form,
|
|
|
- int64_t data);
|
|
|
-- DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag);
|
|
|
-+ void ProcessAttributeReference(enum DwarfAttribute attr,
|
|
|
-+ enum DwarfForm form,
|
|
|
-+ uint64_t data);
|
|
|
-+
|
|
|
- bool EndAttributes();
|
|
|
- void Finish();
|
|
|
-
|
|
|
-@@ -800,10 +550,8 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler {
|
|
|
- DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address.
|
|
|
- DwarfForm ranges_form_; // DW_FORM_sec_offset or DW_FORM_rnglistx
|
|
|
- uint64_t ranges_data_; // DW_AT_ranges
|
|
|
-- // DW_AT_decl_file, value of UINT64_MAX means undefined.
|
|
|
-- uint64_t decl_file_data_;
|
|
|
-+ const AbstractOrigin* abstract_origin_;
|
|
|
- bool inline_;
|
|
|
-- vector<unique_ptr<Module::Inline>> child_inlines_;
|
|
|
- };
|
|
|
-
|
|
|
- void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
|
|
|
-@@ -825,9 +573,7 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned(
|
|
|
- ranges_data_ = data;
|
|
|
- ranges_form_ = form;
|
|
|
- break;
|
|
|
-- case DW_AT_decl_file:
|
|
|
-- decl_file_data_ = data;
|
|
|
-- break;
|
|
|
-+
|
|
|
- default:
|
|
|
- GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data);
|
|
|
- break;
|
|
|
-@@ -849,15 +595,27 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeSigned(
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
--DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler(
|
|
|
-- uint64_t offset,
|
|
|
-- enum DwarfTag tag) {
|
|
|
-- switch (tag) {
|
|
|
-- case DW_TAG_inlined_subroutine:
|
|
|
-- return new InlineHandler(cu_context_, new DIEContext(), offset, 0,
|
|
|
-- child_inlines_);
|
|
|
-+void DwarfCUToModule::FuncHandler::ProcessAttributeReference(
|
|
|
-+ enum DwarfAttribute attr,
|
|
|
-+ enum DwarfForm form,
|
|
|
-+ uint64_t data) {
|
|
|
-+ switch (attr) {
|
|
|
-+ case DW_AT_abstract_origin: {
|
|
|
-+ const AbstractOriginByOffset& origins =
|
|
|
-+ cu_context_->file_context->file_private_->origins;
|
|
|
-+ AbstractOriginByOffset::const_iterator origin = origins.find(data);
|
|
|
-+ if (origin != origins.end()) {
|
|
|
-+ abstract_origin_ = &(origin->second);
|
|
|
-+ } else if (data > offset_) {
|
|
|
-+ forward_ref_die_offset_ = data;
|
|
|
-+ } else {
|
|
|
-+ cu_context_->reporter->UnknownAbstractOrigin(offset_, data);
|
|
|
-+ }
|
|
|
-+ break;
|
|
|
-+ }
|
|
|
- default:
|
|
|
-- return NULL;
|
|
|
-+ GenericDIEHandler::ProcessAttributeReference(attr, form, data);
|
|
|
-+ break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-@@ -870,6 +628,16 @@ bool DwarfCUToModule::FuncHandler::EndAttributes() {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
-+static bool IsEmptyRange(const vector<Module::Range>& ranges) {
|
|
|
-+ uint64_t size = accumulate(ranges.cbegin(), ranges.cend(), 0,
|
|
|
-+ [](uint64_t total, Module::Range entry) {
|
|
|
-+ return total + entry.size;
|
|
|
-+ }
|
|
|
-+ );
|
|
|
-+
|
|
|
-+ return size == 0;
|
|
|
-+}
|
|
|
-+
|
|
|
- void DwarfCUToModule::FuncHandler::Finish() {
|
|
|
- vector<Module::Range> ranges;
|
|
|
-
|
|
|
-@@ -915,12 +683,11 @@ void DwarfCUToModule::FuncHandler::Finish() {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-- bool empty_range = IsEmptyRange(ranges);
|
|
|
- // Did we collect the information we need? Not all DWARF function
|
|
|
- // entries are non-empty (for example, inlined functions that were never
|
|
|
- // used), but all the ones we're interested in cover a non-empty range of
|
|
|
- // bytes.
|
|
|
-- if (!empty_range) {
|
|
|
-+ if (!IsEmptyRange(ranges)) {
|
|
|
- low_pc_ = ranges.front().address;
|
|
|
-
|
|
|
- // Malformed DWARF may omit the name, but all Module::Functions must
|
|
|
-@@ -954,27 +721,11 @@ void DwarfCUToModule::FuncHandler::Finish() {
|
|
|
- cu_context_->spec_function_offsets[cu_context_->functions.back()] =
|
|
|
- forward_ref_die_offset_;
|
|
|
- }
|
|
|
--
|
|
|
-- cu_context_->functions.back()->inlines.swap(child_inlines_);
|
|
|
- }
|
|
|
- } else if (inline_) {
|
|
|
- AbstractOrigin origin(name_);
|
|
|
- cu_context_->file_context->file_private_->origins[offset_] = origin;
|
|
|
- }
|
|
|
--
|
|
|
-- // Only keep track of DW_TAG_subprogram which have the attributes we are
|
|
|
-- // interested.
|
|
|
-- if (!empty_range || inline_ || decl_file_data_ != UINT64_MAX) {
|
|
|
-- uint64_t offset =
|
|
|
-- specification_offset_ != 0 ? specification_offset_ : offset_;
|
|
|
-- cu_context_->file_context->file_private_->inline_origin_map.SetReference(
|
|
|
-- offset_, offset);
|
|
|
-- cu_context_->file_context->file_private_->inline_origin_map
|
|
|
-- .GetOrCreateInlineOrigin(offset_,
|
|
|
-- name_.empty() ? "<name omitted>" : name_);
|
|
|
-- if (decl_file_data_ != UINT64_MAX)
|
|
|
-- cu_context_->inline_origins[decl_file_data_].push_back(offset_);
|
|
|
-- }
|
|
|
- }
|
|
|
-
|
|
|
- // A handler for DIEs that contain functions and contribute a
|
|
|
-@@ -1290,7 +1041,7 @@ void DwarfCUToModule::ReadSourceLines(uint64_t offset) {
|
|
|
- line_section_start, line_section_length,
|
|
|
- string_section_start, string_section_length,
|
|
|
- line_string_section_start, line_string_section_length,
|
|
|
-- cu_context_->file_context->module_, &lines_, &files_);
|
|
|
-+ cu_context_->file_context->module_, &lines_);
|
|
|
- }
|
|
|
-
|
|
|
- namespace {
|
|
|
-@@ -1549,14 +1300,6 @@ void DwarfCUToModule::AssignLinesToFunctions() {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
--void DwarfCUToModule::AssignFilesToInlines() {
|
|
|
-- for (auto iter : files_) {
|
|
|
-- cu_context_->file_context->file_private_->inline_origin_map
|
|
|
-- .AssignFilesToInlineOrigins(cu_context_->inline_origins[iter.first],
|
|
|
-- iter.second);
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
- void DwarfCUToModule::Finish() {
|
|
|
- // Assembly language files have no function data, and that gives us
|
|
|
- // no place to store our line numbers (even though the GNU toolchain
|
|
|
-@@ -1575,8 +1318,6 @@ void DwarfCUToModule::Finish() {
|
|
|
- // Dole out lines to the appropriate functions.
|
|
|
- AssignLinesToFunctions();
|
|
|
-
|
|
|
-- AssignFilesToInlines();
|
|
|
--
|
|
|
- // Add our functions, which now have source lines assigned to them,
|
|
|
- // to module_, and remove duplicate functions.
|
|
|
- for (Module::Function* func : *functions)
|
|
|
-diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h
|
|
|
-index 99dcd879181aac4018080e8d0cb2c413efc67ebe..1320ccc2c885b5d591a877b41fd7d2af5a2ab65f 100644
|
|
|
---- a/src/common/dwarf_cu_to_module.h
|
|
|
-+++ b/src/common/dwarf_cu_to_module.h
|
|
|
-@@ -156,8 +156,7 @@ class DwarfCUToModule: public RootDIEHandler {
|
|
|
- uint64_t string_section_length,
|
|
|
- const uint8_t* line_string_section,
|
|
|
- uint64_t line_string_length,
|
|
|
-- Module* module, vector<Module::Line>* lines,
|
|
|
-- map<uint32_t, Module::File*>* files) = 0;
|
|
|
-+ Module* module, vector<Module::Line>* lines) = 0;
|
|
|
- };
|
|
|
-
|
|
|
- // The interface DwarfCUToModule uses to report warnings. The member
|
|
|
-@@ -290,7 +289,6 @@ class DwarfCUToModule: public RootDIEHandler {
|
|
|
- struct Specification;
|
|
|
- class GenericDIEHandler;
|
|
|
- class FuncHandler;
|
|
|
-- class InlineHandler;
|
|
|
- class NamedScopeHandler;
|
|
|
-
|
|
|
- // A map from section offsets to specifications.
|
|
|
-@@ -311,8 +309,6 @@ class DwarfCUToModule: public RootDIEHandler {
|
|
|
- // lines belong to which functions, beyond their addresses.)
|
|
|
- void AssignLinesToFunctions();
|
|
|
-
|
|
|
-- void AssignFilesToInlines();
|
|
|
--
|
|
|
- // The only reason cu_context_ and child_context_ are pointers is
|
|
|
- // that we want to keep their definitions private to
|
|
|
- // dwarf_cu_to_module.cc, instead of listing them all here. They are
|
|
|
-@@ -339,9 +335,6 @@ class DwarfCUToModule: public RootDIEHandler {
|
|
|
- // during parsing. Then, in Finish, we call AssignLinesToFunctions
|
|
|
- // to dole them out to the appropriate functions.
|
|
|
- vector<Module::Line> lines_;
|
|
|
--
|
|
|
-- // The map from file index to File* in this CU.
|
|
|
-- std::map<uint32_t, Module::File*> files_;
|
|
|
- };
|
|
|
-
|
|
|
- } // namespace google_breakpad
|
|
|
-diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc
|
|
|
-index cb943ae3f085c7074ba48bb8036b669eb71de374..2ce69d73c6043a1f66c2d3406389287bbd557ece 100644
|
|
|
---- a/src/common/dwarf_cu_to_module_unittest.cc
|
|
|
-+++ b/src/common/dwarf_cu_to_module_unittest.cc
|
|
|
-@@ -67,13 +67,12 @@ using ::testing::ValuesIn;
|
|
|
- class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler {
|
|
|
- public:
|
|
|
- MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir));
|
|
|
-- MOCK_METHOD9(ReadProgram, void(const uint8_t* program, uint64_t length,
|
|
|
-+ MOCK_METHOD8(ReadProgram, void(const uint8_t* program, uint64_t length,
|
|
|
- const uint8_t* string_section,
|
|
|
- uint64_t string_section_length,
|
|
|
- const uint8_t* line_string_section,
|
|
|
- uint64_t line_string_section_length,
|
|
|
-- Module* module, vector<Module::Line>* lines,
|
|
|
-- std::map<uint32_t, Module::File*>* files));
|
|
|
-+ Module* module, vector<Module::Line>* lines));
|
|
|
- };
|
|
|
-
|
|
|
- class MockWarningReporter: public DwarfCUToModule::WarningReporter {
|
|
|
-@@ -123,8 +122,7 @@ class CUFixtureBase {
|
|
|
- uint64_t string_section_length,
|
|
|
- const uint8_t* line_string_section,
|
|
|
- uint64_t line_string_section_length,
|
|
|
-- Module *module, vector<Module::Line>* lines,
|
|
|
-- std::map<uint32_t, Module::File*>* files) {
|
|
|
-+ Module *module, vector<Module::Line>* lines) {
|
|
|
- lines->insert(lines->end(), lines_->begin(), lines_->end());
|
|
|
- }
|
|
|
- private:
|
|
|
-@@ -157,7 +155,7 @@ class CUFixtureBase {
|
|
|
- // By default, expect the line program reader not to be invoked. We
|
|
|
- // may override this in StartCU.
|
|
|
- EXPECT_CALL(line_reader_, StartCompilationUnit(_)).Times(0);
|
|
|
-- EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-+ EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-
|
|
|
- // The handler will consult this section map to decide what to
|
|
|
- // pass to our line reader.
|
|
|
-@@ -343,7 +341,7 @@ void CUFixtureBase::StartCU() {
|
|
|
- EXPECT_CALL(line_reader_,
|
|
|
- ReadProgram(&dummy_line_program_[0], dummy_line_size_,
|
|
|
- _,_,_,_,
|
|
|
-- &module_, _,_))
|
|
|
-+ &module_, _))
|
|
|
- .Times(AtMost(1))
|
|
|
- .WillOnce(DoAll(Invoke(appender_), Return()));
|
|
|
- ASSERT_TRUE(root_handler_
|
|
|
-@@ -1519,7 +1517,7 @@ TEST_F(Specifications, InterCU) {
|
|
|
- DwarfCUToModule::FileContext fc("dwarf-filename", &m, true);
|
|
|
- EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
|
|
|
- MockLineToModuleHandler lr;
|
|
|
-- EXPECT_CALL(lr, ReadProgram(_,_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-+ EXPECT_CALL(lr, ReadProgram(_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-
|
|
|
- // Kludge: satisfy reporter_'s expectation.
|
|
|
- reporter_.SetCUName("compilation-unit-name");
|
|
|
-@@ -1578,7 +1576,7 @@ TEST_F(Specifications, UnhandledInterCU) {
|
|
|
- DwarfCUToModule::FileContext fc("dwarf-filename", &m, false);
|
|
|
- EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
|
|
|
- MockLineToModuleHandler lr;
|
|
|
-- EXPECT_CALL(lr, ReadProgram(_,_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-+ EXPECT_CALL(lr, ReadProgram(_,_,_,_,_,_,_,_)).Times(0);
|
|
|
-
|
|
|
- // Kludge: satisfy reporter_'s expectation.
|
|
|
- reporter_.SetCUName("compilation-unit-name");
|
|
|
-diff --git a/src/common/dwarf_line_to_module.cc b/src/common/dwarf_line_to_module.cc
|
|
|
-index 83bb8f1554f31030e6ca8c08d3e1173fbb431d95..fe808c0865e706e279c5d3bea5b317fc15d23298 100644
|
|
|
---- a/src/common/dwarf_line_to_module.cc
|
|
|
-+++ b/src/common/dwarf_line_to_module.cc
|
|
|
-@@ -100,7 +100,7 @@ void DwarfLineToModule::DefineFile(const string& name, int32_t file_num,
|
|
|
-
|
|
|
- // Find a Module::File object of the given name, and add it to the
|
|
|
- // file table.
|
|
|
-- (*files_)[file_num] = module_->FindFile(full_name);
|
|
|
-+ files_[file_num] = module_->FindFile(full_name);
|
|
|
- }
|
|
|
-
|
|
|
- void DwarfLineToModule::AddLine(uint64_t address, uint64_t length,
|
|
|
-@@ -122,7 +122,7 @@ void DwarfLineToModule::AddLine(uint64_t address, uint64_t length,
|
|
|
- }
|
|
|
-
|
|
|
- // Find the source file being referred to.
|
|
|
-- Module::File *file = (*files_)[file_num];
|
|
|
-+ Module::File *file = files_[file_num];
|
|
|
- if (!file) {
|
|
|
- if (!warned_bad_file_number_) {
|
|
|
- fprintf(stderr, "warning: DWARF line number data refers to "
|
|
|
-diff --git a/src/common/dwarf_line_to_module.h b/src/common/dwarf_line_to_module.h
|
|
|
-index da2c5f0ec51688165ffabd67d192be68006c84ae..496a7006d06afbe501c554d82477ba33287c97a5 100644
|
|
|
---- a/src/common/dwarf_line_to_module.h
|
|
|
-+++ b/src/common/dwarf_line_to_module.h
|
|
|
-@@ -120,19 +120,16 @@ class DwarfLineToModule: public LineInfoHandler {
|
|
|
- // end of the address space, we clip it. It's up to our client to
|
|
|
- // sort out which lines belong to which functions; we don't add them
|
|
|
- // to any particular function in MODULE ourselves.
|
|
|
-- DwarfLineToModule(Module* module,
|
|
|
-- const string& compilation_dir,
|
|
|
-- vector<Module::Line>* lines,
|
|
|
-- std::map<uint32_t, Module::File*>* files)
|
|
|
-+ DwarfLineToModule(Module *module, const string& compilation_dir,
|
|
|
-+ vector<Module::Line>* lines)
|
|
|
- : module_(module),
|
|
|
- compilation_dir_(compilation_dir),
|
|
|
- lines_(lines),
|
|
|
-- files_(files),
|
|
|
- highest_file_number_(-1),
|
|
|
- omitted_line_end_(0),
|
|
|
- warned_bad_file_number_(false),
|
|
|
- warned_bad_directory_number_(false) { }
|
|
|
--
|
|
|
-+ // empty line
|
|
|
- ~DwarfLineToModule() { }
|
|
|
-
|
|
|
- void DefineDir(const string& name, uint32_t dir_num);
|
|
|
-@@ -170,12 +167,12 @@ class DwarfLineToModule: public LineInfoHandler {
|
|
|
- DirectoryTable directories_;
|
|
|
-
|
|
|
- // A table mapping file numbers to Module::File pointers.
|
|
|
-- FileTable* files_;
|
|
|
-+ FileTable files_;
|
|
|
-
|
|
|
- // The highest file number we've seen so far, or -1 if we've seen
|
|
|
- // none. Used for dynamically defined file numbers.
|
|
|
- int32_t highest_file_number_;
|
|
|
--
|
|
|
-+ // empty line
|
|
|
- // This is the ending address of the last line we omitted, or zero if we
|
|
|
- // didn't omit the previous line. It is zero before we have received any
|
|
|
- // AddLine calls.
|
|
|
-diff --git a/src/common/dwarf_line_to_module_unittest.cc b/src/common/dwarf_line_to_module_unittest.cc
|
|
|
-index 34cb02ed486e33c8b45685529a29c7666e0ed319..90b6570d8ddebb2f6caf384e7b23901cfa616b2b 100644
|
|
|
---- a/src/common/dwarf_line_to_module_unittest.cc
|
|
|
-+++ b/src/common/dwarf_line_to_module_unittest.cc
|
|
|
-@@ -45,8 +45,7 @@ using google_breakpad::Module;
|
|
|
- TEST(SimpleModule, One) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("file1", 0x30bf0f27, 0, 0, 0);
|
|
|
- h.AddLine(0x6fd126fbf74f2680LL, 0x63c9a14cf556712bLL, 0x30bf0f27,
|
|
|
-@@ -67,8 +66,7 @@ TEST(SimpleModule, One) {
|
|
|
- TEST(SimpleModule, Many) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory1", 0x838299ab);
|
|
|
- h.DefineDir("directory2", 0xf85de023);
|
|
|
-@@ -128,8 +126,7 @@ TEST(SimpleModule, Many) {
|
|
|
- TEST(Filenames, Absolute) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory1", 1);
|
|
|
- h.DefineFile("/absolute", 1, 1, 0, 0);
|
|
|
-@@ -147,8 +144,7 @@ TEST(Filenames, Absolute) {
|
|
|
- TEST(Filenames, Relative) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory1", 1);
|
|
|
- h.DefineFile("relative", 1, 1, 0, 0);
|
|
|
-@@ -166,8 +162,7 @@ TEST(Filenames, Relative) {
|
|
|
- TEST(Filenames, StrangeFile) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory1", 1);
|
|
|
- h.DefineFile("", 1, 1, 0, 0);
|
|
|
-@@ -180,8 +175,7 @@ TEST(Filenames, StrangeFile) {
|
|
|
- TEST(Filenames, StrangeDirectory) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("", 1);
|
|
|
- h.DefineFile("file1", 1, 1, 0, 0);
|
|
|
-@@ -194,8 +188,7 @@ TEST(Filenames, StrangeDirectory) {
|
|
|
- TEST(Filenames, StrangeDirectoryAndFile) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("", 1);
|
|
|
- h.DefineFile("", 1, 1, 0, 0);
|
|
|
-@@ -210,8 +203,7 @@ TEST(Filenames, StrangeDirectoryAndFile) {
|
|
|
- TEST(Filenames, DirectoryZeroFileIsRelativeToCompilationDir) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "src/build", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "src/build", &lines);
|
|
|
-
|
|
|
- h.DefineDir("Dir", 1);
|
|
|
- h.DefineFile("File", 1, 0, 0, 0);
|
|
|
-@@ -227,8 +219,7 @@ TEST(Filenames, DirectoryZeroFileIsRelativeToCompilationDir) {
|
|
|
- TEST(Filenames, IncludeDirectoryRelativeToDirectoryZero) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "src/build", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "src/build", &lines);
|
|
|
-
|
|
|
- h.DefineDir("Dir", 1);
|
|
|
- h.DefineFile("File", 1, 1, 0, 0);
|
|
|
-@@ -244,8 +235,7 @@ TEST(Filenames, IncludeDirectoryRelativeToDirectoryZero) {
|
|
|
- TEST(Filenames, IncludeDirectoryAbsolute) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "src/build", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "src/build", &lines);
|
|
|
-
|
|
|
- h.DefineDir("/Dir", 1);
|
|
|
- h.DefineFile("File", 1, 1, 0, 0);
|
|
|
-@@ -261,8 +251,7 @@ TEST(Filenames, IncludeDirectoryAbsolute) {
|
|
|
- TEST(ModuleErrors, DirectoryZero) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory0", 0); // should be ignored
|
|
|
- h.DefineFile("relative", 1, 0, 0, 0);
|
|
|
-@@ -278,8 +267,7 @@ TEST(ModuleErrors, DirectoryZero) {
|
|
|
- TEST(ModuleErrors, BadFileNumber) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("relative", 1, 0, 0, 0);
|
|
|
- h.AddLine(1, 1, 2, 0, 0); // bad file number
|
|
|
-@@ -293,8 +281,7 @@ TEST(ModuleErrors, BadFileNumber) {
|
|
|
- TEST(ModuleErrors, BadDirectoryNumber) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineDir("directory1", 1);
|
|
|
- h.DefineFile("baddirnumber1", 1, 2, 0, 0); // bad directory number
|
|
|
-@@ -309,8 +296,7 @@ TEST(ModuleErrors, BadDirectoryNumber) {
|
|
|
- TEST(ModuleErrors, EmptyLine) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(1, 0, 1, 0, 0);
|
|
|
-@@ -323,8 +309,7 @@ TEST(ModuleErrors, EmptyLine) {
|
|
|
- TEST(ModuleErrors, BigLine) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(0xffffffffffffffffULL, 2, 1, 0, 0);
|
|
|
-@@ -341,8 +326,7 @@ TEST(ModuleErrors, BigLine) {
|
|
|
- TEST(Omitted, DroppedThenGood) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(0, 10, 1, 83816211, 0); // should be omitted
|
|
|
-@@ -355,8 +339,7 @@ TEST(Omitted, DroppedThenGood) {
|
|
|
- TEST(Omitted, GoodThenDropped) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(0x9dd6a372, 10, 1, 41454594, 0); // should be recorded
|
|
|
-@@ -369,8 +352,7 @@ TEST(Omitted, GoodThenDropped) {
|
|
|
- TEST(Omitted, Mix1) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(0x679ed72f, 10, 1, 58932642, 0); // should be recorded
|
|
|
-@@ -391,8 +373,7 @@ TEST(Omitted, Mix1) {
|
|
|
- TEST(Omitted, Mix2) {
|
|
|
- Module m("name", "os", "architecture", "id");
|
|
|
- vector<Module::Line> lines;
|
|
|
-- std::map<uint32_t, Module::File*> cu_files;
|
|
|
-- DwarfLineToModule h(&m, "/", &lines, &cu_files);
|
|
|
-+ DwarfLineToModule h(&m, "/", &lines);
|
|
|
-
|
|
|
- h.DefineFile("filename1", 1, 0, 0, 0);
|
|
|
- h.AddLine(0, 0xf2, 1, 58802211, 0); // should be omitted
|
|
|
-diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
|
|
|
-index 92a260baf3187db55043eb8c3f3fb36d13276cdd..5909d6ba1f9840a5f649e8530b9a97d4c9380c50 100644
|
|
|
---- a/src/common/linux/dump_symbols.cc
|
|
|
-+++ b/src/common/linux/dump_symbols.cc
|
|
|
-@@ -260,16 +260,13 @@ class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
|
|
|
- void StartCompilationUnit(const string& compilation_dir) {
|
|
|
- compilation_dir_ = compilation_dir;
|
|
|
- }
|
|
|
-- void ReadProgram(const uint8_t* program,
|
|
|
-- uint64_t length,
|
|
|
-+ void ReadProgram(const uint8_t* program, uint64_t length,
|
|
|
- const uint8_t* string_section,
|
|
|
- uint64_t string_section_length,
|
|
|
- const uint8_t* line_string_section,
|
|
|
- uint64_t line_string_section_length,
|
|
|
-- Module* module,
|
|
|
-- std::vector<Module::Line>* lines,
|
|
|
-- std::map<uint32_t, Module::File*>* files) {
|
|
|
-- DwarfLineToModule handler(module, compilation_dir_, lines, files);
|
|
|
-+ Module* module, std::vector<Module::Line>* lines) {
|
|
|
-+ DwarfLineToModule handler(module, compilation_dir_, lines);
|
|
|
- google_breakpad::LineInfo parser(program, length, byte_reader_,
|
|
|
- string_section, string_section_length,
|
|
|
- line_string_section,
|
|
|
-diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc
|
|
|
-index 3592e4bb1afee19979054ff1551563520174594b..e30d8ea952c76f59028763dbc823e08575267c3c 100644
|
|
|
---- a/src/common/mac/dump_syms.cc
|
|
|
-+++ b/src/common/mac/dump_syms.cc
|
|
|
-@@ -351,18 +351,15 @@ class DumpSymbols::DumperLineToModule:
|
|
|
- compilation_dir_ = compilation_dir;
|
|
|
- }
|
|
|
-
|
|
|
-- void ReadProgram(const uint8_t* program,
|
|
|
-- uint64_t length,
|
|
|
-+ void ReadProgram(const uint8_t* program, uint64_t length,
|
|
|
- const uint8_t* string_section,
|
|
|
- uint64_t string_section_length,
|
|
|
- const uint8_t* line_string_section,
|
|
|
- uint64_t line_string_section_length,
|
|
|
-- Module* module,
|
|
|
-- vector<Module::Line>* lines,
|
|
|
-- std::map<uint32_t, Module::File*>* files) {
|
|
|
-- DwarfLineToModule handler(module, compilation_dir_, lines, files);
|
|
|
-- LineInfo parser(program, length, byte_reader_, nullptr, 0,
|
|
|
-- nullptr, 0, &handler);
|
|
|
-+ Module* module, vector<Module::Line>* lines) {
|
|
|
-+ DwarfLineToModule handler(module, compilation_dir_, lines);
|
|
|
-+ LineInfo parser(program, length, byte_reader_,
|
|
|
-+ nullptr, 0, nullptr, 0, &handler);
|
|
|
- parser.Start();
|
|
|
- }
|
|
|
- private:
|
|
|
-diff --git a/src/common/module.cc b/src/common/module.cc
|
|
|
-index eccd01f0957eaf623dcf417fffe379cbfa76322c..0ecf6ca6eb8611e0a06d3631fd76b9f73957c6b6 100644
|
|
|
---- a/src/common/module.cc
|
|
|
-+++ b/src/common/module.cc
|
|
|
-@@ -38,16 +38,14 @@
|
|
|
- #include <stdio.h>
|
|
|
- #include <string.h>
|
|
|
-
|
|
|
--#include <functional>
|
|
|
- #include <iostream>
|
|
|
--#include <memory>
|
|
|
- #include <utility>
|
|
|
-
|
|
|
- namespace google_breakpad {
|
|
|
-
|
|
|
- using std::dec;
|
|
|
- using std::hex;
|
|
|
--using std::unique_ptr;
|
|
|
-+
|
|
|
-
|
|
|
- Module::Module(const string& name, const string& os,
|
|
|
- const string& architecture, const string& id,
|
|
|
-@@ -216,13 +214,6 @@ void Module::AssignSourceIds() {
|
|
|
- line_it != func->lines.end(); ++line_it)
|
|
|
- line_it->file->source_id = 0;
|
|
|
- }
|
|
|
-- // Also mark all files cited by inline functions by setting each one's source
|
|
|
-- // id to zero.
|
|
|
-- for (InlineOrigin* origin : inline_origins_)
|
|
|
-- // There are some artificial inline functions which don't belong to
|
|
|
-- // any file. Those will have file id -1.
|
|
|
-- if (origin->file)
|
|
|
-- origin->file->source_id = 0;
|
|
|
-
|
|
|
- // Finally, assign source ids to those files that have been marked.
|
|
|
- // We could have just assigned source id numbers while traversing
|
|
|
-@@ -236,33 +227,6 @@ void Module::AssignSourceIds() {
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
--static void InlineDFS(
|
|
|
-- vector<unique_ptr<Module::Inline>>& inlines,
|
|
|
-- std::function<void(unique_ptr<Module::Inline>&)> const& forEach) {
|
|
|
-- for (unique_ptr<Module::Inline>& in : inlines) {
|
|
|
-- forEach(in);
|
|
|
-- InlineDFS(in->child_inlines, forEach);
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
--void Module::CreateInlineOrigins() {
|
|
|
-- // Only add origins that have file and deduplicate origins with same name and
|
|
|
-- // file id by doing a DFS.
|
|
|
-- auto addInlineOrigins = [&](unique_ptr<Inline> &in) {
|
|
|
-- auto it = inline_origins_.find(in->origin);
|
|
|
-- if (it == inline_origins_.end())
|
|
|
-- inline_origins_.insert(in->origin);
|
|
|
-- else
|
|
|
-- in->origin = *it;
|
|
|
-- };
|
|
|
-- for (Function* func : functions_)
|
|
|
-- InlineDFS(func->inlines, addInlineOrigins);
|
|
|
-- int next_id = 0;
|
|
|
-- for (InlineOrigin* origin: inline_origins_) {
|
|
|
-- origin->id = next_id++;
|
|
|
-- }
|
|
|
--}
|
|
|
--
|
|
|
- bool Module::ReportError() {
|
|
|
- fprintf(stderr, "error writing symbol file: %s\n",
|
|
|
- strerror(errno));
|
|
|
-@@ -303,8 +267,6 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
|
|
|
- }
|
|
|
-
|
|
|
- if (symbol_data & SYMBOLS_AND_FILES) {
|
|
|
-- if (symbol_data & INLINES)
|
|
|
-- CreateInlineOrigins();
|
|
|
- AssignSourceIds();
|
|
|
-
|
|
|
- // Write out files.
|
|
|
-@@ -317,17 +279,8 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
|
|
|
- return ReportError();
|
|
|
- }
|
|
|
- }
|
|
|
-- // Write out inline origins.
|
|
|
-- if (symbol_data & INLINES) {
|
|
|
-- for (InlineOrigin* origin : inline_origins_) {
|
|
|
-- stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID()
|
|
|
-- << " " << origin->name << "\n";
|
|
|
-- if (!stream.good())
|
|
|
-- return ReportError();
|
|
|
-- }
|
|
|
-- }
|
|
|
-
|
|
|
-- // Write out functions and their inlines and lines.
|
|
|
-+ // Write out functions and their lines.
|
|
|
- for (FunctionSet::const_iterator func_it = functions_.begin();
|
|
|
- func_it != functions_.end(); ++func_it) {
|
|
|
- Function* func = *func_it;
|
|
|
-@@ -343,21 +296,6 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) {
|
|
|
- if (!stream.good())
|
|
|
- return ReportError();
|
|
|
-
|
|
|
-- // Write out inlines.
|
|
|
-- if (symbol_data & INLINES) {
|
|
|
-- auto write_inline = [&](unique_ptr<Inline>& in) {
|
|
|
-- stream << "INLINE ";
|
|
|
-- stream << in->inline_nest_level << " " << in->call_site_line << " "
|
|
|
-- << in->origin->id << hex;
|
|
|
-- for (const Range& r : in->ranges)
|
|
|
-- stream << " " << (r.address - load_address_) << " " << r.size;
|
|
|
-- stream << dec << "\n";
|
|
|
-- };
|
|
|
-- InlineDFS(func->inlines, write_inline);
|
|
|
-- if (!stream.good())
|
|
|
-- return ReportError();
|
|
|
-- }
|
|
|
--
|
|
|
- while ((line_it != func->lines.end()) &&
|
|
|
- (line_it->address >= range_it->address) &&
|
|
|
- (line_it->address < (range_it->address + range_it->size))) {
|
|
|
-diff --git a/src/common/module.h b/src/common/module.h
|
|
|
-index e8678914ff962e35ca3fb35febd7283813762603..f2fff4909a28ad52542f1c7ea95881849e039478 100644
|
|
|
---- a/src/common/module.h
|
|
|
-+++ b/src/common/module.h
|
|
|
-@@ -41,7 +41,6 @@
|
|
|
- #include <iostream>
|
|
|
- #include <limits>
|
|
|
- #include <map>
|
|
|
--#include <memory>
|
|
|
- #include <set>
|
|
|
- #include <string>
|
|
|
- #include <vector>
|
|
|
-@@ -67,8 +66,6 @@ class Module {
|
|
|
- static constexpr uint64_t kMaxAddress = std::numeric_limits<Address>::max();
|
|
|
- struct File;
|
|
|
- struct Function;
|
|
|
-- struct InlineOrigin;
|
|
|
-- struct Inline;
|
|
|
- struct Line;
|
|
|
- struct Extern;
|
|
|
-
|
|
|
-@@ -123,50 +120,6 @@ class Module {
|
|
|
- // Source lines belonging to this function, sorted by increasing
|
|
|
- // address.
|
|
|
- vector<Line> lines;
|
|
|
--
|
|
|
-- // Inlined call sites belonging to this functions.
|
|
|
-- vector<std::unique_ptr<Inline>> inlines;
|
|
|
-- };
|
|
|
--
|
|
|
-- struct InlineOrigin {
|
|
|
-- InlineOrigin(const string& name): id(-1), name(name), file(NULL) {}
|
|
|
--
|
|
|
-- // A unique id for each InlineOrigin object. INLINE records use the id to
|
|
|
-- // refer to its INLINE_ORIGIN record.
|
|
|
-- int id;
|
|
|
--
|
|
|
-- // The inlined function's name.
|
|
|
-- string name;
|
|
|
--
|
|
|
-- File* file;
|
|
|
--
|
|
|
-- int getFileID() const { return file ? file->source_id : -1; }
|
|
|
-- };
|
|
|
--
|
|
|
-- // A inlined call site.
|
|
|
-- struct Inline {
|
|
|
-- Inline(InlineOrigin* origin,
|
|
|
-- const vector<Range>& ranges,
|
|
|
-- int call_site_line,
|
|
|
-- int inline_nest_level,
|
|
|
-- vector<std::unique_ptr<Inline>> child_inlines)
|
|
|
-- : origin(origin),
|
|
|
-- ranges(ranges),
|
|
|
-- call_site_line(call_site_line),
|
|
|
-- inline_nest_level(inline_nest_level),
|
|
|
-- child_inlines(std::move(child_inlines)) {}
|
|
|
--
|
|
|
-- InlineOrigin* origin;
|
|
|
--
|
|
|
-- // The list of addresses and sizes.
|
|
|
-- vector<Range> ranges;
|
|
|
--
|
|
|
-- int call_site_line;
|
|
|
--
|
|
|
-- int inline_nest_level;
|
|
|
--
|
|
|
-- // A list of inlines which are children of this inline.
|
|
|
-- vector<std::unique_ptr<Inline>> child_inlines;
|
|
|
- };
|
|
|
-
|
|
|
- // A source line.
|
|
|
-@@ -226,14 +179,6 @@ class Module {
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
-- struct InlineOriginCompare {
|
|
|
-- bool operator() (const InlineOrigin* lhs, const InlineOrigin* rhs) const {
|
|
|
-- if (lhs->getFileID() == rhs->getFileID())
|
|
|
-- return lhs->name < rhs->name;
|
|
|
-- return lhs->getFileID() < rhs->getFileID();
|
|
|
-- }
|
|
|
-- };
|
|
|
--
|
|
|
- struct ExternCompare {
|
|
|
- bool operator() (const Extern* lhs, const Extern* rhs) const {
|
|
|
- return lhs->address < rhs->address;
|
|
|
-@@ -330,10 +275,6 @@ class Module {
|
|
|
- // symbol file, at which point we omit any unused files.
|
|
|
- void AssignSourceIds();
|
|
|
-
|
|
|
-- // This function should be called before AssignSourceIds() to get the set of
|
|
|
-- // valid InlineOrigins*.
|
|
|
-- void CreateInlineOrigins();
|
|
|
--
|
|
|
- // Call AssignSourceIds, and write this module to STREAM in the
|
|
|
- // breakpad symbol format. Return true if all goes well, or false if
|
|
|
- // an error occurs. This method writes out:
|
|
|
-@@ -393,9 +334,6 @@ class Module {
|
|
|
- // A set containing Function structures, sorted by address.
|
|
|
- typedef set<Function*, FunctionCompare> FunctionSet;
|
|
|
-
|
|
|
-- // A set containing Function structures, sorted by address.
|
|
|
-- typedef set<InlineOrigin*, InlineOriginCompare> InlineOriginSet;
|
|
|
--
|
|
|
- // A set containing Extern structures, sorted by address.
|
|
|
- typedef set<Extern*, ExternCompare> ExternSet;
|
|
|
-
|
|
|
-@@ -404,7 +342,6 @@ class Module {
|
|
|
- // point to.
|
|
|
- FileByNameMap files_; // This module's source files.
|
|
|
- FunctionSet functions_; // This module's functions.
|
|
|
-- InlineOriginSet inline_origins_; // This module's inline origins.
|
|
|
-
|
|
|
- // The module owns all the call frame info entries that have been
|
|
|
- // added to it.
|
|
|
-diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc
|
|
|
-index b0f56e958960534e43febb001d23b11205640507..a562bffbfbf33a587d46824506a915b03abbe59d 100644
|
|
|
---- a/src/tools/linux/dump_syms/dump_syms.cc
|
|
|
-+++ b/src/tools/linux/dump_syms/dump_syms.cc
|
|
|
-@@ -50,7 +50,6 @@ int usage(const char* self) {
|
|
|
- fprintf(stderr, "Options:\n");
|
|
|
- fprintf(stderr, " -i: Output module header information only.\n");
|
|
|
- fprintf(stderr, " -c Do not generate CFI section\n");
|
|
|
-- fprintf(stderr, " -d Generate INLINE/INLINE_ORIGIN records\n");
|
|
|
- fprintf(stderr, " -r Do not handle inter-compilation "
|
|
|
- "unit references\n");
|
|
|
- fprintf(stderr, " -v Print all warnings to stderr\n");
|
|
|
-@@ -65,7 +64,6 @@ int main(int argc, char** argv) {
|
|
|
- return usage(argv[0]);
|
|
|
- bool header_only = false;
|
|
|
- bool cfi = true;
|
|
|
-- bool handle_inlines = false;
|
|
|
- bool handle_inter_cu_refs = true;
|
|
|
- bool log_to_stderr = false;
|
|
|
- std::string obj_name;
|
|
|
-@@ -77,8 +75,6 @@ int main(int argc, char** argv) {
|
|
|
- header_only = true;
|
|
|
- } else if (strcmp("-c", argv[arg_index]) == 0) {
|
|
|
- cfi = false;
|
|
|
-- } else if (strcmp("-d", argv[arg_index]) == 0) {
|
|
|
-- handle_inlines = true;
|
|
|
- } else if (strcmp("-r", argv[arg_index]) == 0) {
|
|
|
- handle_inter_cu_refs = false;
|
|
|
- } else if (strcmp("-v", argv[arg_index]) == 0) {
|
|
|
-@@ -131,8 +127,8 @@ int main(int argc, char** argv) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
- } else {
|
|
|
-- SymbolData symbol_data = (handle_inlines ? INLINES : NO_DATA) |
|
|
|
-- (cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES;
|
|
|
-+ SymbolData symbol_data =
|
|
|
-+ INLINES | (cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES;
|
|
|
- google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs);
|
|
|
- if (!WriteSymbolFile(binary, obj_name, obj_os, debug_dirs, options,
|
|
|
- std::cout)) {
|