diff options
author | Christopher Grant <cjgrant@chromium.org> | 2019-10-29 14:56:38 -0400 |
---|---|---|
committer | Joshua Peraza <jperaza@chromium.org> | 2019-10-29 19:03:12 +0000 |
commit | 862c9f47efe9ea2ff80c4acc94f5595b487878b8 (patch) | |
tree | 8a1b7736a888b1a526858b8c70713b0f4a5bfeda /src/common/linux | |
parent | Add options to set OS and filename (diff) | |
download | breakpad-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.cc | 25 |
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; |