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_(),
|
||||
skeleton_dwo_id_(0), addr_base_(0),
|
||||
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.
|
||||
// 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
|
||||
// processing the original compilation unit.
|
||||
|
||||
void CompilationUnit::SetSplitDwarf(
|
||||
uint64_t addr_base,
|
||||
void CompilationUnit::SetSplitDwarf(uint64_t addr_base,
|
||||
uint64_t dwo_id) {
|
||||
is_split_dwarf_ = true;
|
||||
addr_base_ = addr_base;
|
||||
|
@ -435,6 +435,12 @@ uint64_t CompilationUnit::Start() {
|
|||
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.
|
||||
iter = GetSectionByName(sections_, ".debug_line_str");
|
||||
if (iter != sections_.end()) {
|
||||
|
|
|
@ -496,6 +496,18 @@ class CompilationUnit {
|
|||
|
||||
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_; }
|
||||
|
||||
private:
|
||||
|
@ -585,6 +597,10 @@ class CompilationUnit {
|
|||
else if (attr == DW_AT_low_pc) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -696,7 +712,7 @@ class CompilationUnit {
|
|||
const uint8_t* string_buffer_;
|
||||
uint64_t string_buffer_length_;
|
||||
|
||||
// Similarly for .debug_line_string.
|
||||
// Similarly for .debug_line_str.
|
||||
const uint8_t* line_string_buffer_;
|
||||
uint64_t line_string_buffer_length_;
|
||||
|
||||
|
@ -710,6 +726,10 @@ class CompilationUnit {
|
|||
const uint8_t* addr_buffer_;
|
||||
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
|
||||
// or .dwp file. If true, we are reading this unit because 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.
|
||||
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
|
||||
|
|
|
@ -1075,7 +1075,9 @@ DwarfCUToModule::DwarfCUToModule(FileContext* file_context,
|
|||
WarningReporter* reporter,
|
||||
bool handle_inline,
|
||||
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),
|
||||
line_reader_(line_reader),
|
||||
cu_context_(new CUContext(file_context,
|
||||
|
@ -1084,7 +1086,8 @@ DwarfCUToModule::DwarfCUToModule(FileContext* file_context,
|
|||
low_pc,
|
||||
addr_base)),
|
||||
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() {
|
||||
}
|
||||
|
|
|
@ -266,7 +266,9 @@ class DwarfCUToModule: public RootDIEHandler {
|
|||
WarningReporter* reporter,
|
||||
bool handle_inline = false,
|
||||
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();
|
||||
|
||||
void ProcessAttributeSigned(enum DwarfAttribute attr,
|
||||
|
|
|
@ -351,19 +351,29 @@ void StartProcessSplitDwarf(google_breakpad::CompilationUnit* reader,
|
|||
for (auto section : split_sections)
|
||||
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
||||
section.second.second);
|
||||
// Because DWP/DWO file doesn't have .debug_addr/.debug_line, its debug info
|
||||
// will refer to .debug_addr/.debug_line in the main binary.
|
||||
// Because DWP/DWO file doesn't have .debug_addr/.debug_line/.debug_line_str,
|
||||
// its debug info will refer to .debug_addr/.debug_line in the main binary.
|
||||
if (file_context.section_map().find(".debug_addr") ==
|
||||
file_context.section_map().end())
|
||||
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
||||
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);
|
||||
DumperLineToModule line_to_module(&split_byte_reader);
|
||||
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
||||
DwarfCUToModule root_handler(&file_context, &line_to_module, &ranges_handler,
|
||||
&reporter, handle_inline, reader->GetLowPC(),
|
||||
reader->GetAddrBase());
|
||||
DwarfCUToModule root_handler(
|
||||
&file_context, &line_to_module, &ranges_handler, &reporter, handle_inline,
|
||||
reader->GetLowPC(), reader->GetAddrBase(), reader->HasSourceLineInfo(),
|
||||
reader->GetSourceLineOffset());
|
||||
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
||||
google_breakpad::CompilationUnit split_reader(
|
||||
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
||||
|
|
|
@ -442,18 +442,28 @@ void DumpSymbols::StartProcessSplitDwarf(
|
|||
for (auto section : split_sections)
|
||||
file_context.AddSectionToSectionMap(section.first, section.second.first,
|
||||
section.second.second);
|
||||
// If DWP/DWO file doesn't have .debug_addr, its debug info will refer to
|
||||
// .debug_addr in the main binary.
|
||||
// Because DWP/DWO file doesn't have .debug_addr/.debug_line/.debug_line_str,
|
||||
// its debug info will refer to .debug_addr/.debug_line in the main binary.
|
||||
if (file_context.section_map().find(".debug_addr") ==
|
||||
file_context.section_map().end())
|
||||
file_context.AddSectionToSectionMap(".debug_addr", reader->GetAddrBuffer(),
|
||||
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);
|
||||
DumperLineToModule line_to_module(&split_byte_reader);
|
||||
DwarfCUToModule::WarningReporter reporter(split_file, cu_offset);
|
||||
DwarfCUToModule root_handler(&file_context, &line_to_module, &ranges_handler,
|
||||
&reporter, handle_inline, reader->GetLowPC(),
|
||||
reader->GetAddrBase());
|
||||
DwarfCUToModule root_handler(
|
||||
&file_context, &line_to_module, &ranges_handler, &reporter, handle_inline,
|
||||
reader->GetLowPC(), reader->GetAddrBase(), reader->HasSourceLineInfo(),
|
||||
reader->GetSourceLineOffset());
|
||||
google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
|
||||
google_breakpad::CompilationUnit split_reader(
|
||||
split_file, file_context.section_map(), cu_offset, &split_byte_reader,
|
||||
|
|
Loading…
Reference in a new issue