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>
This commit is contained in:
Christopher Grant 2019-10-29 14:56:38 -04:00 committed by Joshua Peraza
parent 17958ef62c
commit 862c9f47ef
4 changed files with 120 additions and 0 deletions

View file

@ -76,11 +76,19 @@ void Module::SetLoadAddress(Address address) {
load_address_ = address;
}
void Module::SetAddressRanges(const vector<Range>& ranges) {
address_ranges_ = ranges;
}
void Module::AddFunction(Function *function) {
// FUNC lines must not hold an empty name, so catch the problem early if
// callers try to add one.
assert(!function->name.empty());
if (!AddressIsInModule(function->address)) {
return;
}
// FUNCs are better than PUBLICs as they come with sizes, so remove an extern
// with the same address if present.
Extern ext(function->address);
@ -123,10 +131,18 @@ void Module::AddFunctions(vector<Function *>::iterator begin,
}
void Module::AddStackFrameEntry(StackFrameEntry *stack_frame_entry) {
if (!AddressIsInModule(stack_frame_entry->address)) {
return;
}
stack_frame_entries_.push_back(stack_frame_entry);
}
void Module::AddExtern(Extern *ext) {
if (!AddressIsInModule(ext->address)) {
return;
}
std::pair<ExternSet::iterator,bool> ret = externs_.insert(ext);
if (!ret.second) {
// Free the duplicate that was not inserted because this Module
@ -232,6 +248,19 @@ bool Module::WriteRuleMap(const RuleMap &rule_map, std::ostream &stream) {
return stream.good();
}
bool Module::AddressIsInModule(Address address) const {
if (address_ranges_.empty()) {
return true;
}
for (const auto& segment : address_ranges_) {
if (address >= segment.address &&
address < segment.address + segment.size) {
return true;
}
}
return false;
}
bool Module::Write(std::ostream &stream, SymbolData symbol_data) {
stream << "MODULE " << os_ << " " << architecture_ << " "
<< id_ << " " << name_ << "\n";