blob: 10702aafd7e5e50a5974fdc32505fc46b395021f [file] [log] [blame]
// Copyright 2018 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.
#include "garnet/lib/elflib/elflib.h"
#include <algorithm>
#include <iterator>
#include "gtest/gtest.h"
namespace elflib {
namespace {
class TestMemoryAccessor : public ElfLib::MemoryAccessor {
public:
TestMemoryAccessor() {
PushData(Elf64_Ehdr {
.e_ident = { EI_MAG0, EI_MAG1, EI_MAG2, EI_MAG3 },
.e_version = 1,
.e_shoff = sizeof(Elf64_Ehdr),
.e_ehsize = sizeof(Elf64_Ehdr),
.e_shentsize = sizeof(Elf64_Shdr),
.e_shnum = 2,
.e_shstrndx = 0,
});
size_t shsymtab_hdr = PushData(Elf64_Shdr {
.sh_name = 1,
.sh_type = SHT_SYMTAB,
.sh_size = 18,
});
size_t stuff_hdr = PushData(Elf64_Shdr {
.sh_name = 2,
.sh_type = SHT_LOUSER,
.sh_size = 15,
});
DataAt<Elf64_Shdr>(shsymtab_hdr)->sh_offset = content_.size();
const uint8_t* shsymtab_content =
reinterpret_cast<const uint8_t*>("\0.shsymtab\0.stuff\0");
std::copy(shsymtab_content, shsymtab_content + 18,
std::back_inserter(content_));
DataAt<Elf64_Shdr>(stuff_hdr)->sh_offset = content_.size();
const uint8_t* stuff_content =
reinterpret_cast<const uint8_t*>("This is a test.");
std::copy(stuff_content, stuff_content + 15,
std::back_inserter(content_));
}
template<typename T>
T* DataAt(size_t offset) {
return reinterpret_cast<T*>(content_.data() + offset);
}
template<typename T>
size_t PushData(T data) {
uint8_t* start = reinterpret_cast<uint8_t*>(&data);
uint8_t* end = start + sizeof(data);
size_t offset = content_.size();
std::copy(start, end, std::back_inserter(content_));
return offset;
}
bool GetMemory(uint64_t offset, std::vector<uint8_t>* out) {
const auto& start_iter = content_.begin() + offset;
if (content_.size() < offset + out->size()) {
return false;
}
std::copy(start_iter, start_iter + out->size(), out->begin());
return true;
}
private:
std::vector<uint8_t> content_;
};
} // namespace
TEST(ElfLib, Create) {
std::unique_ptr<ElfLib> got;
EXPECT_NE(ElfLib::Create(std::make_unique<TestMemoryAccessor>()).get(),
nullptr);
}
TEST(ElfLib, GetSection) {
std::unique_ptr<ElfLib> elf =
ElfLib::Create(std::make_unique<TestMemoryAccessor>());
ASSERT_NE(elf.get(), nullptr);
auto data = elf->GetSectionData<uint8_t>(".stuff");
const uint8_t* expected_content =
reinterpret_cast<const uint8_t*>("This is a test.");
auto test = std::vector<uint8_t>(expected_content, expected_content + 15);
ASSERT_NE(data, nullptr);
EXPECT_EQ(test, *data);
}
} // namespace elflib