1b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Copyright (c) 2011 Google Inc.
2b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// All rights reserved.
3b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//
4b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Redistribution and use in source and binary forms, with or without
5b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// modification, are permitted provided that the following conditions are
6b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// met:
7b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//
8b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//     * Redistributions of source code must retain the above copyright
9b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// notice, this list of conditions and the following disclaimer.
10b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//     * Redistributions in binary form must reproduce the above
11b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// copyright notice, this list of conditions and the following disclaimer
12b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// in the documentation and/or other materials provided with the
13b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// distribution.
14b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//     * Neither the name of Google Inc. nor the names of its
15b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// contributors may be used to endorse or promote products derived from
16b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// this software without specific prior written permission.
17b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek//
18b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
30b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Original author: Ted Mielczarek <ted.mielczarek@gmail.com>
31b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
32b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// elf_symbols_to_module_unittest.cc:
33b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Unittests for google_breakpad::ELFSymbolsToModule
34b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
35b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include <elf.h>
36b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
37b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include <string>
38b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include <vector>
39b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
40b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include "breakpad_googletest_includes.h"
41b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include "common/linux/elf_symbols_to_module.h"
423ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarek#include "common/linux/synth_elf.h"
43b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include "common/module.h"
44b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek#include "common/test_assembler.h"
454e518a4357a2d1c379d4a91df6d4e153ee791101ivan.penkov@gmail.com#include "common/using_std_string.h"
46b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
47b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::Module;
483ca4a120de8ec3f35e972e4b23f527bb8f65c479ted.mielczarekusing google_breakpad::synth_elf::StringTable;
49b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::test_assembler::Endianness;
50b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::test_assembler::kBigEndian;
51b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::test_assembler::kLittleEndian;
52b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::test_assembler::Label;
53b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing google_breakpad::test_assembler::Section;
54b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing ::testing::Test;
55b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing ::testing::TestWithParam;
56b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekusing std::vector;
57b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
58b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekclass ELFSymbolsToModuleTestFixture {
59b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekpublic:
60b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ELFSymbolsToModuleTestFixture(Endianness endianness,
61b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                size_t value_size) : module("a", "b", "c", "d"),
62b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                                     section(endianness),
63b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                                     table(endianness),
64b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                                     value_size(value_size) {}
65b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
66b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  bool ProcessSection() {
67b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    string section_contents, table_contents;
68b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    section.GetContents(&section_contents);
69b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    table.GetContents(&table_contents);
70b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
71b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    bool ret = ELFSymbolsToModule(reinterpret_cast<const uint8_t*>(section_contents.data()),
72b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  section_contents.size(),
73b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  reinterpret_cast<const uint8_t*>(table_contents.data()),
74b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  table_contents.size(),
75b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  section.endianness() == kBigEndian,
76b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  value_size,
77b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                  &module);
78b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    module.GetExterns(&externs, externs.end());
79b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    return ret;
80b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  }
81b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
82b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module module;
83b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Section section;
84b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  StringTable table;
85b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  string section_contents;
86b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // 4 or 8 (bytes)
87b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  size_t value_size;
88b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
89b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  vector<Module::Extern *> externs;
90b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek};
91b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
92b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekclass ELFSymbolsToModuleTest32 : public ELFSymbolsToModuleTestFixture,
93b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                   public TestWithParam<Endianness>  {
94b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekpublic:
95b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ELFSymbolsToModuleTest32() : ELFSymbolsToModuleTestFixture(GetParam(), 4) {}
96b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
97b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  void AddElf32Sym(const string& name, uint32_t value,
98b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                   uint32_t size, unsigned info, uint16_t shndx) {
99b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    section
100b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D32(table.Add(name))
101b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D32(value)
102b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D32(size)
103b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D8(info)
104b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D8(0) // other
105b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D16(shndx);
106b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  }
107b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek};
108b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
109b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, NoFuncs) {
110b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
111b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
112b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)0, externs.size());
113b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
114b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
115b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, OneFunc) {
116b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "superfunc";
117b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr = 0x1000;
118b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize = 0x10;
119b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
120b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym(kFuncName, kFuncAddr, kFuncSize,
121b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
122b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
123b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
124b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
125b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
126b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
127b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
128b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
129b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
130b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
131b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
132b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
133b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, NameOutOfBounds) {
134b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "";
135b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr = 0x1000;
136b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize = 0x10;
137b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
138b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  table.Add("Foo");
139b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  table.Add("Bar");
140b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Can't use AddElf32Sym because it puts in a valid string offset.
141b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  section
142b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32((uint32_t)table.Here().Value() + 1)
143b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32(kFuncAddr)
144b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32(kFuncSize)
145b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D8(ELF32_ST_INFO(STB_GLOBAL, STT_FUNC))
146b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D8(0) // other
147b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D16(SHN_UNDEF + 1);
148b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
149b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
150b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
151b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
152b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
153b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
154b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
155b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
156b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
157b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, NonTerminatedStringTable) {
158b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "";
159b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr = 0x1000;
160b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize = 0x10;
161b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
162b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  table.Add("Foo");
163b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  table.Add("Bar");
164b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Add a non-null-terminated string to the end of the string table
165b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Label l;
166b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  table
167b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .Mark(&l)
168b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .Append("Unterminated");
169b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Can't use AddElf32Sym because it puts in a valid string offset.
170b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  section
171b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32((uint32_t)l.Value())
172b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32(kFuncAddr)
173b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D32(kFuncSize)
174b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D8(ELF32_ST_INFO(STB_GLOBAL, STT_FUNC))
175b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D8(0) // other
176b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    .D16(SHN_UNDEF + 1);
177b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
178b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
179b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
180b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
181b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
182b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
183b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
184b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
185b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
186b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, MultipleFuncs) {
187b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName1 = "superfunc";
188b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr1 = 0x10001000;
189b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize1 = 0x10;
190b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName2 = "awesomefunc";
191b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr2 = 0x20002000;
192b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize2 = 0x2f;
193b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName3 = "megafunc";
194b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr3 = 0x30003000;
195b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize3 = 0x3c;
196b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
197b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym(kFuncName1, kFuncAddr1, kFuncSize1,
198b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
199b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
200b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
201b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym(kFuncName2, kFuncAddr2, kFuncSize2,
202b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
203b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
204b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 2);
205b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym(kFuncName3, kFuncAddr3, kFuncSize3,
206b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_LOCAL, STT_FUNC),
207b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
208b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 3);
209b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
210b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
211b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
212b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)3, externs.size());
213b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
214b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName1, extern1->name);
215b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr1, extern1->address);
216b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern2 = externs[1];
217b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName2, extern2->name);
218b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr2, extern2->address);
219b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern3 = externs[2];
220b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName3, extern3->name);
221b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr3, extern3->address);
222b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
223b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
224b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest32, SkipStuff) {
225b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "superfunc";
226b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncAddr = 0x1000;
227b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint32_t kFuncSize = 0x10;
228b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
229b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Should skip functions in SHN_UNDEF
230b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym("skipme", 0xFFFF, 0x10,
231b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
232b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF);
233b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym(kFuncName, kFuncAddr, kFuncSize,
234b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
235b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
236b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
237b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Should skip non-STT_FUNC entries.
238b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf32Sym("skipmetoo", 0xAAAA, 0x10,
239b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF32_ST_INFO(STB_GLOBAL, STT_FILE),
240b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
241b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
242b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
243b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
244b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
245b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
246b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
247b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
248b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
249b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
250b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Run all the 32-bit tests with both endianness
251b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekINSTANTIATE_TEST_CASE_P(Endian,
252b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                        ELFSymbolsToModuleTest32,
253b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                        ::testing::Values(kLittleEndian, kBigEndian));
254b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
255b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Similar tests, but with 64-bit values. Ostensibly this could be
256b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// shoehorned into the parameterization by using ::testing::Combine,
257b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// but that would make it difficult to get the types right since these
258b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// actual test cases aren't parameterized. This could also be written
259b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// as a type-parameterized test, but combining that with a value-parameterized
260b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// test seemed really ugly, and also makes it harder to test 64-bit
261b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// values.
262b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekclass ELFSymbolsToModuleTest64 : public ELFSymbolsToModuleTestFixture,
263b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                                 public TestWithParam<Endianness>  {
264b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekpublic:
265b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ELFSymbolsToModuleTest64() : ELFSymbolsToModuleTestFixture(GetParam(), 8) {}
266b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
267b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  void AddElf64Sym(const string& name, uint64_t value,
268b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                   uint64_t size, unsigned info, uint16_t shndx) {
269b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek    section
270b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D32(table.Add(name))
271b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D8(info)
272b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D8(0) // other
273b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D16(shndx)
274b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D64(value)
275b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek      .D64(size);
276b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  }
277b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek};
278b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
279b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest64, NoFuncs) {
280b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
281b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
282b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)0, externs.size());
283b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
284b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
285b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest64, OneFunc) {
286b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "superfunc";
287b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncAddr = 0x1000200030004000ULL;
288b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncSize = 0x1000;
289b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
290b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym(kFuncName, kFuncAddr, kFuncSize,
291b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_GLOBAL, STT_FUNC),
292b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
293b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
294b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
295b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
296b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
297b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
298b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
299b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
300b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
301b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
302b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
303b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest64, MultipleFuncs) {
304b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName1 = "superfunc";
305b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncAddr1 = 0x1000100010001000ULL;
306b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncSize1 = 0x1000;
307b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName2 = "awesomefunc";
308b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncAddr2 = 0x2000200020002000ULL;
309b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncSize2 = 0x2f00;
310b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName3 = "megafunc";
311b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncAddr3 = 0x3000300030003000ULL;
312b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncSize3 = 0x3c00;
313b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
314b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym(kFuncName1, kFuncAddr1, kFuncSize1,
315b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_GLOBAL, STT_FUNC),
316b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
317b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
318b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym(kFuncName2, kFuncAddr2, kFuncSize2,
319b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_LOCAL, STT_FUNC),
320b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
321b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 2);
322b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym(kFuncName3, kFuncAddr3, kFuncSize3,
323b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_LOCAL, STT_FUNC),
324b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
325b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 3);
326b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
327b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
328b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
329b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)3, externs.size());
330b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
331b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName1, extern1->name);
332b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr1, extern1->address);
333b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern2 = externs[1];
334b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName2, extern2->name);
335b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr2, extern2->address);
336b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern3 = externs[2];
337b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName3, extern3->name);
338b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr3, extern3->address);
339b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
340b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
341b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekTEST_P(ELFSymbolsToModuleTest64, SkipStuff) {
342b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const string kFuncName = "superfunc";
343b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncAddr = 0x1000100010001000ULL;
344b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  const uint64_t kFuncSize = 0x1000;
345b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
346b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Should skip functions in SHN_UNDEF
347b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym("skipme", 0xFFFF, 0x10,
348b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_GLOBAL, STT_FUNC),
349b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF);
350b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym(kFuncName, kFuncAddr, kFuncSize,
351b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_GLOBAL, STT_FUNC),
352b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              // Doesn't really matter, just can't be SHN_UNDEF.
353b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
354b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  // Should skip non-STT_FUNC entries.
355b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  AddElf64Sym("skipmetoo", 0xAAAA, 0x10,
356b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              ELF64_ST_INFO(STB_GLOBAL, STT_FILE),
357b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek              SHN_UNDEF + 1);
358b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
359b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ProcessSection();
360b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
361b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  ASSERT_EQ((size_t)1, externs.size());
362b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  Module::Extern *extern1 = externs[0];
363b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ(kFuncName, extern1->name);
364b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek  EXPECT_EQ((Module::Address)kFuncAddr, extern1->address);
365b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek}
366b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek
367b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek// Run all the 64-bit tests with both endianness
368b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarekINSTANTIATE_TEST_CASE_P(Endian,
369b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                        ELFSymbolsToModuleTest64,
370b2f96f314ca9bc2f7307216e61794683a482deaated.mielczarek                        ::testing::Values(kLittleEndian, kBigEndian));
371