Fix macos_dump_syms when __eh_frame is included in the dSYM file.
macho_reader assumes that every section in a segment exists, or none of the sections exist in the file (for dSYM files). https://reviews.llvm.org/D94460?id=315965 added __eh_frame section to the __TEXT segments in dSYM files. All the other sections are removed, but still have non-zero size in the header. macho_reader only looks at `fileoff` and `filesize` fields to determine the size of the segment, but it looks at `addr` and `size` to determine the size of the section, therefore it determines that the sections would not fit in the segment and refused to parse the file. In this case the removed sections all have offset == 0. Ignore such cases. Change-Id: Ife771f7b302c1bc81c673b1103492c41321b5e3e Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2911204 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
b7ce678aec
commit
f7428bc397
2 changed files with 59 additions and 5 deletions
|
@ -518,13 +518,22 @@ bool Reader::WalkSegmentSections(const Segment& segment,
|
||||||
if (offset < size_t(segment.contents.start - buffer_.start) ||
|
if (offset < size_t(segment.contents.start - buffer_.start) ||
|
||||||
offset > size_t(segment.contents.end - buffer_.start) ||
|
offset > size_t(segment.contents.end - buffer_.start) ||
|
||||||
size > size_t(segment.contents.end - buffer_.start - offset)) {
|
size > size_t(segment.contents.end - buffer_.start - offset)) {
|
||||||
|
if (offset > 0) {
|
||||||
reporter_->MisplacedSectionData(section.section_name,
|
reporter_->MisplacedSectionData(section.section_name,
|
||||||
section.segment_name);
|
section.segment_name);
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
// Mach-O files in .dSYM bundles have the contents of the loaded
|
||||||
|
// segments partially removed. The removed sections will have zero as
|
||||||
|
// their offset. MisplacedSectionData should not be called in this
|
||||||
|
// case.
|
||||||
|
section.contents.start = section.contents.end = NULL;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
section.contents.start = buffer_.start + offset;
|
section.contents.start = buffer_.start + offset;
|
||||||
section.contents.end = section.contents.start + size;
|
section.contents.end = section.contents.start + size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!handler->HandleSection(section))
|
if (!handler->HandleSection(section))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1529,6 +1529,51 @@ TEST_F(LoadCommand, MisplacedSectionTooBig) {
|
||||||
// to set all their labels by hand to get the (impossible)
|
// to set all their labels by hand to get the (impossible)
|
||||||
// configurations we want.
|
// configurations we want.
|
||||||
|
|
||||||
|
// A section with 0 as is start address.
|
||||||
|
LoadedSection empty;
|
||||||
|
empty.Append(10, '4');
|
||||||
|
empty.start() = 0;
|
||||||
|
empty.address() = segment.address() + 1;
|
||||||
|
empty.final_size() = empty.Size();
|
||||||
|
|
||||||
|
SegmentLoadCommand command;
|
||||||
|
command.Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057)
|
||||||
|
.AppendSectionEntry("empty", "segment", 0, 0x8b53ae5c, empty);
|
||||||
|
|
||||||
|
LoadCommands commands;
|
||||||
|
commands.Place(&command);
|
||||||
|
|
||||||
|
MachOFile file;
|
||||||
|
file.Header(&commands).Place(&segment);
|
||||||
|
|
||||||
|
ReadFile(&file, true, CPU_TYPE_ANY, 0);
|
||||||
|
|
||||||
|
Segment actual_segment;
|
||||||
|
EXPECT_TRUE(reader.FindSegment("segment", &actual_segment));
|
||||||
|
|
||||||
|
EXPECT_CALL(reporter, MisplacedSectionData("empty", "segment")).Times(0);
|
||||||
|
|
||||||
|
EXPECT_CALL(section_handler,
|
||||||
|
HandleSection(MatchSection(true, "empty", "segment",
|
||||||
|
empty.address().Value())))
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, §ion_handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LoadCommand, MisplacedSectionButSectionIsEmpty) {
|
||||||
|
WithConfiguration config(kLittleEndian, 64);
|
||||||
|
|
||||||
|
// The segment.
|
||||||
|
LoadedSection segment;
|
||||||
|
segment.address() = 0x696d83cc;
|
||||||
|
segment.Append(10, '0');
|
||||||
|
|
||||||
|
// The contents of the following sections don't matter, because
|
||||||
|
// we're not really going to Place them in segment; we're just going
|
||||||
|
// to set all their labels by hand to get the (impossible)
|
||||||
|
// configurations we want.
|
||||||
|
|
||||||
// A section that extends beyond the end of its section.
|
// A section that extends beyond the end of its section.
|
||||||
LoadedSection too_big;
|
LoadedSection too_big;
|
||||||
too_big.Append(10, '3');
|
too_big.Append(10, '3');
|
||||||
|
|
Loading…
Reference in a new issue