blob: 55a6d3e2a0af2521e8576449378cc346d7cb39d3 [file] [log] [blame]
// 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_