// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/elf_loader/dynamic_section.h"

#include "starboard/common/scoped_ptr.h"
#include "starboard/string.h"
#include "testing/gtest/include/gtest/gtest.h"

#if SB_API_VERSION >= 12 &&                                         \
    (SB_API_VERSION >= SB_MMAP_REQUIRED_VERSION || SB_HAS(MMAP)) && \
    SB_CAN(MAP_EXECUTABLE_MEMORY)

namespace starboard {
namespace elf_loader {

namespace {

class DynamicSectionTest : public ::testing::Test {
 protected:
  DynamicSectionTest() {}
  ~DynamicSectionTest() {}
};

typedef struct DynamicSectionMemory {
  Dyn dynamic_table_[3];
  linker_function_t init_array_[2];
  linker_function_t fini_array_[2];
  Sym symbol_table_[2];
  char string_table_[128];
} DynamicSectionMemory;

bool gInitCalled = false;
bool gCtor1Called = false;
bool gCtor2Called = false;
bool gDtor1Called = false;
bool gDtor2Called = false;

void InitFunction() {
  gInitCalled = true;
}

void TestConstructor1() {
  gCtor1Called = true;
}

void TestConstructor2() {
  gCtor2Called = true;
}

void TestDestructor1() {
  gDtor1Called = true;
}

void TestDestructor2() {
  gDtor2Called = true;
}

TEST_F(DynamicSectionTest, Initialize) {
  Addr addr = 0x1234;
  Dyn dynamic_table[3];
  Word flags = 0;

  DynamicSection d(addr, dynamic_table, 3, flags);
  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_table, d.GetDynamicTable());
  ASSERT_EQ(3, d.GetDynamicTableSize());
}

TEST_F(DynamicSectionTest, CallInit) {
  Word flags = 0;
  DynamicSectionMemory dynamic_section_memory;
  Addr base_addr = reinterpret_cast<Addr>(&dynamic_section_memory);
  dynamic_section_memory.dynamic_table_[0].d_tag = DT_INIT;
  dynamic_section_memory.dynamic_table_[0].d_un.d_ptr =
      reinterpret_cast<Addr>(InitFunction) - base_addr;

  DynamicSection d(base_addr, dynamic_section_memory.dynamic_table_, 1, flags);
  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_section_memory.dynamic_table_, d.GetDynamicTable());
  ASSERT_EQ(1, d.GetDynamicTableSize());
  d.CallConstructors();
  ASSERT_TRUE(gInitCalled);
}

TEST_F(DynamicSectionTest, CallConstructors) {
  Word flags = 0;
  DynamicSectionMemory dynamic_section_memory;
  Addr base_addr = reinterpret_cast<Addr>(&dynamic_section_memory);

  dynamic_section_memory.init_array_[0] =
      reinterpret_cast<linker_function_t>(&TestConstructor1);
  dynamic_section_memory.init_array_[1] =
      reinterpret_cast<linker_function_t>(&TestConstructor2);

  dynamic_section_memory.dynamic_table_[0].d_tag = DT_INIT_ARRAY;
  dynamic_section_memory.dynamic_table_[0].d_un.d_ptr =
      reinterpret_cast<Addr>(dynamic_section_memory.init_array_) - base_addr;

  dynamic_section_memory.dynamic_table_[1].d_tag = DT_INIT_ARRAYSZ;
  dynamic_section_memory.dynamic_table_[1].d_un.d_val =
      sizeof(dynamic_section_memory.init_array_);

  DynamicSection d(base_addr, dynamic_section_memory.dynamic_table_, 2, flags);
  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_section_memory.dynamic_table_, d.GetDynamicTable());
  ASSERT_EQ(2, d.GetDynamicTableSize());
  d.CallConstructors();
  ASSERT_TRUE(gCtor1Called);
  ASSERT_TRUE(gCtor2Called);
}

