// Copyright (c) 2011 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Ted Mielczarek <ted.mielczarek@gmail.com>

// dump_symbols_unittest.cc:
// Unittests for google_breakpad::DumpSymbols

#include <elf.h>
#include <link.h>
#include <stdio.h>

#include <sstream>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "common/linux/elf_gnu_compat.h"
#include "common/linux/elfutils.h"
#include "common/linux/dump_symbols.h"
#include "common/linux/synth_elf.h"
#include "common/module.h"
#include "common/using_std_string.h"

namespace google_breakpad {

bool ReadSymbolDataInternal(const uint8_t* obj_file,
                            const string& obj_filename,
                            const std::vector<string>& debug_dir,
                            const DumpOptions& options,
                            Module** module);

using google_breakpad::synth_elf::ELF;
using google_breakpad::synth_elf::Notes;
using google_breakpad::synth_elf::StringTable;
using google_breakpad::synth_elf::SymbolTable;
using google_breakpad::test_assembler::kLittleEndian;
using google_breakpad::test_assembler::Section;
using std::stringstream;
using std::vector;
using ::testing::Test;
using ::testing::Types;

template<typename ElfClass>
class DumpSymbols : public Test {
 public:
  void GetElfContents(ELF& elf) {
    string contents;
    ASSERT_TRUE(elf.GetContents(&contents));
    ASSERT_LT(0U, contents.size());

    elfdata_v.clear();
    elfdata_v.insert(elfdata_v.begin(), contents.begin(), contents.end());
    elfdata = &elfdata_v[0];
  }

  vector<uint8_t> elfdata_v;
  uint8_t* elfdata;
};

typedef Types<ElfClass32, ElfClass64> ElfClasses;

TYPED_TEST_SUITE(DumpSymbols, ElfClasses);

TYPED_TEST(DumpSymbols, Invalid) {
  Elf32_Ehdr header;
  memset(&header, 0, sizeof(header));
  Module* module;
  DumpOptions options(ALL_SYMBOL_DATA, true);
  EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(&header),
                                      "foo",
                                      vector<string>(),
                                      options,
                                      &module));
}

TYPED_TEST(DumpSymbols, SimplePublic) {
  ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian);
  // Zero out text section for simplicity.
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);

  // Add a public symbol.
  StringTable table(kLittleEndian);
  SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table);
  syms.AddSymbol("superfunc",
                   (typename TypeParam::Addr)0x1000,
                   (typename TypeParam::Addr)0x10,
                 // ELF32_ST_INFO works for 32-or 64-bit.
                 ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
                 SHN_UNDEF + 1);
  int index = elf.AddSection(".dynstr", table, SHT_STRTAB);
  elf.AddSection(".dynsym", syms,
                 SHT_DYNSYM,          // type
                 SHF_ALLOC,           // flags
                 0,                   // addr
                 index,               // link
                 sizeof(typename TypeParam::Sym));  // entsize

  elf.Finish();
  this->GetElfContents(elf);

  Module* module;
  DumpOptions options(ALL_SYMBOL_DATA, true);
  EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata,
                                     "foo",
                                     vector<string>(),
                                     options,
                                     &module));

  stringstream s;
  module->Write(s, ALL_SYMBOL_DATA);
  const string expected =
    string("MODULE Linux ") + TypeParam::kMachineName
    + " 000000000000000000000000000000000 foo\n"
    "INFO CODE_ID 00000000000000000000000000000000\n"
    "PUBLIC 1000 0 superfunc\n";
  EXPECT_EQ(expected, s.str());
  delete module;
}

TYPED_TEST(DumpSymbols, SimpleBuildID) {
  ELF elf(TypeParam::kMachine, TypeParam::kClass, kLittleEndian);
  // Zero out text section for simplicity.
  Section text(kLittleEndian);
  text.Append(4096, 0);
  elf.AddSection(".text", text, SHT_PROGBITS);

  // Add a Build ID
  const uint8_t kExpectedIdentifierBytes[] =
    {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     0x10, 0x11, 0x12, 0x13};
  Notes notes(kLittleEndian);
  notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
                sizeof(kExpectedIdentifierBytes));
  elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);

  // Add a public symbol.
  StringTable table(kLittleEndian);
  SymbolTable syms(kLittleEndian, TypeParam::kAddrSize, table);
  syms.AddSymbol("superfunc",
                   (typename TypeParam::Addr)0x1000,
                   (typename TypeParam::Addr)0x10,
                 // ELF32_ST_INFO works for 32-or 64-bit.
                 ELF32_ST_INFO(STB_GLOBAL, STT_FUNC),
                 SHN_UNDEF + 1);
  int index = elf.AddSection(".dynstr", table, SHT_STRTAB);
  elf.AddSection(".dynsym", syms,
                 SHT_DYNSYM,          // type
                 SHF_ALLOC,           // flags
                 0,                   // addr
                 index,               // link
                 sizeof(typename TypeParam::Sym));  // entsize

  elf.Finish();
  this->GetElfContents(elf);

  Module* module;
  DumpOptions options(ALL_SYMBOL_DATA, true);
  EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata,
                                     "foo",
                                     vector<string>(),
                                     options,
                                     &module));

  stringstream s;
  module->Write(s, ALL_SYMBOL_DATA);
  const string expected =
    string("MODULE Linux ") + TypeParam::kMachineName
    + " 030201000504070608090A0B0C0D0E0F0 foo\n"
    "INFO CODE_ID 000102030405060708090A0B0C0D0E0F10111213\n"
    "PUBLIC 1000 0 superfunc\n";
  EXPECT_EQ(expected, s.str());
  delete module;
}

}  // namespace google_breakpad
