1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/linux/synth_elf_unittest.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,413 @@ 1.4 +// Copyright (c) 2011 Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// Original author: Ted Mielczarek <ted.mielczarek@gmail.com> 1.34 + 1.35 +// synth_elf_unittest.cc: 1.36 +// Unittests for google_breakpad::synth_elf::ELF 1.37 + 1.38 +#include <elf.h> 1.39 + 1.40 +#include "breakpad_googletest_includes.h" 1.41 +#include "common/linux/elfutils.h" 1.42 +#include "common/linux/synth_elf.h" 1.43 +#include "common/using_std_string.h" 1.44 + 1.45 +using google_breakpad::ElfClass32; 1.46 +using google_breakpad::ElfClass64; 1.47 +using google_breakpad::synth_elf::ELF; 1.48 +using google_breakpad::synth_elf::Notes; 1.49 +using google_breakpad::synth_elf::Section; 1.50 +using google_breakpad::synth_elf::StringTable; 1.51 +using google_breakpad::synth_elf::SymbolTable; 1.52 +using google_breakpad::test_assembler::Endianness; 1.53 +using google_breakpad::test_assembler::kBigEndian; 1.54 +using google_breakpad::test_assembler::kLittleEndian; 1.55 +using google_breakpad::test_assembler::Label; 1.56 +using ::testing::Test; 1.57 +using ::testing::Types; 1.58 + 1.59 +class StringTableTest : public Test { 1.60 +public: 1.61 + StringTableTest() : table(kLittleEndian) {} 1.62 + 1.63 + StringTable table; 1.64 +}; 1.65 + 1.66 +TEST_F(StringTableTest, Empty) { 1.67 + EXPECT_EQ(1U, table.Size()); 1.68 + string contents; 1.69 + ASSERT_TRUE(table.GetContents(&contents)); 1.70 + const char* kExpectedContents = "\0"; 1.71 + EXPECT_EQ(0, memcmp(kExpectedContents, 1.72 + contents.c_str(), 1.73 + contents.size())); 1.74 + ASSERT_TRUE(table.empty_string.IsKnownConstant()); 1.75 + EXPECT_EQ(0U, table.empty_string.Value()); 1.76 +} 1.77 + 1.78 +TEST_F(StringTableTest, Basic) { 1.79 + const string s1("table fills with strings"); 1.80 + const string s2("offsets preserved as labels"); 1.81 + const string s3("verified with tests"); 1.82 + const char* kExpectedContents = 1.83 + "\0table fills with strings\0" 1.84 + "offsets preserved as labels\0" 1.85 + "verified with tests\0"; 1.86 + Label l1(table.Add(s1)); 1.87 + Label l2(table.Add(s2)); 1.88 + Label l3(table.Add(s3)); 1.89 + string contents; 1.90 + ASSERT_TRUE(table.GetContents(&contents)); 1.91 + EXPECT_EQ(0, memcmp(kExpectedContents, 1.92 + contents.c_str(), 1.93 + contents.size())); 1.94 + // empty_string is at zero, other strings start at 1. 1.95 + ASSERT_TRUE(l1.IsKnownConstant()); 1.96 + EXPECT_EQ(1U, l1.Value()); 1.97 + // Each string has an extra byte for a trailing null. 1.98 + EXPECT_EQ(1 + s1.length() + 1, l2.Value()); 1.99 + EXPECT_EQ(1 + s1.length() + 1 + s2.length() + 1, l3.Value()); 1.100 +} 1.101 + 1.102 +TEST_F(StringTableTest, Duplicates) { 1.103 + const string s1("string 1"); 1.104 + const string s2("string 2"); 1.105 + const string s3(""); 1.106 + const char* kExpectedContents = "\0string 1\0string 2\0"; 1.107 + Label l1(table.Add(s1)); 1.108 + Label l2(table.Add(s2)); 1.109 + // Adding strings twice should return the same Label. 1.110 + Label l3(table.Add(s3)); 1.111 + Label l4(table.Add(s2)); 1.112 + string contents; 1.113 + ASSERT_TRUE(table.GetContents(&contents)); 1.114 + EXPECT_EQ(0, memcmp(kExpectedContents, 1.115 + contents.c_str(), 1.116 + contents.size())); 1.117 + EXPECT_EQ(0U, table.empty_string.Value()); 1.118 + EXPECT_EQ(table.empty_string.Value(), l3.Value()); 1.119 + EXPECT_EQ(l2.Value(), l4.Value()); 1.120 +} 1.121 + 1.122 +class SymbolTableTest : public Test {}; 1.123 + 1.124 +TEST_F(SymbolTableTest, Simple32) { 1.125 + StringTable table(kLittleEndian); 1.126 + SymbolTable syms(kLittleEndian, 4, table); 1.127 + 1.128 + const string kFuncName1 = "superfunc"; 1.129 + const uint32_t kFuncAddr1 = 0x10001000; 1.130 + const uint32_t kFuncSize1 = 0x10; 1.131 + const string kFuncName2 = "awesomefunc"; 1.132 + const uint32_t kFuncAddr2 = 0x20002000; 1.133 + const uint32_t kFuncSize2 = 0x2f; 1.134 + const string kFuncName3 = "megafunc"; 1.135 + const uint32_t kFuncAddr3 = 0x30003000; 1.136 + const uint32_t kFuncSize3 = 0x3c; 1.137 + 1.138 + syms.AddSymbol(kFuncName1, kFuncAddr1, kFuncSize1, 1.139 + ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 1.140 + SHN_UNDEF + 1); 1.141 + syms.AddSymbol(kFuncName2, kFuncAddr2, kFuncSize2, 1.142 + ELF32_ST_INFO(STB_LOCAL, STT_FUNC), 1.143 + SHN_UNDEF + 2); 1.144 + syms.AddSymbol(kFuncName3, kFuncAddr3, kFuncSize3, 1.145 + ELF32_ST_INFO(STB_LOCAL, STT_FUNC), 1.146 + SHN_UNDEF + 3); 1.147 + 1.148 + const char kExpectedStringTable[] = "\0superfunc\0awesomefunc\0megafunc"; 1.149 + const size_t kExpectedStringTableSize = sizeof(kExpectedStringTable); 1.150 + EXPECT_EQ(kExpectedStringTableSize, table.Size()); 1.151 + string table_contents; 1.152 + table.GetContents(&table_contents); 1.153 + EXPECT_EQ(0, memcmp(kExpectedStringTable, 1.154 + table_contents.c_str(), 1.155 + table_contents.size())); 1.156 + 1.157 + const uint8_t kExpectedSymbolContents[] = { 1.158 + // Symbol 1 1.159 + 0x01, 0x00, 0x00, 0x00, // name 1.160 + 0x00, 0x10, 0x00, 0x10, // value 1.161 + 0x10, 0x00, 0x00, 0x00, // size 1.162 + ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), // info 1.163 + 0x00, // other 1.164 + 0x01, 0x00, // shndx 1.165 + // Symbol 2 1.166 + 0x0B, 0x00, 0x00, 0x00, // name 1.167 + 0x00, 0x20, 0x00, 0x20, // value 1.168 + 0x2f, 0x00, 0x00, 0x00, // size 1.169 + ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info 1.170 + 0x00, // other 1.171 + 0x02, 0x00, // shndx 1.172 + // Symbol 3 1.173 + 0x17, 0x00, 0x00, 0x00, // name 1.174 + 0x00, 0x30, 0x00, 0x30, // value 1.175 + 0x3c, 0x00, 0x00, 0x00, // size 1.176 + ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info 1.177 + 0x00, // other 1.178 + 0x03, 0x00, // shndx 1.179 + }; 1.180 + const size_t kExpectedSymbolSize = sizeof(kExpectedSymbolContents); 1.181 + EXPECT_EQ(kExpectedSymbolSize, syms.Size()); 1.182 + 1.183 + string symbol_contents; 1.184 + syms.GetContents(&symbol_contents); 1.185 + EXPECT_EQ(0, memcmp(kExpectedSymbolContents, 1.186 + symbol_contents.c_str(), 1.187 + symbol_contents.size())); 1.188 +} 1.189 + 1.190 +template<typename ElfClass> 1.191 +class BasicElf : public Test {}; 1.192 + 1.193 +// Doesn't seem worthwhile writing the tests to be endian-independent 1.194 +// when they're unlikely to ever be run on big-endian systems. 1.195 +#if defined(__i386__) || defined(__x86_64__) 1.196 + 1.197 +typedef Types<ElfClass32, ElfClass64> ElfClasses; 1.198 + 1.199 +TYPED_TEST_CASE(BasicElf, ElfClasses); 1.200 + 1.201 +TYPED_TEST(BasicElf, EmptyLE) { 1.202 + typedef typename TypeParam::Ehdr Ehdr; 1.203 + typedef typename TypeParam::Phdr Phdr; 1.204 + typedef typename TypeParam::Shdr Shdr; 1.205 + const size_t kStringTableSize = sizeof("\0.shstrtab"); 1.206 + const size_t kStringTableAlign = 4 - kStringTableSize % 4; 1.207 + const size_t kExpectedSize = sizeof(Ehdr) + 1.208 + // Two sections, SHT_NULL + the section header string table. 1.209 + 2 * sizeof(Shdr) + 1.210 + kStringTableSize + kStringTableAlign; 1.211 + 1.212 + // It doesn't really matter that the machine type is right for the class. 1.213 + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); 1.214 + elf.Finish(); 1.215 + EXPECT_EQ(kExpectedSize, elf.Size()); 1.216 + 1.217 + string contents; 1.218 + ASSERT_TRUE(elf.GetContents(&contents)); 1.219 + ASSERT_EQ(kExpectedSize, contents.size()); 1.220 + const Ehdr* header = 1.221 + reinterpret_cast<const Ehdr*>(contents.data()); 1.222 + const uint8_t kIdent[] = { 1.223 + ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, 1.224 + TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV, 1.225 + 0, 0, 0, 0, 0, 0, 0, 0 1.226 + }; 1.227 + EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent))); 1.228 + EXPECT_EQ(ET_EXEC, header->e_type); 1.229 + EXPECT_EQ(EM_386, header->e_machine); 1.230 + EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version); 1.231 + EXPECT_EQ(0U, header->e_entry); 1.232 + EXPECT_EQ(0U, header->e_phoff); 1.233 + EXPECT_EQ(sizeof(Ehdr) + kStringTableSize + kStringTableAlign, 1.234 + header->e_shoff); 1.235 + EXPECT_EQ(0U, header->e_flags); 1.236 + EXPECT_EQ(sizeof(Ehdr), header->e_ehsize); 1.237 + EXPECT_EQ(sizeof(Phdr), header->e_phentsize); 1.238 + EXPECT_EQ(0, header->e_phnum); 1.239 + EXPECT_EQ(sizeof(Shdr), header->e_shentsize); 1.240 + EXPECT_EQ(2, header->e_shnum); 1.241 + EXPECT_EQ(1, header->e_shstrndx); 1.242 + 1.243 + const Shdr* shdr = 1.244 + reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff); 1.245 + EXPECT_EQ(0U, shdr[0].sh_name); 1.246 + EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type); 1.247 + EXPECT_EQ(0U, shdr[0].sh_flags); 1.248 + EXPECT_EQ(0U, shdr[0].sh_addr); 1.249 + EXPECT_EQ(0U, shdr[0].sh_offset); 1.250 + EXPECT_EQ(0U, shdr[0].sh_size); 1.251 + EXPECT_EQ(0U, shdr[0].sh_link); 1.252 + EXPECT_EQ(0U, shdr[0].sh_info); 1.253 + EXPECT_EQ(0U, shdr[0].sh_addralign); 1.254 + EXPECT_EQ(0U, shdr[0].sh_entsize); 1.255 + 1.256 + EXPECT_EQ(1U, shdr[1].sh_name); 1.257 + EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[1].sh_type); 1.258 + EXPECT_EQ(0U, shdr[1].sh_flags); 1.259 + EXPECT_EQ(0U, shdr[1].sh_addr); 1.260 + EXPECT_EQ(sizeof(Ehdr), shdr[1].sh_offset); 1.261 + EXPECT_EQ(kStringTableSize, shdr[1].sh_size); 1.262 + EXPECT_EQ(0U, shdr[1].sh_link); 1.263 + EXPECT_EQ(0U, shdr[1].sh_info); 1.264 + EXPECT_EQ(0U, shdr[1].sh_addralign); 1.265 + EXPECT_EQ(0U, shdr[1].sh_entsize); 1.266 +} 1.267 + 1.268 +TYPED_TEST(BasicElf, BasicLE) { 1.269 + typedef typename TypeParam::Ehdr Ehdr; 1.270 + typedef typename TypeParam::Phdr Phdr; 1.271 + typedef typename TypeParam::Shdr Shdr; 1.272 + const size_t kStringTableSize = sizeof("\0.text\0.bss\0.shstrtab"); 1.273 + const size_t kStringTableAlign = 4 - kStringTableSize % 4; 1.274 + const size_t kExpectedSize = sizeof(Ehdr) + 1.275 + // Four sections, SHT_NULL + the section header string table + 1.276 + // 4096 bytes of the size-aligned .text section + one program header. 1.277 + sizeof(Phdr) + 4 * sizeof(Shdr) + 4096 + 1.278 + kStringTableSize + kStringTableAlign; 1.279 + 1.280 + // It doesn't really matter that the machine type is right for the class. 1.281 + ELF elf(EM_386, TypeParam::kClass, kLittleEndian); 1.282 + Section text(kLittleEndian); 1.283 + text.Append(4094, 0); 1.284 + int text_idx = elf.AddSection(".text", text, SHT_PROGBITS); 1.285 + Section bss(kLittleEndian); 1.286 + bss.Append(16, 0); 1.287 + int bss_idx = elf.AddSection(".bss", bss, SHT_NOBITS); 1.288 + elf.AddSegment(text_idx, bss_idx, PT_LOAD); 1.289 + elf.Finish(); 1.290 + EXPECT_EQ(kExpectedSize, elf.Size()); 1.291 + 1.292 + string contents; 1.293 + ASSERT_TRUE(elf.GetContents(&contents)); 1.294 + ASSERT_EQ(kExpectedSize, contents.size()); 1.295 + const Ehdr* header = 1.296 + reinterpret_cast<const Ehdr*>(contents.data()); 1.297 + const uint8_t kIdent[] = { 1.298 + ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, 1.299 + TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV, 1.300 + 0, 0, 0, 0, 0, 0, 0, 0 1.301 + }; 1.302 + EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent))); 1.303 + EXPECT_EQ(ET_EXEC, header->e_type); 1.304 + EXPECT_EQ(EM_386, header->e_machine); 1.305 + EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version); 1.306 + EXPECT_EQ(0U, header->e_entry); 1.307 + EXPECT_EQ(sizeof(Ehdr), header->e_phoff); 1.308 + EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096 + kStringTableSize + 1.309 + kStringTableAlign, header->e_shoff); 1.310 + EXPECT_EQ(0U, header->e_flags); 1.311 + EXPECT_EQ(sizeof(Ehdr), header->e_ehsize); 1.312 + EXPECT_EQ(sizeof(Phdr), header->e_phentsize); 1.313 + EXPECT_EQ(1, header->e_phnum); 1.314 + EXPECT_EQ(sizeof(Shdr), header->e_shentsize); 1.315 + EXPECT_EQ(4, header->e_shnum); 1.316 + EXPECT_EQ(3, header->e_shstrndx); 1.317 + 1.318 + const Shdr* shdr = 1.319 + reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff); 1.320 + EXPECT_EQ(0U, shdr[0].sh_name); 1.321 + EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type); 1.322 + EXPECT_EQ(0U, shdr[0].sh_flags); 1.323 + EXPECT_EQ(0U, shdr[0].sh_addr); 1.324 + EXPECT_EQ(0U, shdr[0].sh_offset); 1.325 + EXPECT_EQ(0U, shdr[0].sh_size); 1.326 + EXPECT_EQ(0U, shdr[0].sh_link); 1.327 + EXPECT_EQ(0U, shdr[0].sh_info); 1.328 + EXPECT_EQ(0U, shdr[0].sh_addralign); 1.329 + EXPECT_EQ(0U, shdr[0].sh_entsize); 1.330 + 1.331 + EXPECT_EQ(1U, shdr[1].sh_name); 1.332 + EXPECT_EQ(static_cast<unsigned int>(SHT_PROGBITS), shdr[1].sh_type); 1.333 + EXPECT_EQ(0U, shdr[1].sh_flags); 1.334 + EXPECT_EQ(0U, shdr[1].sh_addr); 1.335 + EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), shdr[1].sh_offset); 1.336 + EXPECT_EQ(4094U, shdr[1].sh_size); 1.337 + EXPECT_EQ(0U, shdr[1].sh_link); 1.338 + EXPECT_EQ(0U, shdr[1].sh_info); 1.339 + EXPECT_EQ(0U, shdr[1].sh_addralign); 1.340 + EXPECT_EQ(0U, shdr[1].sh_entsize); 1.341 + 1.342 + EXPECT_EQ(sizeof("\0.text"), shdr[2].sh_name); 1.343 + EXPECT_EQ(static_cast<unsigned int>(SHT_NOBITS), shdr[2].sh_type); 1.344 + EXPECT_EQ(0U, shdr[2].sh_flags); 1.345 + EXPECT_EQ(0U, shdr[2].sh_addr); 1.346 + EXPECT_EQ(0U, shdr[2].sh_offset); 1.347 + EXPECT_EQ(16U, shdr[2].sh_size); 1.348 + EXPECT_EQ(0U, shdr[2].sh_link); 1.349 + EXPECT_EQ(0U, shdr[2].sh_info); 1.350 + EXPECT_EQ(0U, shdr[2].sh_addralign); 1.351 + EXPECT_EQ(0U, shdr[2].sh_entsize); 1.352 + 1.353 + EXPECT_EQ(sizeof("\0.text\0.bss"), shdr[3].sh_name); 1.354 + EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[3].sh_type); 1.355 + EXPECT_EQ(0U, shdr[3].sh_flags); 1.356 + EXPECT_EQ(0U, shdr[3].sh_addr); 1.357 + EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096, shdr[3].sh_offset); 1.358 + EXPECT_EQ(kStringTableSize, shdr[3].sh_size); 1.359 + EXPECT_EQ(0U, shdr[3].sh_link); 1.360 + EXPECT_EQ(0U, shdr[3].sh_info); 1.361 + EXPECT_EQ(0U, shdr[3].sh_addralign); 1.362 + EXPECT_EQ(0U, shdr[3].sh_entsize); 1.363 + 1.364 + const Phdr* phdr = 1.365 + reinterpret_cast<const Phdr*>(contents.data() + header->e_phoff); 1.366 + EXPECT_EQ(static_cast<unsigned int>(PT_LOAD), phdr->p_type); 1.367 + EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), phdr->p_offset); 1.368 + EXPECT_EQ(0U, phdr->p_vaddr); 1.369 + EXPECT_EQ(0U, phdr->p_paddr); 1.370 + EXPECT_EQ(4096U, phdr->p_filesz); 1.371 + EXPECT_EQ(4096U + 16U, phdr->p_memsz); 1.372 + EXPECT_EQ(0U, phdr->p_flags); 1.373 + EXPECT_EQ(0U, phdr->p_align); 1.374 +} 1.375 + 1.376 +class ElfNotesTest : public Test {}; 1.377 + 1.378 +TEST_F(ElfNotesTest, Empty) { 1.379 + Notes notes(kLittleEndian); 1.380 + string contents; 1.381 + ASSERT_TRUE(notes.GetContents(&contents)); 1.382 + EXPECT_EQ(0U, contents.size()); 1.383 +} 1.384 + 1.385 +TEST_F(ElfNotesTest, Notes) { 1.386 + Notes notes(kLittleEndian); 1.387 + notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"), 1.388 + 4); 1.389 + notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"), 1.390 + sizeof("foobar") - 1); 1.391 + 1.392 + const uint8_t kExpectedNotesContents[] = { 1.393 + // Note 1 1.394 + 0x06, 0x00, 0x00, 0x00, // name size, including terminating zero 1.395 + 0x04, 0x00, 0x00, 0x00, // desc size 1.396 + 0x01, 0x00, 0x00, 0x00, // type 1.397 + 'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux" 1.398 + 0x42, 0x02, 0x00, 0x00, // desc 1.399 + // Note 2 1.400 + 0x02, 0x00, 0x00, 0x00, // name size 1.401 + 0x06, 0x00, 0x00, 0x00, // desc size 1.402 + 0x02, 0x00, 0x00, 0x00, // type 1.403 + 'a', 0x00, 0x00, 0x00, // padded "a" 1.404 + 'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar" 1.405 + }; 1.406 + const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents); 1.407 + EXPECT_EQ(kExpectedNotesSize, notes.Size()); 1.408 + 1.409 + string notes_contents; 1.410 + ASSERT_TRUE(notes.GetContents(¬es_contents)); 1.411 + EXPECT_EQ(0, memcmp(kExpectedNotesContents, 1.412 + notes_contents.data(), 1.413 + notes_contents.size())); 1.414 +} 1.415 + 1.416 +#endif // defined(__i386__) || defined(__x86_64__)