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

@ -564,3 +564,53 @@ TEST(Construct, FunctionsAndThumbExternsWithSameAddress) {
"PUBLIC cc00 0 arm_func\n",
contents.c_str());
}
TEST(Write, OutOfRangeAddresses) {
stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Specify an allowed address range, representing a PT_LOAD segment in a
// module.
vector<Module::Range> address_ranges = {
Module::Range(0x2000ULL, 0x1000ULL),
};
m.SetAddressRanges(address_ranges);
// Add three stack frames (one lower, one in, and one higher than the allowed
// address range). Only the middle frame should be captured.
Module::StackFrameEntry* entry1 = new Module::StackFrameEntry();
entry1->address = 0x1000ULL;
entry1->size = 0x100ULL;
m.AddStackFrameEntry(entry1);
Module::StackFrameEntry* entry2 = new Module::StackFrameEntry();
entry2->address = 0x2000ULL;
entry2->size = 0x100ULL;
m.AddStackFrameEntry(entry2);
Module::StackFrameEntry* entry3 = new Module::StackFrameEntry();
entry3->address = 0x3000ULL;
entry3->size = 0x100ULL;
m.AddStackFrameEntry(entry3);
// Add a function outside the allowed range.
Module::File* file = m.FindFile("file_name.cc");
Module::Function* function = new Module::Function(
"function_name", 0x4000ULL);
Module::Range range(0x4000ULL, 0x1000ULL);
function->ranges.push_back(range);
function->parameter_size = 0x100ULL;
Module::Line line = { 0x4000ULL, 0x100ULL, file, 67519080 };
function->lines.push_back(line);
m.AddFunction(function);
// Add an extern outside the allowed range.
Module::Extern* extern1 = new Module::Extern(0x5000ULL);
extern1->name = "_xyz";
m.AddExtern(extern1);
m.Write(s, ALL_SYMBOL_DATA);
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"STACK CFI INIT 2000 100 \n",
s.str().c_str());
}