blob: fc5e81d01925cc16d481fcf9bec5eac8514b513b [file] [log] [blame]
// Copyright 2025 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 "src/lib/unwinder/arm_ehabi_module.h"
#include <cstdint>
#include <filesystem>
#include <limits>
#include <gtest/gtest.h>
#include "src/lib/unwinder/memory.h"
namespace {
#ifdef __Fuchsia__
constexpr char file_path[] = "/pkg/testdata/libunwind_info_test_data.targetso";
#else
constexpr char file_path[] = "test_data/unwinder/libunwind_info_test_data.targetso";
#endif
std::string GetTestFilePath() {
std::string ret;
#ifdef __Fuchsia__
ret = file_path;
#else
char fullpath[PATH_MAX];
realpath("/proc/self/exe", fullpath);
std::filesystem::path self_path = fullpath;
ret = self_path.parent_path() / file_path;
#endif
return ret;
}
} // namespace
namespace unwinder {
// This tests the upper bounds searching algorithm with a curated binary. It is important to use the
// checked in binary so the addresses don't change. If changes are made to the test data source
// file the checked in file also needs to be updated.
TEST(ArmEhAbiModule, Search) {
// This only works if p_offset == p_vaddr in the elf file.
FileMemory memory(GetTestFilePath());
ArmEhAbiModule module(&memory, 0);
ASSERT_TRUE(module.Load().ok());
ArmEhAbiModule::IdxHeader entry;
// Test with an address below all of the entries. This is an error.
Error error = module.Search(0, entry);
ASSERT_TRUE(error.has_err());
// Test with an address above all of the entries. This won't return an error, but instead will
// return the last entry in the table.
error = module.Search(std::numeric_limits<uint32_t>::max(), entry);
ASSERT_TRUE(error.ok());
EXPECT_EQ(entry.header.fn_addr, 0x160A4u);
// This should get us the specific entry with a function address at 0x11FAC and compact inline
// representation.
error = module.Search(0x11FB0, entry);
ASSERT_TRUE(error.ok());
EXPECT_EQ(entry.header.fn_addr, 0x11FACu);
EXPECT_EQ(entry.type, ArmEhAbiModule::IdxHeader::Type::kCompactInline);
// This should get us the specific entry with a function address at 0x13284 and an offset to the
// .ARM.extab section with the unwinding instructions.
error = module.Search(0x13290, entry);
ASSERT_TRUE(error.ok());
EXPECT_EQ(entry.header.fn_addr, 0x13284u);
EXPECT_EQ(entry.type, ArmEhAbiModule::IdxHeader::Type::kCompact);
}
} // namespace unwinder