diff --git a/src/common/mac/macho_reader.cc b/src/common/mac/macho_reader.cc index b42506cc..e89e0906 100644 --- a/src/common/mac/macho_reader.cc +++ b/src/common/mac/macho_reader.cc @@ -518,12 +518,21 @@ bool Reader::WalkSegmentSections(const Segment& segment, if (offset < size_t(segment.contents.start - buffer_.start) || offset > size_t(segment.contents.end - buffer_.start) || size > size_t(segment.contents.end - buffer_.start - offset)) { - reporter_->MisplacedSectionData(section.section_name, - section.segment_name); - return false; + if (offset > 0) { + reporter_->MisplacedSectionData(section.section_name, + section.segment_name); + 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.end = section.contents.start + size; } - section.contents.start = buffer_.start + offset; - section.contents.end = section.contents.start + size; } if (!handler->HandleSection(section)) return false; diff --git a/src/common/mac/macho_reader_unittest.cc b/src/common/mac/macho_reader_unittest.cc index dccda4e7..fb2c479c 100644 --- a/src/common/mac/macho_reader_unittest.cc +++ b/src/common/mac/macho_reader_unittest.cc @@ -1529,6 +1529,51 @@ TEST_F(LoadCommand, MisplacedSectionTooBig) { // to set all their labels by hand to get the (impossible) // 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. LoadedSection too_big; too_big.Append(10, '3');