aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
authorChristopher Grant <cjgrant@chromium.org>2019-10-29 14:56:38 -0400
committerJoshua Peraza <jperaza@chromium.org>2019-10-29 19:03:12 +0000
commit862c9f47efe9ea2ff80c4acc94f5595b487878b8 (patch)
tree8a1b7736a888b1a526858b8c70713b0f4a5bfeda /src/common/linux
parentAdd options to set OS and filename (diff)
downloadbreakpad-862c9f47efe9ea2ff80c4acc94f5595b487878b8.tar.xz
linux, dump_syms: Filter module entries outside specified ranges
Partitioned libraries generated with lld and llvm-objcopy currently contain a superset of debug information, beyond what applies to the library itself. This is because objcopy cannot split up debug information by partition - instead, it places a copy of all debug information into each partition. In lieu of potential future support for lld or objcopy becoming able to split up debug information, let dump_syms do the next best thing: - Find the address ranges of all PT_LOAD segments in the lib. - Supply these to the Module being generated. - Filter additions to the Module based on these ranges. Bug: 990190 Change-Id: Ib5f279f42e3f6ea79eed9665efbcc23c3c5d25dc Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1884699 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/dump_symbols.cc25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index 660f133e..e561ad94 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -182,6 +182,23 @@ typename ElfClass::Addr GetLoadingAddress(
return 0;
}
+// Find the set of address ranges for all PT_LOAD segments.
+template <typename ElfClass>
+vector<Module::Range> GetPtLoadSegmentRanges(
+ const typename ElfClass::Phdr* program_headers,
+ int nheader) {
+ typedef typename ElfClass::Phdr Phdr;
+ vector<Module::Range> ranges;
+
+ for (int i = 0; i < nheader; ++i) {
+ const Phdr& header = program_headers[i];
+ if (header.p_type == PT_LOAD) {
+ ranges.push_back(Module::Range(header.p_vaddr, header.p_memsz));
+ }
+ }
+ return ranges;
+}
+
#ifndef NO_STABS_SUPPORT
template<typename ElfClass>
bool LoadStabs(const typename ElfClass::Ehdr* elf_header,
@@ -649,6 +666,14 @@ bool LoadSymbols(const string& obj_file,
module->SetLoadAddress(loading_addr);
info->set_loading_addr(loading_addr, obj_file);
+ // Allow filtering of extraneous debug information in partitioned libraries.
+ // Such libraries contain debug information for all libraries extracted from
+ // the same combined library, implying extensive duplication.
+ vector<Module::Range> address_ranges = GetPtLoadSegmentRanges<ElfClass>(
+ GetOffset<ElfClass, Phdr>(elf_header, elf_header->e_phoff),
+ elf_header->e_phnum);
+ module->SetAddressRanges(address_ranges);
+
const Shdr* sections =
GetOffset<ElfClass, Shdr>(elf_header, elf_header->e_shoff);
const Shdr* section_names = sections + elf_header->e_shstrndx;