13ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// Copyright (c) 2011 Google Inc.
23ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// All rights reserved.
33ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//
43ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// Redistribution and use in source and binary forms, with or without
53ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// modification, are permitted provided that the following conditions are
63ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// met:
73ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//
83ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//     * Redistributions of source code must retain the above copyright
93ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// notice, this list of conditions and the following disclaimer.
103ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//     * Redistributions in binary form must reproduce the above
113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// copyright notice, this list of conditions and the following disclaimer
123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// in the documentation and/or other materials provided with the
133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// distribution.
143ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//     * Neither the name of Google Inc. nor the names of its
153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// contributors may be used to endorse or promote products derived from
163ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// this software without specific prior written permission.
173ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek//
183ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
193ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
203ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
213ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
243ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
253ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
263ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
273ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
283ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
293ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
303ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// Original author: Ted Mielczarek <ted.mielczarek@gmail.com>
313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
323ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// synth_elf_unittest.cc:
333ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// Unittests for google_breakpad::synth_elf::ELF
343ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
353ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include <elf.h>
363ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
373ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include "breakpad_googletest_includes.h"
3897e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com#include "common/linux/elfutils.h"
393ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include "common/linux/synth_elf.h"
404e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
413ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
4297e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comusing google_breakpad::ElfClass32;
4397e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comusing google_breakpad::ElfClass64;
443ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::synth_elf::ELF;
45ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.comusing google_breakpad::synth_elf::Notes;
46cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.comusing google_breakpad::synth_elf::Section;
473ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::synth_elf::StringTable;
483ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::synth_elf::SymbolTable;
493ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::test_assembler::Endianness;
503ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::test_assembler::kBigEndian;
513ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::test_assembler::kLittleEndian;
523ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::test_assembler::Label;
533ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing ::testing::Test;
5497e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comusing ::testing::Types;
553ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
563ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekclass StringTableTest : public Test {
573ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekpublic:
583ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  StringTableTest() : table(kLittleEndian) {}
593ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
603ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  StringTable table;
613ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek};
623ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
633ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekTEST_F(StringTableTest, Empty) {
642971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(1U, table.Size());
653ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string contents;
663ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(table.GetContents(&contents));
673ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const char* kExpectedContents = "\0";
683ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kExpectedContents,
693ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.c_str(),
703ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.size()));
713ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(table.empty_string.IsKnownConstant());
722971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(0U, table.empty_string.Value());
733ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
743ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
753ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekTEST_F(StringTableTest, Basic) {
763ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s1("table fills with strings");
773ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s2("offsets preserved as labels");
783ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s3("verified with tests");
793ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const char* kExpectedContents =
803ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    "\0table fills with strings\0"
813ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    "offsets preserved as labels\0"
823ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    "verified with tests\0";
833ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l1(table.Add(s1));
843ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l2(table.Add(s2));
853ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l3(table.Add(s3));
863ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string contents;
873ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(table.GetContents(&contents));
883ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kExpectedContents,
893ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.c_str(),
903ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.size()));
913ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // empty_string is at zero, other strings start at 1.
923ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(l1.IsKnownConstant());
932971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(1U, l1.Value());
943ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Each string has an extra byte for a trailing null.
953ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(1 + s1.length() + 1, l2.Value());
963ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(1 + s1.length() + 1 + s2.length() + 1, l3.Value());
973ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
983ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
993ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekTEST_F(StringTableTest, Duplicates) {
1003ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s1("string 1");
1013ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s2("string 2");
1023ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string s3("");
1033ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const char* kExpectedContents = "\0string 1\0string 2\0";
1043ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l1(table.Add(s1));
1053ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l2(table.Add(s2));
1063ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  // Adding strings twice should return the same Label.
1073ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l3(table.Add(s3));
1083ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  Label l4(table.Add(s2));
1093ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string contents;
1103ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(table.GetContents(&contents));
1113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kExpectedContents,
1123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.c_str(),
1133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      contents.size()));
1142971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(0U, table.empty_string.Value());
1153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(table.empty_string.Value(), l3.Value());
1163ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(l2.Value(), l4.Value());
1173ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
1183ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1193ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekclass SymbolTableTest : public Test {};
1203ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1213ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekTEST_F(SymbolTableTest, Simple32) {
1223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  StringTable table(kLittleEndian);
1233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  SymbolTable syms(kLittleEndian, 4, table);
1243ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1253ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string kFuncName1 = "superfunc";
1263ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncAddr1 = 0x10001000;
1273ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncSize1 = 0x10;
1283ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string kFuncName2 = "awesomefunc";
1293ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncAddr2 = 0x20002000;
1303ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncSize2 = 0x2f;
1313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const string kFuncName3 = "megafunc";
1323ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncAddr3 = 0x30003000;
1333ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint32_t kFuncSize3 = 0x3c;
1343ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1353ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  syms.AddSymbol(kFuncName1, kFuncAddr1, kFuncSize1,
1363ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
1373ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 SHN_UNDEF + 1);
1383ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  syms.AddSymbol(kFuncName2, kFuncAddr2, kFuncSize2,
1393ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
1403ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 SHN_UNDEF + 2);
1413ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  syms.AddSymbol(kFuncName3, kFuncAddr3, kFuncSize3,
1423ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
1433ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                 SHN_UNDEF + 3);
1443ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1453ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const char kExpectedStringTable[] = "\0superfunc\0awesomefunc\0megafunc";
1463ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const size_t kExpectedStringTableSize = sizeof(kExpectedStringTable);
1473ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(kExpectedStringTableSize, table.Size());
1483ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string table_contents;
1493ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  table.GetContents(&table_contents);
1503ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kExpectedStringTable,
1513ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      table_contents.c_str(),
1523ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      table_contents.size()));
1533ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1543ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint8_t kExpectedSymbolContents[] = {
1553ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // Symbol 1
1563ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x01, 0x00, 0x00, 0x00, // name
1573ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, 0x10, 0x00, 0x10, // value
1583ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x10, 0x00, 0x00, 0x00, // size
1593ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), // info
1603ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, // other
1613ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x01, 0x00, // shndx
1623ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // Symbol 2
1633ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x0B, 0x00, 0x00, 0x00, // name
1643ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, 0x20, 0x00, 0x20, // value
1653ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x2f, 0x00, 0x00, 0x00, // size
1663ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info
1673ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, // other
1683ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x02, 0x00, // shndx
1693ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // Symbol 3
1703ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x17, 0x00, 0x00, 0x00, // name
1713ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, 0x30, 0x00, 0x30, // value
1723ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x3c, 0x00, 0x00, 0x00, // size
1733ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    ELF32_ST_INFO(STB_LOCAL, STT_FUNC), // info
1743ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x00, // other
1753ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0x03, 0x00, // shndx
1763ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  };
1773ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const size_t kExpectedSymbolSize = sizeof(kExpectedSymbolContents);
1783ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(kExpectedSymbolSize, syms.Size());
1793ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1803ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string symbol_contents;
1813ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  syms.GetContents(&symbol_contents);
1823ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kExpectedSymbolContents,
1833ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      symbol_contents.c_str(),
1843ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek                      symbol_contents.size()));
1853ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
1863ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
18797e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comtemplate<typename ElfClass>
1883ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekclass BasicElf : public Test {};
1893ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
1903ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// Doesn't seem worthwhile writing the tests to be endian-independent
1913ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek// when they're unlikely to ever be run on big-endian systems.
1923ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#if defined(__i386__) || defined(__x86_64__)
1933ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
19497e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comtypedef Types<ElfClass32, ElfClass64> ElfClasses;
1953ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
19697e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comTYPED_TEST_CASE(BasicElf, ElfClasses);
1973ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
19897e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.comTYPED_TEST(BasicElf, EmptyLE) {
19997e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  typedef typename TypeParam::Ehdr Ehdr;
20097e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  typedef typename TypeParam::Phdr Phdr;
20197e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  typedef typename TypeParam::Shdr Shdr;
2023ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const size_t kStringTableSize = sizeof("\0.shstrtab");
2033ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const size_t kStringTableAlign = 4 - kStringTableSize % 4;
20497e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  const size_t kExpectedSize = sizeof(Ehdr) +
2053ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    // Two sections, SHT_NULL + the section header string table.
20697e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com    2 * sizeof(Shdr) +
2073ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    kStringTableSize + kStringTableAlign;
2083ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
20997e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  // It doesn't really matter that the machine type is right for the class.
21097e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
2113ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  elf.Finish();
2123ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(kExpectedSize, elf.Size());
2133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
2143ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  string contents;
2153ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_TRUE(elf.GetContents(&contents));
2163ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  ASSERT_EQ(kExpectedSize, contents.size());
21797e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  const Ehdr* header =
21897e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com    reinterpret_cast<const Ehdr*>(contents.data());
2193ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  const uint8_t kIdent[] = {
2203ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
22197e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com    TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
2223ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek    0, 0, 0, 0, 0, 0, 0, 0
2233ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  };
2243ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
2253ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(ET_EXEC, header->e_type);
22697e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  EXPECT_EQ(EM_386, header->e_machine);
2272971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
2282971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(0U, header->e_entry);
2292971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(0U, header->e_phoff);
23097e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr) + kStringTableSize + kStringTableAlign,
2313ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek            header->e_shoff);
2322971a050754f48aaa807db47a29e0d0beddbdcf7ivan.penkov@gmail.com  EXPECT_EQ(0U, header->e_flags);
23397e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
23497e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
2353ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(0, header->e_phnum);
23697e972cd6340ae1d7d238d5c7aa7363a58145a0eted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
2373ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(2, header->e_shnum);
2383ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek  EXPECT_EQ(1, header->e_shstrndx);
23976be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com
24076be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  const Shdr* shdr =
24176be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com    reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
24276be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_name);
24376be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
24476be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_flags);
24576be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_addr);
24676be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_offset);
24776be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_size);
24876be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_link);
24976be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_info);
25076be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_addralign);
25176be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_entsize);
25276be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com
25376be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(1U, shdr[1].sh_name);
25476be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[1].sh_type);
25576be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_flags);
25676be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_addr);
25776be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr), shdr[1].sh_offset);
25876be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(kStringTableSize, shdr[1].sh_size);
25976be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_link);
26076be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_info);
26176be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_addralign);
26276be5b612882150ce8f0b39bb403ecbba8d611fated.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_entsize);
2633ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek}
2643ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek
265cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.comTYPED_TEST(BasicElf, BasicLE) {
266cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  typedef typename TypeParam::Ehdr Ehdr;
267cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  typedef typename TypeParam::Phdr Phdr;
268cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  typedef typename TypeParam::Shdr Shdr;
269cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const size_t kStringTableSize = sizeof("\0.text\0.bss\0.shstrtab");
270cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const size_t kStringTableAlign = 4 - kStringTableSize % 4;
271cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const size_t kExpectedSize = sizeof(Ehdr) +
272cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // Four sections, SHT_NULL + the section header string table +
273cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    // 4096 bytes of the size-aligned .text section + one program header.
274cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    sizeof(Phdr) + 4 * sizeof(Shdr) + 4096 +
275cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    kStringTableSize + kStringTableAlign;
276cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
277cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  // It doesn't really matter that the machine type is right for the class.
278cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
279cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  Section text(kLittleEndian);
280cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  text.Append(4094, 0);
281cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  int text_idx = elf.AddSection(".text", text, SHT_PROGBITS);
282cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  Section bss(kLittleEndian);
283cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  bss.Append(16, 0);
284cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  int bss_idx = elf.AddSection(".bss", bss, SHT_NOBITS);
285cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  elf.AddSegment(text_idx, bss_idx, PT_LOAD);
286cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  elf.Finish();
287cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(kExpectedSize, elf.Size());
288cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
289cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  string contents;
290cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  ASSERT_TRUE(elf.GetContents(&contents));
291cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  ASSERT_EQ(kExpectedSize, contents.size());
292cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const Ehdr* header =
293cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    reinterpret_cast<const Ehdr*>(contents.data());
294cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const uint8_t kIdent[] = {
295cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
296cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    TypeParam::kClass, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
297cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    0, 0, 0, 0, 0, 0, 0, 0
298cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  };
299cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0, memcmp(kIdent, header->e_ident, sizeof(kIdent)));
300cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(ET_EXEC, header->e_type);
301cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(EM_386, header->e_machine);
302cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(EV_CURRENT), header->e_version);
303cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, header->e_entry);
304cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr), header->e_phoff);
305cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096 + kStringTableSize +
306cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com            kStringTableAlign, header->e_shoff);
307cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, header->e_flags);
308cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr), header->e_ehsize);
309cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Phdr), header->e_phentsize);
310cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(1, header->e_phnum);
311cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Shdr), header->e_shentsize);
312cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(4, header->e_shnum);
313cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(3, header->e_shstrndx);
314cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
315cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const Shdr* shdr =
316cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    reinterpret_cast<const Shdr*>(contents.data() + header->e_shoff);
317cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_name);
318cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_NULL), shdr[0].sh_type);
319cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_flags);
320cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_addr);
321cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_offset);
322cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_size);
323cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_link);
324cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_info);
325cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_addralign);
326cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[0].sh_entsize);
327cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
328cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(1U, shdr[1].sh_name);
329cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_PROGBITS), shdr[1].sh_type);
330cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_flags);
331cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_addr);
332cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), shdr[1].sh_offset);
333cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(4094U, shdr[1].sh_size);
334cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_link);
335cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_info);
336cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_addralign);
337cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[1].sh_entsize);
338cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
339cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof("\0.text"), shdr[2].sh_name);
340cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_NOBITS), shdr[2].sh_type);
341cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_flags);
342cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_addr);
343cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_offset);
344cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(16U, shdr[2].sh_size);
345cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_link);
346cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_info);
347cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_addralign);
348cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[2].sh_entsize);
349cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
350cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof("\0.text\0.bss"), shdr[3].sh_name);
351cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(SHT_STRTAB), shdr[3].sh_type);
352cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_flags);
353cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_addr);
354cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr) + 4096, shdr[3].sh_offset);
355cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(kStringTableSize, shdr[3].sh_size);
356cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_link);
357cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_info);
358cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_addralign);
359cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, shdr[3].sh_entsize);
360cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
361cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  const Phdr* phdr =
362cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com    reinterpret_cast<const Phdr*>(contents.data() + header->e_phoff);
363cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(static_cast<unsigned int>(PT_LOAD), phdr->p_type);
364cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(sizeof(Ehdr) + sizeof(Phdr), phdr->p_offset);
365cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, phdr->p_vaddr);
366cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, phdr->p_paddr);
367cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(4096U, phdr->p_filesz);
368cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(4096U + 16U, phdr->p_memsz);
369cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, phdr->p_flags);
370cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com  EXPECT_EQ(0U, phdr->p_align);
371cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com}
372cb9a3dc4c863368f337f84a5fc337e1719e41949ted.mielczarek@gmail.com
373ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.comclass ElfNotesTest : public Test {};
374ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com
375ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.comTEST_F(ElfNotesTest, Empty) {
376ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  Notes notes(kLittleEndian);
377ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  string contents;
378ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  ASSERT_TRUE(notes.GetContents(&contents));
379ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  EXPECT_EQ(0U, contents.size());
380ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com}
381ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com
382ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.comTEST_F(ElfNotesTest, Notes) {
383ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  Notes notes(kLittleEndian);
384ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"),
385ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com                4);
386ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"),
387ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com                sizeof("foobar") - 1);
388ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com
389ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  const uint8_t kExpectedNotesContents[] = {
390ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    // Note 1
391ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x06, 0x00, 0x00, 0x00, // name size, including terminating zero
392ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x04, 0x00, 0x00, 0x00, // desc size
393ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x01, 0x00, 0x00, 0x00, // type
394ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    'L', 'i', 'n', 'u', 'x', 0x00, 0x00, 0x00, // padded "Linux"
395ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x42, 0x02, 0x00, 0x00, // desc
396ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    // Note 2
397ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x02, 0x00, 0x00, 0x00, // name size
398ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x06, 0x00, 0x00, 0x00, // desc size
399ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    0x02, 0x00, 0x00, 0x00, // type
400ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    'a',  0x00, 0x00, 0x00, // padded "a"
401ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com    'f', 'o', 'o', 'b', 'a', 'r', 0x00, 0x00, // padded "foobar"
402ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  };
403ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  const size_t kExpectedNotesSize = sizeof(kExpectedNotesContents);
404ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  EXPECT_EQ(kExpectedNotesSize, notes.Size());
405ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com
406ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  string notes_contents;
407ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  ASSERT_TRUE(notes.GetContents(&notes_contents));
408ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com  EXPECT_EQ(0, memcmp(kExpectedNotesContents,
409ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com                      notes_contents.data(),
410ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com                      notes_contents.size()));
411ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com}
412ea6e48ee7dc6bb0e553e4ad2cc45093bcbb27cbdted.mielczarek@gmail.com
4133ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#endif  // defined(__i386__) || defined(__x86_64__)
414