Share .debug_line and .debug_line_str among dwp file and main binary file.
The debug info in the dwp file needs to refer to the .debug_line and .debug_line_str sections in the main binary. This fixes dump_syms not generating LINE records for dwp in split dwarf. Bug: chromium:1448979 Change-Id: I71923f12cea72caae081c1406e2cbca55e95859e Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4576346 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
18aa6faf2e
commit
a9bb984785
6 changed files with 72 additions and 17 deletions
|
@ -82,7 +82,8 @@ CompilationUnit::CompilationUnit(const string& path,
|
||||||
is_split_dwarf_(false), is_type_unit_(false), dwo_id_(0), dwo_name_(),
|
is_split_dwarf_(false), is_type_unit_(false), dwo_id_(0), dwo_name_(),
|
||||||
skeleton_dwo_id_(0), addr_base_(0),
|
skeleton_dwo_id_(0), addr_base_(0),
|
||||||
str_offsets_base_(0), have_checked_for_dwp_(false),
|
str_offsets_base_(0), have_checked_for_dwp_(false),
|
||||||
should_process_split_dwarf_(false) {}
|
should_process_split_dwarf_(false), low_pc_(0),
|
||||||
|
has_source_line_info_(false), source_line_offset_(0) {}
|
||||||
|
|
||||||
// Initialize a compilation unit from a .dwo or .dwp file.
|
// Initialize a compilation unit from a .dwo or .dwp file.
|
||||||
// In this case, we need the .debug_addr section from the
|
// In this case, we need the .debug_addr section from the
|
||||||
|
@ -91,8 +92,7 @@ CompilationUnit::CompilationUnit(const string& path,
|
||||||
// the executable file, and call it as if we were still
|
// the executable file, and call it as if we were still
|
||||||
// processing the original compilation unit.
|
// processing the original compilation unit.
|
||||||
|
|
||||||
void CompilationUnit::SetSplitDwarf(
|
void CompilationUnit::SetSplitDwarf(uint64_t addr_base,
|
||||||
uint64_t addr_base,
|
|
||||||
uint64_t dwo_id) {
|
uint64_t dwo_id) {
|
||||||
is_split_dwarf_ = true;
|
is_split_dwarf_ = true;
|
||||||
addr_base_ = addr_base;
|
addr_base_ = addr_base;
|
||||||
|
@ -435,6 +435,12 @@ uint64_t CompilationUnit::Start() {
|
||||||
string_buffer_length_ = iter->second.second;
|
string_buffer_length_ = iter->second.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iter = GetSectionByName(sections_, ".debug_line");
|
||||||
|
if (iter != sections_.end()) {
|
||||||
|
line_buffer_ = iter->second.first;
|
||||||
|
line_buffer_length_ = iter->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the line string section if we have one.
|
// Set the line string section if we have one.
|
||||||
iter = GetSectionByName(sections_, ".debug_line_str");
|
iter = GetSectionByName(sections_, ".debug_line_str");
|
||||||
if (iter != sections_.end()) {
|
if (iter != sections_.end()) {
|
||||||
|
|
|
@ -496,6 +496,18 @@ class CompilationUnit {
|
||||||
|
|
||||||
uint64_t GetDWOID() { return dwo_id_; }
|
uint64_t GetDWOID() { return dwo_id_; }
|
||||||
|
|
||||||
|
const uint8_t* GetLineBuffer() { return line_buffer_; }
|
||||||
|
|
||||||
|
uint64_t GetLineBufferLen() { return line_buffer_length_; }
|
||||||
|
|
||||||
|
const uint8_t* GetLineStrBuffer() { return line_string_buffer_; }
|
||||||
|
|
||||||
|
uint64_t GetLineStrBufferLen() { return line_string_buffer_length_; }
|
||||||
|
|
||||||
|
bool HasSourceLineInfo() { return has_source_line_info_; }
|
||||||
|
|
||||||
|
uint64_t GetSourceLineOffset() { return source_line_offset_; }
|
||||||
|
|
||||||
bool ShouldProcessSplitDwarf() { return should_process_split_dwarf_; }
|
bool ShouldProcessSplitDwarf() { return should_process_split_dwarf_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -585,6 +597,10 @@ class CompilationUnit {
|
||||||
else if (attr == DW_AT_low_pc) {
|
else if (attr == DW_AT_low_pc) {
|
||||||
low_pc_ = data;
|
low_pc_ = data;
|
||||||
}
|
}
|
||||||
|
else if (attr == DW_AT_stmt_list) {
|
||||||
|
has_source_line_info_ = true;
|
||||||
|
source_line_offset_ = data;
|
||||||
|
}
|
||||||
handler_->ProcessAttributeUnsigned(offset, attr, form, data);
|
handler_->ProcessAttributeUnsigned(offset, attr, form, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +712,7 @@ class CompilationUnit {
|
||||||
const uint8_t* string_buffer_;
|
const uint8_t* string_buffer_;
|
||||||
uint64_t string_buffer_length_;
|
uint64_t string_buffer_length_;
|
||||||
|
|
||||||
// Similarly for .debug_line_string.
|
// Similarly for .debug_line_str.
|
||||||
const uint8_t* line_string_buffer_;
|
const uint8_t* line_string_buffer_;
|
||||||
uint64_t line_string_buffer_length_;
|
uint64_t line_string_buffer_length_;
|
||||||
|
|
||||||
|
@ -710,6 +726,10 @@ class CompilationUnit {
|
||||||
const uint8_t* addr_buffer_;
|
const uint8_t* addr_buffer_;
|
||||||
uint64_t addr_buffer_length_;
|
uint64_t addr_buffer_length_;
|
||||||
|
|
||||||
|
// .debug_line section buffer and length.
|
||||||
|
const uint8_t* line_buffer_;
|
||||||
|
uint64_t line_buffer_length_;
|
||||||
|
|
||||||
// Flag indicating whether this compilation unit is part of a .dwo
|
// Flag indicating whether this compilation unit is part of a .dwo
|
||||||
// or .dwp file. If true, we are reading this unit because a
|
// or .dwp file. If true, we are reading this unit because a
|
||||||
// skeleton compilation unit in an executable file had a
|
// skeleton compilation unit in an executable file had a
|
||||||
|
@ -757,6 +777,10 @@ class CompilationUnit {
|
||||||
|
|
||||||
// The value of the DW_AT_low_pc attribute, if any.
|
// The value of the DW_AT_low_pc attribute, if any.
|
||||||
uint64_t low_pc_;
|
uint64_t low_pc_;
|
||||||
|
|
||||||
|
// The value of DW_AT_stmt_list attribute if any.
|
||||||
|
bool has_source_line_info_;
|
||||||
|
uint64_t source_line_offset_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A Reader for a .dwp file. Supports the fetching of DWARF debug
|
// A Reader for a .dwp file. Supports the fetching of DWARF debug
|
||||||
|
|
|
@ -1075,7 +1075,9 @@ DwarfCUToModule::DwarfCUToModule(FileContext* file_context,
|
||||||
WarningReporter* reporter,
|
WarningReporter* reporter,
|
||||||
bool handle_inline,
|
bool handle_inline,
|
||||||
uint64_t low_pc,
|
uint64_t low_pc,
|
||||||
uint64_t addr_base)
|
uint64_t addr_base,
|
||||||
|
bool has_source_line_info,
|
||||||
|
uint64_t source_line_offset)
|
||||||
: RootDIEHandler(handle_inline),
|
: RootDIEHandler(handle_inline),
|
||||||
line_reader_(line_reader),
|
line_reader_(line_reader),
|
||||||
cu_context_(new CUContext(file_context,
|
cu_context_(new CUContext(file_context,
|
||||||
|
@ -1084,7 +1086,8 @@ DwarfCUToModule::DwarfCUToModule(FileContext* file_context,
|
||||||
low_pc,
|
low_pc,
|
||||||
addr_base)),
|
addr_base)),
|
||||||
child_context_(new DIEContext()),
|
child_context_(new DIEContext()),
|
||||||
has_source_line_info_(false) {}
|
has_source_line_info_(has_source_line_info),
|
||||||
|
source_line_offset_(source_line_offset) {}
|
||||||
|
|
||||||
DwarfCUToModule::~DwarfCUToModule() {
|
DwarfCUToModule::~DwarfCUToModule() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,9 @@ class DwarfCUToModule: public RootDIEHandler {
|
||||||
WarningReporter* reporter,
|
WarningReporter* reporter,
|
||||||
bool handle_inline = false,
|
bool handle_inline = false,
|
||||||
uint64_t low_pc = 0,
|
uint64_t low_pc = 0,
|
||||||
uint64_t addr_base = 0);
|
uint64_t addr_base = 0,
|
||||||
|
bool has_source_line_info = false,
|
||||||
|
uint64_t source_line_offset = 0);
|
||||||
~DwarfCUToModule();
|
~DwarfCUToModule();
|
||||||
|
|
||||||
void ProcessAttributeSigned(enum DwarfAttribute attr,
|
void ProcessAttributeSigned(enum DwarfAttribute attr,
|
||||||
|
|
|
@ -351,19 +351,29 @@ void StartProcessSplitDwarf(google_breakpad::CompilationUnit* reader,
|
||||||
for (auto section : split_sections)
|
for (auto section : split_sections)
|
||||||
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
||||||
section.second.second);
|
section.second.second);
|
||||||
// Because DWP/DWO file doesn't have .debug_addr/.debug_line, its debug info
|
// Because DWP/DWO file doesn't have .debug_addr/.debug_line/.debug_line_str,
|
||||||
// will refer to .debug_addr/.debug_line in the main binary.
|
// its debug info will refer to .debug_addr/.debug_line in the main binary.
|
||||||
if (file_context.section_map().find(".debug_addr") ==
|
if (file_context.section_map().find(".debug_addr") ==
|
||||||
file_context.section_map().end())
|
file_context.section_map().end())
|
||||||
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
||||||
reader->GetAddrBufferLen());
|
reader->GetAddrBufferLen());
|
||||||
|
if (file_context.section_map().find(".debug_line") ==
|
||||||
|
file_context.section_map().end())
|
||||||
|
file_context.AddSectionToSectionMap(".debug_line", reader->GetLineBuffer(),
|
||||||
|
reader->GetLineBufferLen());
|
||||||
|
if (file_context.section_map().find(".debug_line_str") ==
|
||||||
|
file_context.section_map().end())
|
||||||
|
file_context.AddSectionToSectionMap(".debug_line_str",
|
||||||
|
reader->GetLineStrBuffer(),
|
||||||
|
reader->GetLineStrBufferLen());
|
||||||
|
|
||||||
DumperRangesHandler ranges_handler(&split_byte_reader);
|
DumperRangesHandler ranges_handler(&split_byte_reader);
|
||||||
DumperLineToModule line_to_module(&split_byte_reader);
|
DumperLineToModule line_to_module(&split_byte_reader);
|
||||||
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
||||||
DwarfCUToModule root_handler(&file_context, &line_to_module, &ranges_handler,
|
DwarfCUToModule root_handler(
|
||||||
&reporter, handle_inline, reader->GetLowPC(),
|
&file_context, &line_to_module, &ranges_handler, &reporter, handle_inline,
|
||||||
reader->GetAddrBase());
|
reader->GetLowPC(), reader->GetAddrBase(), reader->HasSourceLineInfo(),
|
||||||
|
reader->GetSourceLineOffset());
|
||||||
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
||||||
google_breakpad::CompilationUnit split_reader(
|
google_breakpad::CompilationUnit split_reader(
|
||||||
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
||||||
|
|
|
@ -442,18 +442,28 @@ void DumpSymbols::StartProcessSplitDwarf(
|
||||||
for (auto section : split_sections)
|
for (auto section : split_sections)
|
||||||
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
||||||
section.second.second);
|
section.second.second);
|
||||||
// If DWP/DWO file doesn't have .debug_addr, its debug info will refer to
|
// Because DWP/DWO file doesn't have .debug_addr/.debug_line/.debug_line_str,
|
||||||
// .debug_addr in the main binary.
|
// its debug info will refer to .debug_addr/.debug_line in the main binary.
|
||||||
if (file_context.section_map().find(".debug_addr") ==
|
if (file_context.section_map().find(".debug_addr") ==
|
||||||
file_context.section_map().end())
|
file_context.section_map().end())
|
||||||
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
||||||
reader->GetAddrBufferLen());
|
reader->GetAddrBufferLen());
|
||||||
|
if (file_context.section_map().find(".debug_line") ==
|
||||||
|
file_context.section_map().end())
|
||||||
|
file_context.AddSectionToSectionMap(".debug_line", reader->GetLineBuffer(),
|
||||||
|
reader->GetLineBufferLen());
|
||||||
|
if (file_context.section_map().find(".debug_line_str") ==
|
||||||
|
file_context.section_map().end())
|
||||||
|
file_context.AddSectionToSectionMap(".debug_line_str",
|
||||||
|
reader->GetLineStrBuffer(),
|
||||||
|
reader->GetLineStrBufferLen());
|
||||||
DumperRangesHandler ranges_handler(&split_byte_reader);
|
DumperRangesHandler ranges_handler(&split_byte_reader);
|
||||||
DumperLineToModule line_to_module(&split_byte_reader);
|
DumperLineToModule line_to_module(&split_byte_reader);
|
||||||
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
||||||
DwarfCUToModule root_handler(&file_context, &line_to_module, &ranges_handler,
|
DwarfCUToModule root_handler(
|
||||||
&reporter, handle_inline, reader->GetLowPC(),
|
&file_context, &line_to_module, &ranges_handler, &reporter, handle_inline,
|
||||||
reader->GetAddrBase());
|
reader->GetLowPC(), reader->GetAddrBase(), reader->HasSourceLineInfo(),
|
||||||
|
reader->GetSourceLineOffset());
|
||||||
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
||||||
google_breakpad::CompilationUnit split_reader(
|
google_breakpad::CompilationUnit split_reader(
|
||||||
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
||||||
|
|
Loading…
Reference in a new issue