TEST_F(DynamicSectionTest, CallDestructors) {
  Word flags = 0;
  DynamicSectionMemory dynamic_section_memory;
  Addr base_addr = reinterpret_cast<Addr>(&dynamic_section_memory);

  dynamic_section_memory.fini_array_[0] =
      reinterpret_cast<linker_function_t>(&TestDestructor1);
  dynamic_section_memory.fini_array_[1] =
      reinterpret_cast<linker_function_t>(&TestDestructor2);

  dynamic_section_memory.dynamic_table_[0].d_tag = DT_FINI_ARRAY;
  dynamic_section_memory.dynamic_table_[0].d_un.d_ptr =
      reinterpret_cast<Addr>(dynamic_section_memory.fini_array_) - base_addr;

  dynamic_section_memory.dynamic_table_[1].d_tag = DT_FINI_ARRAYSZ;
  dynamic_section_memory.dynamic_table_[1].d_un.d_val =
      sizeof(dynamic_section_memory.fini_array_);

  DynamicSection d(base_addr, dynamic_section_memory.dynamic_table_, 2, flags);
  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_section_memory.dynamic_table_, d.GetDynamicTable());
  ASSERT_EQ(2, d.GetDynamicTableSize());
  d.CallDestructors();
  ASSERT_TRUE(gDtor1Called);
  ASSERT_TRUE(gDtor2Called);
}

TEST_F(DynamicSectionTest, LookupById) {
  Word flags = 0;
  DynamicSectionMemory dynamic_section_memory;
  Addr base_addr = reinterpret_cast<Addr>(&dynamic_section_memory);

  dynamic_section_memory.dynamic_table_[0].d_tag = DT_SYMTAB;
  dynamic_section_memory.dynamic_table_[0].d_un.d_ptr =
      reinterpret_cast<Addr>(dynamic_section_memory.symbol_table_) - base_addr;

  DynamicSection d(base_addr, dynamic_section_memory.dynamic_table_, 1, flags);

  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_section_memory.dynamic_table_, d.GetDynamicTable());
  ASSERT_EQ(1, d.GetDynamicTableSize());
  ASSERT_EQ(dynamic_section_memory.symbol_table_, d.LookupById(0));
  ASSERT_EQ(dynamic_section_memory.symbol_table_ + 1, d.LookupById(1));
}

TEST_F(DynamicSectionTest, LookupNameById) {
  Word flags = 0;
  DynamicSectionMemory dynamic_section_memory;
  Addr base_addr = reinterpret_cast<Addr>(&dynamic_section_memory);

  dynamic_section_memory.dynamic_table_[0].d_tag = DT_SYMTAB;
  dynamic_section_memory.dynamic_table_[0].d_un.d_ptr =
      reinterpret_cast<Addr>(dynamic_section_memory.symbol_table_) - base_addr;

  dynamic_section_memory.dynamic_table_[1].d_tag = DT_STRTAB;
  dynamic_section_memory.dynamic_table_[1].d_un.d_ptr =
      reinterpret_cast<Addr>(dynamic_section_memory.string_table_) - base_addr;

  SbMemoryCopy(dynamic_section_memory.string_table_, "test1\x00test2\x00", 12);

  dynamic_section_memory.symbol_table_[0].st_name = 0;  // the offset of test1
  dynamic_section_memory.symbol_table_[1].st_name = 6;  // the offset of test2

  DynamicSection d(base_addr, dynamic_section_memory.dynamic_table_, 2, flags);

  ASSERT_TRUE(d.InitDynamicSection());

  ASSERT_EQ(dynamic_section_memory.dynamic_table_, d.GetDynamicTable());
  ASSERT_EQ(2, d.GetDynamicTableSize());

  ASSERT_EQ(0, SbStringCompareAll("test1", d.LookupNameById(0)));
  ASSERT_EQ(0, SbStringCompareAll("test2", d.LookupNameById(1)));
}

}  // namespace
}  // namespace elf_loader
}  // namespace starboard
#endif  // SB_API_VERSION >= 12 && (SB_API_VERSION >= SB_MMAP_REQUIRED_VERSION
        // || SB_HAS(MMAP)) && SB_CAN(MAP_EXECUTABLE_MEMORY)
