135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Copyright (c) 2010 Google Inc. 235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// All rights reserved. 335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// 435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Redistribution and use in source and binary forms, with or without 535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// modification, are permitted provided that the following conditions are 635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// met: 735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// 835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// * Redistributions of source code must retain the above copyright 935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// notice, this list of conditions and the following disclaimer. 1035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// * Redistributions in binary form must reproduce the above 1135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// copyright notice, this list of conditions and the following disclaimer 1235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// in the documentation and/or other materials provided with the 1335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// distribution. 1435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// * Neither the name of Google Inc. nor the names of its 1535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// contributors may be used to endorse or promote products derived from 1635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// this software without specific prior written permission. 1735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// 1835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 3035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 3135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 3235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// macho_reader_unittest.cc: Unit tests for google_breakpad::Mach_O::FatReader 3335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// and google_breakpad::Mach_O::Reader. 3435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 3535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include <map> 3635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include <string> 3735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include <vector> 3835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 3935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include "breakpad_googletest_includes.h" 4035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include "common/mac/macho_reader.h" 4135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek#include "common/test_assembler.h" 4235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 4335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczareknamespace mach_o = google_breakpad::mach_o; 4435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczareknamespace test_assembler = google_breakpad::test_assembler; 4535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 4635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::FatReader; 4735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::FileFlags; 4835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::FileType; 4935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::LoadCommandType; 5035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::Reader; 5135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::Section; 5235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::SectionMap; 5335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing mach_o::Segment; 5435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing test_assembler::Endianness; 5535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing test_assembler::Label; 5635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing test_assembler::kBigEndian; 5735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing test_assembler::kLittleEndian; 5835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing test_assembler::kUnsetEndian; 5935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing google_breakpad::ByteBuffer; 6035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing std::map; 6135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing std::string; 6235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing std::vector; 6335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::AllOf; 6435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::DoAll; 6535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::Field; 6635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::InSequence; 6735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::Matcher; 6835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::Return; 6935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::SaveArg; 7035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::Test; 7135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekusing testing::_; 7235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 7335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 7435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Mock classes for the reader's various reporters and handlers. 7535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 7635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass MockFatReaderReporter: public FatReader::Reporter { 7735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 7835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockFatReaderReporter(const string &filename) 7935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : FatReader::Reporter(filename) { } 8035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(BadHeader, void()); 8135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(MisplacedObjectFile, void()); 8235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(TooShort, void()); 8335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 8435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 8535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass MockReaderReporter: public Reader::Reporter { 8635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 8735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockReaderReporter(const string &filename) : Reader::Reporter(filename) { } 8835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(BadHeader, void()); 8935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD4(CPUTypeMismatch, void(cpu_type_t cpu_type, 9035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_subtype_t cpu_subtype, 9135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_type_t expected_cpu_type, 9235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_subtype_t expected_cpu_subtype)); 9335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(HeaderTruncated, void()); 9435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(LoadCommandRegionTruncated, void()); 9535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD3(LoadCommandsOverrun, void(size_t claimed, size_t i, 9635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommandType type)); 9735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD2(LoadCommandTooShort, void(size_t i, LoadCommandType type)); 9835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD1(SectionsMissing, void(const string &name)); 9935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD1(MisplacedSegmentData, void(const string &name)); 10035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD2(MisplacedSectionData, void(const string §ion, 10135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const string &segment)); 10235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD0(MisplacedSymbolTable, void()); 10335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD1(UnsupportedCPUType, void(cpu_type_t cpu_type)); 10435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 10535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 10635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass MockLoadCommandHandler: public Reader::LoadCommandHandler { 10735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 10835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD2(UnknownCommand, bool(LoadCommandType, const ByteBuffer &)); 10935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD1(SegmentCommand, bool(const Segment &)); 11035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD2(SymtabCommand, bool(const ByteBuffer &, const ByteBuffer &)); 11135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 11235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 11335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass MockSectionHandler: public Reader::SectionHandler { 11435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 11535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MOCK_METHOD1(HandleSection, bool(const Section §ion)); 11635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 11735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 11835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 11935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Tests for mach_o::FatReader. 12035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 12135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Since the effect of these functions is to write to stderr, the 12235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// results of these tests must be inspected by hand. 12335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(FatReaderReporter, BadHeader) { 12435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FatReader::Reporter reporter("filename"); 12535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.BadHeader(); 12635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 12735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 12835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(FatReaderReporter, MisplacedObjectFile) { 12935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FatReader::Reporter reporter("filename"); 13035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.MisplacedObjectFile(); 13135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 13235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 13335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(FatReaderReporter, TooShort) { 13435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FatReader::Reporter reporter("filename"); 13535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.TooShort(); 13635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 13735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 13835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, BadHeader) { 13935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 14035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.BadHeader(); 14135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 14235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 14335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, CPUTypeMismatch) { 14435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 14535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, 14635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL); 14735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 14835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 14935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, HeaderTruncated) { 15035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 15135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.HeaderTruncated(); 15235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 15335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 15435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, LoadCommandRegionTruncated) { 15535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 15635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.LoadCommandRegionTruncated(); 15735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 15835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 15935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, LoadCommandsOverrun) { 16035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 16135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.LoadCommandsOverrun(10, 9, LC_DYSYMTAB); 16235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.LoadCommandsOverrun(10, 9, 0); 16335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 16435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 16535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, LoadCommandTooShort) { 16635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 16735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.LoadCommandTooShort(11, LC_SYMTAB); 16835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 16935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 17035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, SectionsMissing) { 17135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 17235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.SectionsMissing("segment name"); 17335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 17435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 17535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, MisplacedSegmentData) { 17635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 17735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.MisplacedSegmentData("segment name"); 17835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 17935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 18035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, MisplacedSectionData) { 18135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 18235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.MisplacedSectionData("section name", "segment name"); 18335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 18435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 18535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, MisplacedSymbolTable) { 18635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 18735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.MisplacedSymbolTable(); 18835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 18935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 19035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST(MachOReaderReporter, UnsupportedCPUType) { 19135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader::Reporter reporter("filename"); 19235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter.UnsupportedCPUType(CPU_TYPE_HPPA); 19335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 19435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 19535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekstruct FatReaderFixture { 19635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FatReaderFixture() 19735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : fat(kBigEndian), 19835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reporter("reporter filename"), 19935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reader(&reporter), object_files(), object_files_size() { 20035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, BadHeader()).Times(0); 20135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, TooShort()).Times(0); 20235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 20335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // here, start, and Mark are file offsets in 'fat'. 20435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.start() = 0; 20535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 20635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Append a 'fat_arch' entry to 'fat', with the given field values. 20735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void AppendFatArch(cpu_type_t type, cpu_subtype_t subtype, 20835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label offset, Label size, uint32_t align) { 20935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 21035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(type) 21135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(subtype) 21235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(offset) 21335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(size) 21435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(align); 21535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 21635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Append |n| dummy 'fat_arch' entries to 'fat'. The cpu type and 21735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // subtype have unrealistic values. 21835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void AppendDummyArchEntries(int n) { 21935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek for (int i = 0; i < n; i++) 22035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0xb68ad617, 0x715a0840, 0, 0, 1); 22135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 22235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void ReadFat(bool expect_parse_success = true) { 22335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(fat.GetContents(&contents)); 22435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat_bytes = reinterpret_cast<const uint8_t *>(contents.data()); 22535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek if (expect_parse_success) { 22635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.Read(fat_bytes, contents.size())); 22735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek object_files = reader.object_files(&object_files_size); 22835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 22935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek else 23035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.Read(fat_bytes, contents.size())); 23135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 23235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek test_assembler::Section fat; 23335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockFatReaderReporter reporter; 23435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FatReader reader; 23535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek string contents; 23635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const uint8_t *fat_bytes; 23735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const struct fat_arch *object_files; 23835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t object_files_size; 23935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 24035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 24135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass FatReaderTest: public FatReaderFixture, public Test { }; 24235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 24335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, BadMagic) { 24435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, BadHeader()).Times(1); 24535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 24635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafed00d) // magic number (incorrect) 24735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(10); // number of architectures 24835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendDummyArchEntries(10); 24935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(false); 25035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 25135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 25235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, HeaderTooShort) { 25335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, TooShort()).Times(1); 25435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 25535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe); // magic number 25635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(false); 25735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 25835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 25935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, ObjectListTooShort) { 26035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, TooShort()).Times(1); 26135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 26235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe) // magic number 26335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(10); // number of architectures 26435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendDummyArchEntries(9); // nine dummy architecture entries... 26535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat // and a tenth, missing a byte at the end 26635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0x3d46c8fc) // cpu type 26735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0x8a7bfb01) // cpu subtype 26835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0) // offset 26935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0) // size 27035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(3, '*'); // one byte short of a four-byte alignment 27135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(false); 27235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 27335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 27435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, DataTooShort) { 27535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedObjectFile()).Times(1); 27635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label arch_data; 27735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 27835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe) // magic number 27935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(1); // number of architectures 28035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0xb4d4a366, 0x4ba4f525, arch_data, 40, 0); 28135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 28235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Mark(&arch_data) // file data begins here 28335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(30, '*'); // only 30 bytes, not 40 as header claims 28435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(false); 28535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 28635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 28735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, NoObjectFiles) { 28835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 28935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe) // magic number 29035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0); // number of architectures 29135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 29235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, object_files_size); 29335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 29435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 29535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, OneObjectFile) { 29635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label obj1_offset; 29735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 29835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe) // magic number 29935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(1); // number of architectures 30035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // First object file list entry 30135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0x5e3a6e91, 0x52ccd852, obj1_offset, 0x42, 0x355b15b2); 30235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // First object file data 30335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 30435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Mark(&obj1_offset) 30535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(0x42, '*'); // dummy contents 30635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 30735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(1U, object_files_size); 30835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x5e3a6e91, object_files[0].cputype); 30935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x52ccd852, object_files[0].cpusubtype); 31035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(obj1_offset.Value(), object_files[0].offset); 31135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x42U, object_files[0].size); 31235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x355b15b2U, object_files[0].align); 31335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 31435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 31535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, ThreeObjectFiles) { 31635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label obj1, obj2, obj3; 31735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 31835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(0xcafebabe) // magic number 31935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .B32(3); // number of architectures 32035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Three object file list entries. 32135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0x0cb92c30, 0x6a159a71, obj1, 0xfb4, 0x2615dbe8); 32235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0x0f3f1cbb, 0x6c55e90f, obj2, 0xc31, 0x83af6ffd); 32335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendFatArch(0x3717276d, 0x10ecdc84, obj3, 0x4b3, 0x035267d7); 32435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 32535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // First object file data 32635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Mark(&obj1) 32735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(0xfb4, '*') // dummy contents 32835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Second object file data 32935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Mark(&obj2) 33035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(0xc31, '%') // dummy contents 33135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Third object file data 33235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Mark(&obj3) 33335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(0x4b3, '^'); // dummy contents 33435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 33535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 33635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 33735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(3U, object_files_size); 33835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 33935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // First object file. 34035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x0cb92c30, object_files[0].cputype); 34135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x6a159a71, object_files[0].cpusubtype); 34235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(obj1.Value(), object_files[0].offset); 34335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xfb4U, object_files[0].size); 34435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x2615dbe8U, object_files[0].align); 34535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 34635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Second object file. 34735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x0f3f1cbb, object_files[1].cputype); 34835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x6c55e90f, object_files[1].cpusubtype); 34935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(obj2.Value(), object_files[1].offset); 35035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xc31U, object_files[1].size); 35135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x83af6ffdU, object_files[1].align); 35235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 35335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Third object file. 35435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x3717276d, object_files[2].cputype); 35535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x10ecdc84, object_files[2].cpusubtype); 35635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(obj3.Value(), object_files[2].offset); 35735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x4b3U, object_files[2].size); 35835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x035267d7U, object_files[2].align); 35935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 36035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 36135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, BigEndianMachO32) { 36235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.set_endianness(kBigEndian); 36335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 36435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedface) // Mach-O file magic number 36535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1a9d0518) // cpu type 36635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1b779357) // cpu subtype 36735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x009df67e) // file type 36835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 36935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // the load commands occupy no bytes 37035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x21987a99); // flags 37135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 37235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 37335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 37435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // FatReader should treat a Mach-O file as if it were a fat binary file 37535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // containing one object file --- the whole thing. 37635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(1U, object_files_size); 37735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x1a9d0518, object_files[0].cputype); 37835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x1b779357, object_files[0].cpusubtype); 37935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, object_files[0].offset); 38035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(contents.size(), object_files[0].size); 38135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 38235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 38335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, BigEndianMachO64) { 38435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.set_endianness(kBigEndian); 38535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 38635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // Mach-O 64-bit file magic number 38735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x5aff8487) // cpu type 38835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x4c6a57f7) // cpu subtype 38935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x4392d2c8) // file type 39035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 39135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // the load commands occupy no bytes 39235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1b033eea); // flags 39335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 39435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 39535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 39635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // FatReader should treat a Mach-O file as if it were a fat binary file 39735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // containing one object file --- the whole thing. 39835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(1U, object_files_size); 39935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x5aff8487, object_files[0].cputype); 40035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype); 40135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, object_files[0].offset); 40235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(contents.size(), object_files[0].size); 40335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 40435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 40535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, LittleEndianMachO32) { 40635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.set_endianness(kLittleEndian); 40735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 40835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedface) // Mach-O file magic number 40935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1a9d0518) // cpu type 41035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1b779357) // cpu subtype 41135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x009df67e) // file type 41235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 41335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // the load commands occupy no bytes 41435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x21987a99); // flags 41535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 41635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 41735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 41835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // FatReader should treat a Mach-O file as if it were a fat binary file 41935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // containing one object file --- the whole thing. 42035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(1U, object_files_size); 42135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x1a9d0518, object_files[0].cputype); 42235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x1b779357, object_files[0].cpusubtype); 42335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, object_files[0].offset); 42435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(contents.size(), object_files[0].size); 42535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 42635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 42735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, LittleEndianMachO64) { 42835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.set_endianness(kLittleEndian); 42935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 43035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // Mach-O 64-bit file magic number 43135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x5aff8487) // cpu type 43235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x4c6a57f7) // cpu subtype 43335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x4392d2c8) // file type 43435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 43535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // the load commands occupy no bytes 43635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x1b033eea); // flags 43735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 43835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(); 43935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 44035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // FatReader should treat a Mach-O file as if it were a fat binary file 44135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // containing one object file --- the whole thing. 44235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_EQ(1U, object_files_size); 44335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x5aff8487, object_files[0].cputype); 44435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x4c6a57f7, object_files[0].cpusubtype); 44535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, object_files[0].offset); 44635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(contents.size(), object_files[0].size); 44735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 44835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 44935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(FatReaderTest, IncompleteMach) { 45035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat.set_endianness(kLittleEndian); 45135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek fat 45235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // Mach-O 64-bit file magic number 45335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x5aff8487); // cpu type 45435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Truncated! 45535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 45635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, TooShort()).WillOnce(Return()); 45735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 45835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFat(false); 45935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 46035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 46135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 46235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// General mach_o::Reader tests. 46335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 46435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Dynamically scoped configuration data. 46535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass WithConfiguration { 46635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 46735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Establish the given parameters as the default for SizedSections 46835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // created within the dynamic scope of this instance. 46935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration(Endianness endianness, size_t word_size) 47035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : endianness_(endianness), word_size_(word_size), saved_(current_) { 47135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek current_ = this; 47235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 47335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ~WithConfiguration() { current_ = saved_; } 47435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek static Endianness endianness() { 47535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(current_); 47635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return current_->endianness_; 47735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 47835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek static size_t word_size() { 47935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(current_); 48035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return current_->word_size_; 48135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 48235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 48335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek private: 48435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The innermost WithConfiguration in whose dynamic scope we are 48535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // currently executing. 48635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek static WithConfiguration *current_; 48735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 48835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The innermost WithConfiguration whose dynamic scope encloses this 48935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // WithConfiguration. 49035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Endianness endianness_; 49135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t word_size_; 49235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration *saved_; 49335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 49435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 49535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekWithConfiguration *WithConfiguration::current_ = NULL; 49635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 49735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A test_assembler::Section with a size that we can cite. The start(), 49835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Here() and Mark() member functions of a SizedSection always represent 49935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// offsets within the overall file. 50035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass SizedSection: public test_assembler::Section { 50135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 50235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Construct a section of the given endianness and word size. 50335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek explicit SizedSection(Endianness endianness, size_t word_size) 50435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : test_assembler::Section(endianness), word_size_(word_size) { 50535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(word_size_ == 32 || word_size_ == 64); 50635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 50735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection() 50835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : test_assembler::Section(WithConfiguration::endianness()), 50935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek word_size_(WithConfiguration::word_size()) { 51035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(word_size_ == 32 || word_size_ == 64); 51135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 51235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 51335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Access/set this section's word size. 51435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t word_size() const { return word_size_; } 51535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void set_word_size(size_t word_size) { 51635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(word_size_ == 32 || word_size_ == 64); 51735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek word_size_ = word_size; 51835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 51935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 52035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a label representing the size this section will have when it 52135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // is Placed in some containing section. 52235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label final_size() const { return final_size_; } 52335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 52435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Append SECTION to the end of this section, and call its Finish member. 52535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a reference to this section. 52635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection &Place(SizedSection *section) { 52735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(section->endianness() == endianness()); 52835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section->Finish(); 52935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section->start() = Here(); 53035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek test_assembler::Section::Append(*section); 53135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 53235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 53335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 53435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek protected: 53535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Mark this section's contents as complete. For plain SizedSections, we 53635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // set SECTION's start to its position in this section, and its final_size 53735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // label to its current size. Derived classes can extend this as needed 53835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // for their additional semantics. 53935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek virtual void Finish() { 54035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek final_size_ = Size(); 54135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 54235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 54335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The word size for this data: either 32 or 64. 54435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t word_size_; 54535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 54635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek private: 54735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // This section's final size, set when we are placed in some other 54835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // SizedSection. 54935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label final_size_; 55035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 55135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 55235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A SizedSection that is loaded into memory at a particular address. 55335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass LoadedSection: public SizedSection { 55435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 55535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek explicit LoadedSection(Label address = Label()) : address_(address) { } 55635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 55735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a label representing this section's address. 55835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label address() const { return address_; } 55935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 56035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Placing a loaded section within a loaded section sets the relationship 56135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // between their addresses. 56235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection &Place(LoadedSection *section) { 56335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section->address() = address() + Size(); 56435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection::Place(section); 56535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 56635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 56735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 56835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek protected: 56935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The address at which this section's contents will be loaded. 57035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label address_; 57135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 57235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 57335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A SizedSection representing a segment load command. 57435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass SegmentLoadCommand: public SizedSection { 57535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 57635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand() : section_count_(0) { } 57735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 57835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Append a segment load command header with the given characteristics. 57935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The load command will refer to CONTENTS, which must be Placed in the 58035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // file separately, at the desired position. Return a reference to this 58135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // section. 58235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand &Header(const string &name, const LoadedSection &contents, 58335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek uint32_t maxprot, uint32_t initprot, 58435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek uint32_t flags) { 58535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek assert(contents.word_size() == word_size()); 58635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(word_size() == 32 ? LC_SEGMENT : LC_SEGMENT_64); 58735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(final_size()); 58835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendCString(name, 16); 58935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, contents.address()); 59035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, vmsize_); 59135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, contents.start()); 59235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, contents.final_size()); 59335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(maxprot); 59435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(initprot); 59535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(final_section_count_); 59635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(flags); 59735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 59835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek content_final_size_ = contents.final_size(); 59935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 60035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 60135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 60235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 60335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a label representing the size of this segment when loaded into 60435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // memory. If this label is still undefined by the time we place this 60535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // segment, it defaults to the final size of the segment's in-file 60635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // contents. Return a reference to this load command. 60735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label &vmsize() { return vmsize_; } 60835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 60935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Add a section entry with the given characteristics to this segment 61035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // load command. Return a reference to this. The section entry will refer 61135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // to CONTENTS, which must be Placed in the segment's contents 61235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // separately, at the desired position. 61335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand &AppendSectionEntry(const string §ion_name, 61435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const string &segment_name, 61535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek uint32_t alignment, uint32_t flags, 61635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const LoadedSection &contents) { 61735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendCString(section_name, 16); 61835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendCString(segment_name, 16); 61935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, contents.address()); 62035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size() / 8, contents.final_size()); 62135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(contents.start()); 62235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(alignment); 62335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0); // relocations start 62435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0); // relocations size 62535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(flags); 62635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0x93656b95); // reserved1 62735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0xc35a2473); // reserved2 62835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek if (word_size() == 64) 62935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0x70284b95); // reserved3 63035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 63135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section_count_++; 63235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 63335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 63435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 63535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 63635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek protected: 63735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void Finish() { 63835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek final_section_count_ = section_count_; 63935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek if (!vmsize_.IsKnownConstant()) 64035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek vmsize_ = content_final_size_; 64135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection::Finish(); 64235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 64335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 64435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek private: 64535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The number of sections that have been added to this segment so far. 64635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t section_count_; 64735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 64835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A label representing the final number of sections this segment will hold. 64935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label final_section_count_; 65035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 65135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The size of the contents for this segment present in the file. 65235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label content_final_size_; 65335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 65435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A label representing the size of this segment when loaded; this can be 65535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // larger than the size of its file contents, the difference being 65635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // zero-filled. If not set explicitly by calling set_vmsize, this is set 65735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // equal to the size of the contents. 65835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label vmsize_; 65935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 66035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 66135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A SizedSection holding a list of Mach-O load commands. 66235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass LoadCommands: public SizedSection { 66335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 66435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands() : command_count_(0) { } 66535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 66635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a label representing the final load command count. 66735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label final_command_count() const { return final_command_count_; } 66835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 66935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Increment the command count; return a reference to this section. 67035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands &CountCommand() { 67135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command_count_++; 67235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 67335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 67435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 67535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Place COMMAND, containing a load command, at the end of this section. 67635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a reference to this section. 67735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands &Place(SizedSection *section) { 67835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection::Place(section); 67935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek CountCommand(); 68035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 68135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 68235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 68335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek protected: 68435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Mark this load command list as complete. 68535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void Finish() { 68635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection::Finish(); 68735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek final_command_count_ = command_count_; 68835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 68935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 69035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek private: 69135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The number of load commands we have added to this file so far. 69235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t command_count_; 69335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 69435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A label representing the final command count. 69535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label final_command_count_; 69635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 69735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 69835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A SizedSection holding the contents of a Mach-O file. Within a 69935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// MachOFile, the start, Here, and Mark members refer to file offsets. 70035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass MachOFile: public SizedSection { 70135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 70235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile() { 70335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek start() = 0; 70435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 70535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 70635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create a Mach-O file header using the given characteristics and load 70735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // command list. This Places COMMANDS immediately after the header. 70835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Return a reference to this section. 70935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile &Header(LoadCommands *commands, 71035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_type_t cpu_type = CPU_TYPE_X86, 71135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_subtype_t cpu_subtype = CPU_SUBTYPE_I386_ALL, 71235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FileType file_type = MH_EXECUTE, 71335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek uint32_t file_flags = (MH_TWOLEVEL | 71435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_DYLDLINK | 71535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_NOUNDEFS)) { 71635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(word_size() == 32 ? 0xfeedface : 0xfeedfacf); // magic number 71735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(cpu_type); // cpu type 71835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(cpu_subtype); // cpu subtype 71935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(file_type); // file type 72035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(commands->final_command_count()); // number of load commands 72135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(commands->final_size()); // their size in bytes 72235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(file_flags); // flags 72335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek if (word_size() == 64) 72435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(0x55638b90); // reserved 72535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Place(commands); 72635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 72735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 72835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 72935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 73035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 73135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekstruct ReaderFixture { 73235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReaderFixture() 73335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : reporter("reporter filename"), 73435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reader(&reporter) { 73535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, BadHeader()).Times(0); 73635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, CPUTypeMismatch(_, _, _, _)).Times(0); 73735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, HeaderTruncated()).Times(0); 73835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandRegionTruncated()).Times(0); 73935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandsOverrun(_, _, _)).Times(0); 74035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandTooShort(_, _)).Times(0); 74135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, SectionsMissing(_)).Times(0); 74235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSegmentData(_)).Times(0); 74335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSectionData(_, _)).Times(0); 74435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(0); 74535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, UnsupportedCPUType(_)).Times(0); 74635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 74735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, UnknownCommand(_, _)).Times(0); 74835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)).Times(0); 74935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 75035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 75135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek void ReadFile(MachOFile *file, 75235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek bool expect_parse_success, 75335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_type_t expected_cpu_type, 75435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cpu_subtype_t expected_cpu_subtype) { 75535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(file->GetContents(&file_contents)); 75635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file_bytes = reinterpret_cast<const uint8_t *>(file_contents.data()); 75735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek if (expect_parse_success) { 75835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.Read(file_bytes, 75935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file_contents.size(), 76035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected_cpu_type, 76135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected_cpu_subtype)); 76235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } else { 76335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.Read(file_bytes, 76435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file_contents.size(), 76535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected_cpu_type, 76635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected_cpu_subtype)); 76735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 76835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 76935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 77035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek string file_contents; 77135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const uint8_t *file_bytes; 77235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockReaderReporter reporter; 77335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Reader reader; 77435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockLoadCommandHandler load_command_handler; 77535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MockSectionHandler section_handler; 77635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 77735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 77835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass ReaderTest: public ReaderFixture, public Test { }; 77935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 78035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, BadMagic) { 78135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 78235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 78335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 78435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 78535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 78635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x67bdebe1) // Not a proper magic number. 78735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 78835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 78935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 79035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 79135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 79235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 79335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 79435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, BadHeader()).WillOnce(Return()); 79535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); 79635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 79735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 79835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, MismatchedMagic) { 79935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 80035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = CPU_TYPE_I386; 80135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL; 80235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 80335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 80435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(MH_CIGAM) // Right magic, but winds up wrong 80535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // due to bitswapping 80635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 80735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 80835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 80935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 81035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 81135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 81235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 81335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, BadHeader()).WillOnce(Return()); 81435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, kCPUType, kCPUSubType); 81535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 81635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 81735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, ShortMagic) { 81835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 81935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 82035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 82135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D16(0xfeed); // magic number 82235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // truncated! 82335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return()); 82435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, CPU_TYPE_ANY, 0); 82535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 82635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 82735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, ShortHeader) { 82835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 82935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = CPU_TYPE_ANY; 83035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 83135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 83235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 83335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedface) // magic number 83435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 83535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 83635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 83735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 83835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // they occupy no bytes 83935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, HeaderTruncated()).WillOnce(Return()); 84035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); 84135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 84235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 84335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, MismatchedCPU) { 84435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 84535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = CPU_TYPE_I386; 84635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = CPU_SUBTYPE_X86_ALL; 84735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 84835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 84935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(MH_MAGIC) // Right magic for PPC (once bitswapped) 85035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 85135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 85235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 85335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 85435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 85535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 85635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 85735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, 85835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek CPUTypeMismatch(CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL, 85935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL)) 86035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 86135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL); 86235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 86335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 86435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, LittleEndian32Bit) { 86535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 86635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 86735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 86835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 86935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 87035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedface) // magic number 87135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 87235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 87335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 87435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 87535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 87635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 87735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 87835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); 87935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.bits_64()); 88035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.big_endian()); 88135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUType, reader.cpu_type()); 88235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); 88335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileType(0x149fc717), reader.file_type()); 88435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); 88535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 88635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 88735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, LittleEndian64Bit) { 88835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 88935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 89035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 89135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 89235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 89335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // magic number 89435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 89535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 89635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 89735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 89835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 89935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 90035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 90135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); 90235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.bits_64()); 90335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.big_endian()); 90435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUType, reader.cpu_type()); 90535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); 90635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileType(0x149fc717), reader.file_type()); 90735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); 90835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 90935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 91035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, BigEndian32Bit) { 91135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 91235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 91335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 91435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 91535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 91635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedface) // magic number 91735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 91835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 91935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 92035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 92135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 92235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 92335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 92435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); 92535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.bits_64()); 92635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.big_endian()); 92735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUType, reader.cpu_type()); 92835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); 92935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileType(0x149fc717), reader.file_type()); 93035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); 93135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 93235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 93335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(ReaderTest, BigEndian64Bit) { 93435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 93535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 93635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 93735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 93835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 93935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // magic number 94035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 94135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 94235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 94335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no load commands 94435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // they occupy no bytes 94535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 94635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0); // reserved 94735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, kCPUSubType); 94835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.bits_64()); 94935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.big_endian()); 95035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUType, reader.cpu_type()); 95135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(kCPUSubType, reader.cpu_subtype()); 95235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileType(0x149fc717), reader.file_type()); 95335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(0x80e71d64), reader.flags()); 95435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 95535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 95635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 95735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Load command tests. 95835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 95935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass LoadCommand: public ReaderFixture, public Test { }; 96035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 96135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, RegionTruncated) { 96235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 96335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_type_t kCPUType = 0x46b760df; 96435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek const cpu_subtype_t kCPUSubType = 0x76a0e7f7; 96535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 96635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 96735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xfeedfacf) // magic number 96835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUType) // cpu type 96935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(kCPUSubType) // cpu subtype 97035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x149fc717) // file type 97135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(1) // one load command 97235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(40) // occupying 40 bytes 97335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x80e71d64) // flags 97435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // reserved 97535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(20, 0); // load command region, not as long as 97635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Mach-O header promised 97735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 97835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandRegionTruncated()).WillOnce(Return()); 97935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 98035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, false, CPU_TYPE_ANY, kCPUSubType); 98135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 98235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 98335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, None) { 98435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 98535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 98635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 98735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 98835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 98935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_X86, CPU_SUBTYPE_I386_ALL); 99035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 99135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.bits_64()); 99235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.big_endian()); 99335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(CPU_TYPE_X86, reader.cpu_type()); 99435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype()); 9954ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach EXPECT_EQ(static_cast<uint32_t>(MH_EXECUTE), reader.file_type()); 99635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(MH_TWOLEVEL | 99735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_DYLDLINK | 99835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_NOUNDEFS), 99935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek FileFlags(reader.flags())); 100035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 100135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 100235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 100335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 100435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, Unknown) { 100535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 100635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 100735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands 100835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .CountCommand() 100935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x33293d4a) // unknown load command 101035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(40) // total size in bytes 101135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(32, '*'); // dummy data 101235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 101335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 101435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 101535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 101635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 101735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.bits_64()); 101835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.big_endian()); 101935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(CPU_TYPE_X86, reader.cpu_type()); 102035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(CPU_SUBTYPE_I386_ALL, reader.cpu_subtype()); 10214ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach EXPECT_EQ(static_cast<uint32_t>(MH_EXECUTE), reader.file_type()); 102235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(FileFlags(MH_TWOLEVEL | 102335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_DYLDLINK | 102435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MH_NOUNDEFS), 102535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek reader.flags()); 102635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 102735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer expected; 102835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected.start = file_bytes + load_commands.start().Value(); 102935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected.end = expected.start + load_commands.final_size().Value(); 103035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, UnknownCommand(0x33293d4a, 103135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek expected)) 103235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 103335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 103435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 103535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 103635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 103735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, TypeIncomplete) { 103835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 103935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 104035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands 104135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .CountCommand() 104235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(3, 0); // load command type, incomplete 104335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 104435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 104535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 104635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 104735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 104835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 104935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, 0)) 105035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 105135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 105235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 105335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 105435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, LengthIncomplete) { 105535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 105635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 105735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands 105835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .CountCommand() 105935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SEGMENT); // load command 106035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // no length 106135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 106235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 106335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 106435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 106535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 106635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT)) 106735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 106835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 106935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 107035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 107135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, ContentIncomplete) { 107235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 107335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 107435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands 107535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .CountCommand() 107635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SEGMENT) // load command 107735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(40) // total size in bytes 107835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(28, '*'); // not enough dummy data 107935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 108035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 108135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 108235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 108335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 108435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandsOverrun(1, 0, LC_SEGMENT)) 108535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 108635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 108735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 108835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 108935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentBE32) { 109035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 109135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 109235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x1891139c; 109335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(42, '*'); // segment contents 109435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 109535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 109635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("froon", segment, 0x94d6dd22, 0x8bdbc319, 0x990a16dd); 109735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command.vmsize() = 0xcb76584fU; 109835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 109935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&segment_command); 110035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 110135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 110235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header(&load_commands) 110335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Place(&segment); 110435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 110535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 110635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 110735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 110835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)) 110935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&actual_segment), 111035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 111135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 111235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 111335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(false, actual_segment.bits_64); 111435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("froon", actual_segment.name); 111535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x1891139cU, actual_segment.vmaddr); 111635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xcb76584fU, actual_segment.vmsize); 111735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x94d6dd22U, actual_segment.maxprot); 111835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x8bdbc319U, actual_segment.initprot); 111935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x990a16ddU, actual_segment.flags); 112035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.nsects); 112135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.section_list.Size()); 112235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); 112335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 112435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 112535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentLE32) { 112635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 112735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 112835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x4b877866; 112935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(42, '*'); // segment contents 113035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 113135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 113235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("sixteenprecisely", segment, 113335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x350759ed, 0x6cf5a62e, 0x990a16dd); 113435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command.vmsize() = 0xcb76584fU; 113535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 113635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&segment_command); 113735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 113835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 113935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header(&load_commands) 114035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Place(&segment); 114135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 114235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 114335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 114435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 114535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)) 114635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&actual_segment), 114735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 114835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 114935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 115035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(false, actual_segment.bits_64); 115135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("sixteenprecisely", actual_segment.name); 115235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x4b877866U, actual_segment.vmaddr); 115335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xcb76584fU, actual_segment.vmsize); 115435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x350759edU, actual_segment.maxprot); 115535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x6cf5a62eU, actual_segment.initprot); 115635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x990a16ddU, actual_segment.flags); 115735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.nsects); 115835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.section_list.Size()); 115935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); 116035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 116135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 116235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentBE64) { 116335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 116435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 116535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x79f484f77009e511ULL; 116635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(42, '*'); // segment contents 116735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 116835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 116935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("froon", segment, 0x42b45da5, 0x8bdbc319, 0xb2335220); 117035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command.vmsize() = 0x8d92397ce6248abaULL; 117135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 117235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&segment_command); 117335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 117435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 117535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header(&load_commands) 117635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Place(&segment); 117735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 117835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 117935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 118035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 118135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)) 118235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&actual_segment), 118335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 118435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 118535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 118635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(true, actual_segment.bits_64); 118735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("froon", actual_segment.name); 118835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x79f484f77009e511ULL, actual_segment.vmaddr); 118935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x8d92397ce6248abaULL, actual_segment.vmsize); 119035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x42b45da5U, actual_segment.maxprot); 119135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x8bdbc319U, actual_segment.initprot); 119235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xb2335220U, actual_segment.flags); 119335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.nsects); 119435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.section_list.Size()); 119535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); 119635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 119735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 119835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentLE64) { 119935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 120035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 120135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x50c0501dc5922d35ULL; 120235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(42, '*'); // segment contents 120335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 120435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 120535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("sixteenprecisely", segment, 120635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x917c339d, 0xdbc446fa, 0xb650b563); 120735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command.vmsize() = 0x84ae73e7c75469bfULL; 120835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 120935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&segment_command); 121035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 121135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 121235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header(&load_commands) 121335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Place(&segment); 121435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 121535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 121635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 121735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 121835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)) 121935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&actual_segment), 122035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 122135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 122235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 122335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(true, actual_segment.bits_64); 122435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("sixteenprecisely", actual_segment.name); 122535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x50c0501dc5922d35ULL, actual_segment.vmaddr); 122635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x84ae73e7c75469bfULL, actual_segment.vmsize); 122735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0x917c339dU, actual_segment.maxprot); 122835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xdbc446faU, actual_segment.initprot); 122935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xb650b563U, actual_segment.flags); 123035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.nsects); 123135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0U, actual_segment.section_list.Size()); 123235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(segment.final_size().Value(), actual_segment.contents.Size()); 123335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 123435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 123535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentCommandTruncated) { 123635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 123735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment_contents; 123835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_contents.Append(20, '*'); // lah di dah 123935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection command; 124035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command 124135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SEGMENT) // command type 124235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(command.final_size()) // command size 124335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendCString("too-short", 16) // segment name 124435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x9c759211) // vmaddr 124535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(segment_contents.final_size()) // vmsize 124635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(segment_contents.start()) // file offset 124735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(segment_contents.final_size()) // file size 124835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0x56f28446) // max protection 124935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0xe7910dcb) // initial protection 125035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(0) // no sections 125135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Append(3, 0); // flags (one byte short!) 125235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 125335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&command); 125435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 125535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file 125635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header(&load_commands) 125735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Place(&segment_contents); 125835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 125935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 126035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 126135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, LoadCommandTooShort(0, LC_SEGMENT)) 126235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 126335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 126435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 126535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 126635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 126735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, SegmentBadContentOffset) { 126835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 126935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Instead of letting a Place call set the segment's file offset and size, 127035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // set them ourselves, to check that the parser catches invalid offsets 127135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // instead of handing us bogus pointers. 127235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 127335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x4db5489c; 127435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.start() = 0x7e189e76; // beyond end of file 127535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.final_size() = 0x98b9c3ab; 127635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 127735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 127835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("notmerelyfifteen", segment, 0xcbab25ee, 0x359a20db, 0x68a3933f); 127935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 128035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&segment_command); 128135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 128235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands); 128335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 128435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 128535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 128635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSegmentData("notmerelyfifteen")) 128735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 128835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 128935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 129035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 129135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 129235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, ThreeLoadCommands) { 129335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 129435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection seg1, seg2, seg3; 129535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand cmd1, cmd2, cmd3; 129635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 129735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg1.Append(128, '@'); 129835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg1.address() = 0xa7f61ef6; 129935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd1.Header("head", seg1, 0x88bf1cc7, 0x889a26a4, 0xe9b80d87); 130035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Include some dummy data at the end of the load command. Since we 130135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // didn't claim to have any sections, the reader should ignore this. But 130235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // making sure the commands have different lengths ensures that we're 130335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // using the right command's length to advance the LoadCommandIterator. 130435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd1.Append(128, '!'); 130535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 130635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg2.Append(42, '*'); 130735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg2.address() = 0xc70fc909; 130835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd2.Header("thorax", seg2, 0xde7327f4, 0xfdaf771d, 0x65e74b30); 130935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // More dummy data at the end of the load command. 131035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd2.Append(32, '^'); 131135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 131235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg3.Append(42, '%'); 131335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek seg3.address() = 0x46b3ab05; 131435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd3.Header("abdomen", seg3, 0x7098b70d, 0x8d8d7728, 0x5131419b); 131535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // More dummy data at the end of the load command. 131635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd3.Append(64, '&'); 131735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 131835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 131935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&cmd1).Place(&cmd2).Place(&cmd3); 132035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 132135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 132235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands).Place(&seg1).Place(&seg2).Place(&seg3); 132335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 132435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 132535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 132635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek { 132735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek InSequence s; 132835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, 132935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentCommand(Field(&Segment::name, "head"))) 133035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 133135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, 133235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentCommand(Field(&Segment::name, "thorax"))) 133335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 133435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, 133535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentCommand(Field(&Segment::name, "abdomen"))) 133635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 133735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 133835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 133935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 134035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 134135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 134235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekstatic inline Matcher<const Section &> MatchSection( 134335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<bool> bits_64, 134435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<const string &> section_name, 134535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<const string &> segment_name, 134635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<uint64_t> address, 134735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<uint32_t> alignment, 134835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<uint32_t> flags, 134935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<const ByteBuffer &> contents) { 135035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return AllOf(AllOf(Field(&Section::bits_64, bits_64), 135135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::section_name, section_name), 135235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::segment_name, segment_name), 135335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::address, address)), 135435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AllOf(Field(&Section::align, alignment), 135535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::flags, flags), 135635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::contents, contents))); 135735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 135835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 135935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekstatic inline Matcher<const Section &> MatchSection( 136035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<bool> bits_64, 136135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<const string &> section_name, 136235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<const string &> segment_name, 136335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Matcher<uint64_t> address) { 136435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return AllOf(Field(&Section::bits_64, bits_64), 136535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::section_name, section_name), 136635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::segment_name, segment_name), 136735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Field(&Section::address, address)); 136835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 136935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 137035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, OneSegmentTwoSections) { 137135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 137235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 137335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create some sections with some data. 137435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection section1, section2; 137535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section1.Append("buddha's hand"); 137635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section2.Append("kumquat"); 137735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 137835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create a segment to hold them. 137935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 138035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0xe1d0eeec; 138135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Place(§ion2).Place(§ion1); 138235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 138335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command; 138435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command 138535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("head", segment, 0x92c9568c, 0xa89f2627, 0x4dc7a1e2) 138635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("mandarin", "kishu", 12, 0x8cd4604bU, section1) 138735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("bergamot", "cara cara", 12, 0x98746efaU, section2); 138835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 138935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 139035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&segment_command); 139135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 139235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 139335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment); 139435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 139535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 139635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 139735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 139835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SegmentCommand(_)) 139935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&actual_segment), 140035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 140135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 140235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 140335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek { 140435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek InSequence s; 140535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer contents1; 140635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents1.start = file_bytes + section1.start().Value(); 140735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents1.end = contents1.start + section1.final_size().Value(); 140835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("buddha's hand", 140935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek string(reinterpret_cast<const char *>(contents1.start), 141035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents1.Size())); 141135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(section_handler, 141235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek HandleSection(MatchSection(true, "mandarin", "kishu", 141335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section1.address().Value(), 12, 141435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x8cd4604bU, contents1))) 141535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 141635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 141735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer contents2; 141835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents2.start = file_bytes + section2.start().Value(); 141935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents2.end = contents2.start + section2.final_size().Value(); 142035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ("kumquat", 142135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek string(reinterpret_cast<const char *>(contents2.start), 142235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek contents2.Size())); 142335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(section_handler, 142435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek HandleSection(MatchSection(true, "bergamot", "cara cara", 142535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section2.address().Value(), 12, 142635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x98746efaU, contents2))) 142735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 142835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 142935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 143035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, §ion_handler)); 143135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 143235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 143335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, MisplacedSectionBefore) { 143435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 143535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 143635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The segment. 143735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 143835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x696d83cc; 143935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(10, '0'); 144035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 144135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The contents of the following sections don't matter, because 144235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // we're not really going to Place them in segment; we're just going 144335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // to set all their labels by hand to get the (impossible) 144435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // configurations we want. 144535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 144635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A section whose starting offset is before that of its section. 144735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection before; 144835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek before.Append(10, '1'); 144935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek before.start() = segment.start() - 1; 145035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek before.address() = segment.address() - 1; 145135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek before.final_size() = before.Size(); 145235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 145335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand command; 145435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command 145535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) 145635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("before", "segment", 0, 0x686c6921, before); 145735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 145835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 145935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&command); 146035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 146135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 146235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment); 146335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 146435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 146535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 146635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 146735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); 146835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 146935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSectionData("before", "segment")) 147035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 147135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); 147235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 147335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 147435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, MisplacedSectionAfter) { 147535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 147635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 147735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The segment. 147835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 147935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x696d83cc; 148035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(10, '0'); 148135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 148235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The contents of the following sections don't matter, because 148335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // we're not really going to Place them in segment; we're just going 148435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // to set all their labels by hand to get the (impossible) 148535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // configurations we want. 148635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 148735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A section whose starting offset is after the end of its section. 148835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection after; 148935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek after.Append(10, '2'); 149035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek after.start() = segment.start() + 11; 149135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek after.address() = segment.address() + 11; 149235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek after.final_size() = after.Size(); 149335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 149435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand command; 149535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command 149635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) 149735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("after", "segment", 0, 0x2ee50124, after); 149835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 149935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 150035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&command); 150135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 150235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 150335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment); 150435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 150535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 150635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 150735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 150835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); 150935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 151035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSectionData("after", "segment")) 151135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 151235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); 151335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 151435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 151535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, MisplacedSectionTooBig) { 151635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 64); 151735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 151835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The segment. 151935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 152035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x696d83cc; 152135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.Append(10, '0'); 152235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 152335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The contents of the following sections don't matter, because 152435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // we're not really going to Place them in segment; we're just going 152535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // to set all their labels by hand to get the (impossible) 152635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // configurations we want. 152735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 152835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // A section that extends beyond the end of its section. 152935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection too_big; 153035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek too_big.Append(10, '3'); 153135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek too_big.start() = segment.start() + 1; 153235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek too_big.address() = segment.address() + 1; 153335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek too_big.final_size() = too_big.Size(); 153435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 153535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand command; 153635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command 153735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("segment", segment, 0x173baa29, 0x8407275d, 0xed8f7057) 153835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("too big", "segment", 0, 0x8b53ae5c, too_big); 153935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 154035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 154135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&command); 154235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 154335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 154435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment); 154535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 154635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 154735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 154835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 154935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.FindSegment("segment", &actual_segment)); 155035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 155135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSectionData("too big", "segment")) 155235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return()); 155335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkSegmentSections(actual_segment, §ion_handler)); 155435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 155535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 155635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 155735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// The segments in a .dSYM bundle's Mach-O file have their file offset 155835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// and size set to zero, but the sections don't. The reader shouldn't 155935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// report an error in this case. 156035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, ZappedSegment) { 156135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 156235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 156335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The segment. 156435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment; 156535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.address() = 0x696d83cc; 156635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.start() = 0; 156735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment.final_size() = 0; 156835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 156935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The section. 157035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection section; 157135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section.address() = segment.address(); 157235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section.start() = 0; 157335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section.final_size() = 1000; // extends beyond its segment 157435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 157535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand command; 157635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek command 157735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("zapped", segment, 0x0861a5cb, 0x68ccff67, 0x0b66255c) 157835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("twitching", "zapped", 0, 0x93b3bd42, section); 157935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 158035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 158135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&command); 158235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 158335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 158435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands); 158535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 158635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 158735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 158835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 158935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.FindSegment("zapped", &actual_segment)); 159035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 159135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer zapped_extent(NULL, 0); 159235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(section_handler, 159335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek HandleSection(MatchSection(false, "twitching", "zapped", 159435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x696d83cc, 0, 0x93b3bd42, 159535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek zapped_extent))) 159635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(Return(true)); 159735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 159835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkSegmentSections(actual_segment, §ion_handler)); 159935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 160035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 160135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, MapSegmentSections) { 160235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 160335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 160435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create some sections with some data. 160535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection section1, section2, section3, section4; 160635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section1.Append("buddha's hand"); 160735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section2.start() = 0; // Section 2 is an S_ZEROFILL section. 160835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section2.final_size() = 0; 160935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section3.Append("shasta gold"); 161035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section4.Append("satsuma"); 161135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 161235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create two segments to hold them. 161335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment1, segment2; 161435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment1.address() = 0x13e6c8a9; 161535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment1.Place(§ion3).Place(§ion1); 161635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment2.set_word_size(64); 161735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment2.address() = 0x04d462e2; 161835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment2.Place(§ion4); 161935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek section2.address() = segment2.address() + segment2.Size(); 162035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 162135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand segment_command1, segment_command2; 162235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command1 162335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("head", segment1, 0x67d955a6, 0x7a61c13e, 0xe3e50c64) 162435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("mandarin", "head", 12, 0x5bb565d7, section1) 162535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("bergamot", "head", 12, 0x8620de73, section3); 162635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command2.set_word_size(64); 162735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment_command2 162835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Header("thorax", segment2, 0x7aab2419, 0xe908007f, 0x17961d33) 162935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("sixteenprecisely", "thorax", 163035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 12, S_ZEROFILL, section2) 163135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .AppendSectionEntry("cara cara", "thorax", 12, 0xb6c5dd8a, section4); 163235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 163335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 163435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&segment_command1).Place(&segment_command2); 163535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 163635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 163735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment1).Place(&segment2); 163835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 163935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 164035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 164135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment segment; 164235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SectionMap section_map; 164335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 164435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.FindSegment("smoot", &segment)); 164535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 164635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(reader.FindSegment("thorax", &segment)); 164735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(reader.MapSegmentSections(segment, §ion_map)); 164835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 164935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(section_map.find("sixteenpreciselyandthensome") 165035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek != section_map.end()); 165135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(section_map.find("mandarin") != section_map.end()); 165235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(section_map.find("cara cara") != section_map.end()); 165335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_THAT(section_map["cara cara"], 165435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MatchSection(true, "cara cara", "thorax", 0x04d462e2)); 165535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(section_map.find("sixteenprecisely") 165635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek != section_map.end()); 165735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer sixteenprecisely_contents(NULL, 0); 165835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_THAT(section_map["sixteenprecisely"], 165935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MatchSection(true, "sixteenprecisely", "thorax", 166035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 0x04d462e2 + 7, 12, S_ZEROFILL, 166135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek sixteenprecisely_contents)); 166235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 166335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(reader.FindSegment("head", &segment)); 166435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(reader.MapSegmentSections(segment, §ion_map)); 166535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 166635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(section_map.find("mandarin") != section_map.end()); 166735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_THAT(section_map["mandarin"], 166835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MatchSection(false, "mandarin", "head", 0x13e6c8a9 + 11)); 166935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ASSERT_TRUE(section_map.find("bergamot") != section_map.end()); 167035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_THAT(section_map["bergamot"], 167135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MatchSection(false, "bergamot", "head", 0x13e6c8a9)); 167235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 167335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 167435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(LoadCommand, FindSegment) { 167535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 167635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 167735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadedSection segment1, segment2, segment3; 167835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment1.address() = 0xb8ae5752; 167935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment1.Append("Some contents!"); 168035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment2.address() = 0xd6b0ce83; 168135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment2.Append("Different stuff."); 168235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment3.address() = 0x7374fd2a; 168335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek segment3.Append("Further materials."); 168435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 168535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SegmentLoadCommand cmd1, cmd2, cmd3; 168635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd1.Header("first", segment1, 0xfadb6932, 0x175bf529, 0x0de790ad); 168735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd2.Header("second", segment2, 0xeef716e0, 0xe103a9d7, 0x7d38a8ef); 168835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek cmd3.Header("third", segment3, 0xe172b39e, 0x86012f07, 0x080ac94d); 168935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 169035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands commands; 169135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek commands.Place(&cmd1).Place(&cmd2).Place(&cmd3); 169235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 169335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 169435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&commands).Place(&segment1).Place(&segment2).Place(&segment3); 169535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 169635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 169735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 169835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Segment actual_segment; 169935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 170035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.FindSegment("murphy", &actual_segment)); 170135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 170235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.FindSegment("second", &actual_segment)); 170335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(0xd6b0ce83, actual_segment.vmaddr); 170435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 170535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 170635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 170735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// Symtab tests. 170835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 170935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A StringAssembler is a class for generating .stabstr sections to present 171035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// as input to the STABS parser. 171135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass StringAssembler: public SizedSection { 171235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 171335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Add the string S to this StringAssembler, and return the string's 171435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // offset within this compilation unit's strings. 171535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t Add(const string &s) { 171635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t offset = Size(); 171735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek AppendCString(s); 171835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return offset; 171935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 172035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 172135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 172235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// A SymbolAssembler is a class for generating .stab sections to present as 172335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek// test input for the STABS parser. 172435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass SymbolAssembler: public SizedSection { 172535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek public: 172635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Create a SymbolAssembler that uses StringAssembler for its strings. 172735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek explicit SymbolAssembler(StringAssembler *string_assembler) 172835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek : string_assembler_(string_assembler), 172935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek entry_count_(0) { } 173035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 173135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Append a STAB entry to the end of this section with the given 173235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // characteristics. NAME is the offset of this entry's name string within 173335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // its compilation unit's portion of the .stabstr section; this can be a 173435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // value generated by a StringAssembler. Return a reference to this 173535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // SymbolAssembler. 173635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor, 173735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label value, Label name) { 173835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D32(name); 173935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D8(type); 174035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D8(other); 174135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek D16(descriptor); 174235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Append(endianness(), word_size_ / 8, value); 174335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek entry_count_++; 174435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return *this; 174535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 174635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 174735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // As above, but automatically add NAME to our StringAssembler. 174835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler &Symbol(uint8_t type, uint8_t other, Label descriptor, 174935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Label value, const string &name) { 175035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek return Symbol(type, other, descriptor, value, string_assembler_->Add(name)); 175135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek } 175235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 175335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek private: 175435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The strings for our STABS entries. 175535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek StringAssembler *string_assembler_; 175635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 175735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // The number of entries in this compilation unit so far. 175835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek size_t entry_count_; 175935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek}; 176035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 176135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekclass Symtab: public ReaderFixture, public Test { }; 176235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 176335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(Symtab, Symtab32) { 176435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 176535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 176635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek StringAssembler strings; 176735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler symbols(&strings); 176835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symbols 176935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0x52, 0x7c, 0x3470, 0x9bb02e7c, "hrududu") 177035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0x50, 0x90, 0x7520, 0x1122525d, "Frith"); 177135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 177235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection symtab_command; 177335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symtab_command 177435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SYMTAB) // command 177535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symtab_command.final_size()) // size 177635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symbols.start()) // file offset of symbols 177735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(2) // symbol count 177835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.start()) // file offset of strings 177935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.final_size()); // strings size 178035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 178135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 178235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&symtab_command); 178335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 178435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 178535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands).Place(&symbols).Place(&strings); 178635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 178735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 178835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 178935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer symbols_found, strings_found; 179035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SymtabCommand(_, _)) 179135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&symbols_found), 179235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SaveArg<1>(&strings_found), 179335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 179435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 179535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 179635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(24U, symbols_found.Size()); 179735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(14U, strings_found.Size()); 179835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 179935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 180035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(Symtab, Symtab64) { 180135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 64); 180235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 180335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek StringAssembler strings; 180435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler symbols(&strings); 180535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symbols 180635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") 180735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); 180835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 180935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection symtab_command; 181035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symtab_command 181135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SYMTAB) // command 181235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symtab_command.final_size()) // size 181335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symbols.start()) // file offset of symbols 181435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(2) // symbol count 181535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.start()) // file offset of strings 181635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.final_size()); // strings size 181735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 181835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 181935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&symtab_command); 182035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 182135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 182235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands).Place(&symbols).Place(&strings); 182335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 182435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 182535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 182635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ByteBuffer symbols_found, strings_found; 182735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(load_command_handler, SymtabCommand(_, _)) 182835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .WillOnce(DoAll(SaveArg<0>(&symbols_found), 182935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SaveArg<1>(&strings_found), 183035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek Return(true))); 183135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_TRUE(reader.WalkLoadCommands(&load_command_handler)); 183235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 183335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(32U, symbols_found.Size()); 183435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_EQ(8U, strings_found.Size()); 183535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 183635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 183735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(Symtab, SymtabMisplacedSymbols) { 183835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kBigEndian, 32); 183935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 184035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek StringAssembler strings; 184135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler symbols(&strings); 184235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symbols 184335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") 184435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); 184535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 184635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection symtab_command; 184735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symtab_command 184835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SYMTAB) // command 184935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symtab_command.final_size()) // size 185035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symbols.start()) // file offset of symbols 185135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(3) // symbol count (too many) 185235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.start()) // file offset of strings 185335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.final_size()); // strings size 185435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 185535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 185635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&symtab_command); 185735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 185835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 185935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Put symbols at end, so the excessive length will be noticed. 186035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands).Place(&strings).Place(&symbols); 186135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 186235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 186335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 186435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1); 186535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 186635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 186735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 186835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarekTEST_F(Symtab, SymtabMisplacedStrings) { 186935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek WithConfiguration config(kLittleEndian, 32); 187035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 187135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek StringAssembler strings; 187235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SymbolAssembler symbols(&strings); 187335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symbols 187435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xa7, 0xaf, 0x03af, 0x42f3072c74335181ULL, "foo") 187535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .Symbol(0xb0, 0x9a, 0x2aa7, 0x2e2d349b3d5744a0ULL, "bar"); 187635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 187735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek SizedSection symtab_command; 187835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek symtab_command 187935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(LC_SYMTAB) // command 188035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symtab_command.final_size()) // size 188135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(symbols.start()) // file offset of symbols 188235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(2) // symbol count 188335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.start()) // file offset of strings 188435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek .D32(strings.final_size() + 1); // strings size (too long) 188535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 188635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek LoadCommands load_commands; 188735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek load_commands.Place(&symtab_command); 188835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 188935c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek MachOFile file; 189035c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek // Put strings at end, so the excessive length will be noticed. 189135c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek file.Header(&load_commands).Place(&symbols).Place(&strings); 189235c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 189335c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek ReadFile(&file, true, CPU_TYPE_ANY, 0); 189435c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 189535c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_CALL(reporter, MisplacedSymbolTable()).Times(1); 189635c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek EXPECT_FALSE(reader.WalkLoadCommands(&load_command_handler)); 189735c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek} 189835c41e00ee2cf9280fe0122c75877ba70b41bb46ted.mielczarek 1899