// Copyright 2014 The Crashpad Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "snapshot/mac/mach_o_image_segment_reader.h" #include #include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" namespace crashpad { namespace test { namespace { // Most of MachOImageSegmentReader is tested as part of MachOImageReader, which // depends on MachOImageSegmentReader to provide major portions of its // functionality. Because MachOImageSegmentReader is difficult to use except by // a Mach-O load command reader such as MachOImageReader, these portions // of MachOImageSegmentReader are not tested independently. // // The tests here exercise the portions of MachOImageSegmentReader that are // exposed and independently useful. TEST(MachOImageSegmentReader, SegmentNameString) { // The output value should be a string of up to 16 characters, even if the // input value is not NUL-terminated within 16 characters. EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("__TEXT"), "__TEXT"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("__OVER"), "__OVER"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString(""), ""); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("p"), "p"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("NoUnderChar"), "NoUnderChar"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("0123456789abcde"), "0123456789abcde"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("0123456789abcdef"), "0123456789abcdef"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("gfedcba9876543210"), "gfedcba987654321"); EXPECT_EQ(MachOImageSegmentReader::SegmentNameString("hgfedcba9876543210"), "hgfedcba98765432"); // Segment names defined in . All of these should come // through SegmentNameString() cleanly and without truncation. static constexpr const char* kSegmentTestData[] = { SEG_TEXT, SEG_DATA, SEG_OBJC, SEG_ICON, SEG_LINKEDIT, SEG_UNIXSTACK, SEG_IMPORT, }; for (size_t index = 0; index < base::size(kSegmentTestData); ++index) { EXPECT_EQ( MachOImageSegmentReader::SegmentNameString(kSegmentTestData[index]), kSegmentTestData[index]) << base::StringPrintf("index %zu", index); } } TEST(MachOImageSegmentReader, SectionNameString) { // The output value should be a string of up to 16 characters, even if the // input value is not NUL-terminated within 16 characters. EXPECT_EQ(MachOImageSegmentReader::SectionNameString("__text"), "__text"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("__over"), "__over"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString(""), ""); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("p"), "p"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("NoUnderChar"), "NoUnderChar"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("0123456789abcde"), "0123456789abcde"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("0123456789abcdef"), "0123456789abcdef"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("gfedcba9876543210"), "gfedcba987654321"); EXPECT_EQ(MachOImageSegmentReader::SectionNameString("hgfedcba9876543210"), "hgfedcba98765432"); // Section names defined in . All of these should come // through SectionNameString() cleanly and without truncation. static constexpr const char* kSectionTestData[] = { SECT_TEXT, SECT_FVMLIB_INIT0, SECT_FVMLIB_INIT1, SECT_DATA, SECT_BSS, SECT_COMMON, SECT_OBJC_SYMBOLS, SECT_OBJC_MODULES, SECT_OBJC_STRINGS, SECT_OBJC_REFS, SECT_ICON_HEADER, SECT_ICON_TIFF, }; for (size_t index = 0; index < base::size(kSectionTestData); ++index) { EXPECT_EQ( MachOImageSegmentReader::SectionNameString(kSectionTestData[index]), kSectionTestData[index]) << base::StringPrintf("index %zu", index); } } TEST(MachOImageSegmentReader, SegmentAndSectionNameString) { static constexpr struct { const char* segment; const char* section; const char* output; } kSegmentAndSectionTestData[] = { {"segment", "section", "segment,section"}, {"Segment", "Section", "Segment,Section"}, {"SEGMENT", "SECTION", "SEGMENT,SECTION"}, {"__TEXT", "__plain", "__TEXT,__plain"}, {"__TEXT", "poetry", "__TEXT,poetry"}, {"__TEXT", "Prose", "__TEXT,Prose"}, {"__PLAIN", "__text", "__PLAIN,__text"}, {"rich", "__text", "rich,__text"}, {"segment", "", "segment,"}, {"", "section", ",section"}, {"", "", ","}, {"0123456789abcdef", "section", "0123456789abcdef,section"}, {"gfedcba9876543210", "section", "gfedcba987654321,section"}, {"0123456789abcdef", "", "0123456789abcdef,"}, {"gfedcba9876543210", "", "gfedcba987654321,"}, {"segment", "0123456789abcdef", "segment,0123456789abcdef"}, {"segment", "gfedcba9876543210", "segment,gfedcba987654321"}, {"", "0123456789abcdef", ",0123456789abcdef"}, {"", "gfedcba9876543210", ",gfedcba987654321"}, {"0123456789abcdef", "0123456789abcdef", "0123456789abcdef,0123456789abcdef"}, {"gfedcba9876543210", "gfedcba9876543210", "gfedcba987654321,gfedcba987654321"}, // Sections defined in . All of these should come through // SegmentAndSectionNameString() cleanly and without truncation. {SEG_TEXT, SECT_TEXT, "__TEXT,__text"}, {SEG_TEXT, SECT_FVMLIB_INIT0, "__TEXT,__fvmlib_init0"}, {SEG_TEXT, SECT_FVMLIB_INIT1, "__TEXT,__fvmlib_init1"}, {SEG_DATA, SECT_DATA, "__DATA,__data"}, {SEG_DATA, SECT_BSS, "__DATA,__bss"}, {SEG_DATA, SECT_COMMON, "__DATA,__common"}, {SEG_OBJC, SECT_OBJC_SYMBOLS, "__OBJC,__symbol_table"}, {SEG_OBJC, SECT_OBJC_MODULES, "__OBJC,__module_info"}, {SEG_OBJC, SECT_OBJC_STRINGS, "__OBJC,__selector_strs"}, {SEG_OBJC, SECT_OBJC_REFS, "__OBJC,__selector_refs"}, {SEG_ICON, SECT_ICON_HEADER, "__ICON,__header"}, {SEG_ICON, SECT_ICON_TIFF, "__ICON,__tiff"}, // These segments don’t normally have sections, but the above group tested // the known segment names for segments that do normally have sections. // This group does the same for segments that normally don’t. {SEG_LINKEDIT, "", "__LINKEDIT,"}, {SEG_UNIXSTACK, "", "__UNIXSTACK,"}, {SEG_IMPORT, "", "__IMPORT,"}, }; for (size_t index = 0; index < base::size(kSegmentAndSectionTestData); ++index) { const auto& test = kSegmentAndSectionTestData[index]; EXPECT_EQ(MachOImageSegmentReader::SegmentAndSectionNameString( test.segment, test.section), test.output) << base::StringPrintf("index %zu, segment %s, section %s", index, test.segment, test.section); } } } // namespace } // namespace test } // namespace crashpad