// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_ELFLDLTL_SYMBOL_TESTS_H_
#define SRC_LIB_ELFLDLTL_SYMBOL_TESTS_H_

#include <lib/elfldltl/symbol.h>

#include <string>
#include <string_view>
#include <vector>

#include "tests.h"

using namespace std::string_view_literals;

template <class Elf>
class TestSymtab {
 public:
  using Addr = typename Elf::Addr;
  using Half = typename Elf::Half;
  using Sym = typename Elf::Sym;

  uint32_t AddString(std::string_view str) {
    if (str.empty()) {
      return 0;
    }
    size_t offset = strtab_.size();
    strtab_ += str;
    strtab_ += '\0';
    return static_cast<uint32_t>(offset);
  }

  TestSymtab& AddSymbol(std::string_view name, Addr value, Addr size, elfldltl::ElfSymBind bind,
                        elfldltl::ElfSymType type, Half shndx) {
    Sym sym{};
    sym.name = AddString(name);
    sym.value = value;
    sym.size = size;
    sym.info = static_cast<uint8_t>((static_cast<uint8_t>(bind) << 4) |  //
                                    (static_cast<uint8_t>(type) << 0));
    sym.shndx = shndx;
    symtab_.push_back(sym);
    return *this;
  }

  void SetInfo(elfldltl::SymbolInfo<Elf>& si) const {
    si.set_symtab(symtab());
    si.set_strtab(strtab());
  }

  cpp20::span<const Sym> symtab() const { return {symtab_.data(), symtab_.size()}; }

  std::string_view strtab() const { return strtab_; }

 private:
  std::vector<Sym> symtab_{{}};
  std::string strtab_{'\0', 1};
};

inline constexpr std::string_view kFoobar = "foobar";
inline constexpr elfldltl::SymbolName kFoobarSymbol(kFoobar);

inline constexpr elfldltl::SymbolName kQuuxSymbol("quux"sv);
inline constexpr elfldltl::SymbolName kFooSymbol("foo"sv);
inline constexpr elfldltl::SymbolName kBarSymbol("bar"sv);
inline constexpr elfldltl::SymbolName kNotFoundSymbol("NotFound"sv);

template <class Elf>
inline const auto kTestSymbols =
    TestSymtab<Elf>()
        .AddSymbol(kQuuxSymbol, 0, 0, elfldltl::ElfSymBind::kGlobal, elfldltl::ElfSymType::kFunc, 0)
        .AddSymbol(kFooSymbol, 1, 1, elfldltl::ElfSymBind::kGlobal, elfldltl::ElfSymType::kFunc, 1)
        .AddSymbol(kBarSymbol, 2, 1, elfldltl::ElfSymBind::kGlobal, elfldltl::ElfSymType::kFunc, 1)
        .AddSymbol(kFoobarSymbol, 3, 1, elfldltl::ElfSymBind::kGlobal, elfldltl::ElfSymType::kFunc,
                   1);

// There is always a null entry at index 0, which is counted in the size.
constexpr size_t kTestSymbolCount = 5;

// DT_HASH data is always in the same format, modulo byte-swapping.
template <typename Word>
inline constexpr Word kTestCompatHash[] = {
    0x00000005, 0x00000005, 0x00000000, 0x00000000, 0x00000001, 0x00000004,
    0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
};

// 32-bit DT_GNU_HASH data looks the same after byte-swapping.
template <typename Addr>
inline constexpr Addr kTestGnuHash[] = {
    0x00000001, 0x00000002, 0x00000002, 0x0000001a, 0x00000204,
    0xc4000004, 0x00000002, 0x0b887388, 0x0b8860ba, 0xfde460bf,
};

// The 64-bit data isn't just byte-swapped, since some 64-bit words are
// actually pairs of 32-bit words and their relative order isn't swapped.
using Addr64BE = elfldltl::Elf64<elfldltl::ElfData::k2Msb>::Addr;
using Addr64LE = elfldltl::Elf64<elfldltl::ElfData::k2Lsb>::Addr;

template <typename Addr>
constexpr Addr WordPair(uint32_t first, uint32_t second) {
  if constexpr (std::is_same_v<Addr, Addr64BE>) {
    return (static_cast<uint64_t>(first) << 32) | second;
  } else {
    static_assert(std::is_same_v<Addr, Addr64LE>);
    return (static_cast<uint64_t>(second) << 32) | first;
  }
}

template <typename Addr>
constexpr auto MakeTestGnuHash64() {
  return std::array{
      WordPair<Addr>(0x00000001, 0x00000002),  // nbucket, bias
      WordPair<Addr>(0x00000001, 0x0000001a),  // nfilter, shift
      Addr{0xc400000000000204},                // Bloom filter words (64-bit)
      WordPair<Addr>(0x00000002, 0x0b887388),  // sole hash bucket, and ...
      WordPair<Addr>(0x0b8860ba, 0xfde460bf),  // chain table words
  };
}

template <>
inline constexpr auto kTestGnuHash<Addr64LE> = MakeTestGnuHash64<Addr64LE>();

template <>
inline constexpr auto kTestGnuHash<Addr64BE> = MakeTestGnuHash64<Addr64BE>();

#endif  // SRC_LIB_ELFLDLTL_SYMBOL_TESTS_H_
