blob: 16da068891a4703b4d944fb9005aa852709e225a [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/bin/zxdb/expr/resolve_array.h"
#include "garnet/bin/zxdb/common/err.h"
#include "garnet/bin/zxdb/common/test_with_loop.h"
#include "garnet/bin/zxdb/expr/expr_value.h"
#include "garnet/bin/zxdb/symbols/array_type.h"
#include "garnet/bin/zxdb/symbols/base_type.h"
#include "garnet/bin/zxdb/symbols/mock_symbol_data_provider.h"
#include "garnet/bin/zxdb/symbols/modified_type.h"
#include "gtest/gtest.h"
namespace zxdb {
namespace {
class ResolveArrayTest : public TestWithLoop {};
} // namespace
TEST_F(ResolveArrayTest, ResolveStatic) {
auto data_provider = fxl::MakeRefCounted<MockSymbolDataProvider>();
// Request 3 elements from 1-4.
constexpr uint64_t kBaseAddress = 0x100000;
constexpr uint32_t kBeginIndex = 1;
constexpr uint32_t kEndIndex = 4;
// Array holds 3 uint16_t.
constexpr uint32_t kTypeSize = 2;
auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned,
kTypeSize, "uint16_t");
auto array_type = fxl::MakeRefCounted<ArrayType>(elt_type, 3);
// Values are 0x1122, 0x3344, 0x5566
std::vector<uint8_t> array_bytes = {0x22, 0x11, 0x44, 0x33, 0x66, 0x55};
ExprValue value(array_type, array_bytes, ExprValueSource(kBaseAddress));
std::vector<ExprValue> result;
Err err = ResolveArray(value, kBeginIndex, kEndIndex, &result);
EXPECT_FALSE(err.has_error());
// Should have returned two values (the overlap of the array and the
// requested range).
ASSERT_EQ(2u, result.size());
EXPECT_EQ(elt_type.get(), result[0].type());
EXPECT_EQ(0x3344, result[0].GetAs<uint16_t>());
EXPECT_EQ(kBaseAddress + kTypeSize, result[0].source().address());
EXPECT_EQ(elt_type.get(), result[1].type());
EXPECT_EQ(0x5566, result[1].GetAs<uint16_t>());
EXPECT_EQ(kBaseAddress + kTypeSize * 2, result[1].source().address());
}
// Resolves an array element with a pointer as the base.
TEST_F(ResolveArrayTest, ResolvePointer) {
auto data_provider = fxl::MakeRefCounted<MockSymbolDataProvider>();
// Request 3 elements from 1-4.
constexpr uint64_t kBaseAddress = 0x100000;
constexpr uint32_t kBeginIndex = 1;
constexpr uint32_t kEndIndex = 4;
// Array holds 3 uint16_t.
constexpr uint32_t kTypeSize = 2;
auto elt_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned,
kTypeSize, "uint16_t");
auto ptr_type = fxl::MakeRefCounted<ModifiedType>(Symbol::kTagPointerType,
LazySymbol(elt_type));
// Create memory with two values 0x3344, 0x5566. Note that these are offset
// one value from the beginning of the array so the requested address of the
// kBeginIndex'th element matches this address.
constexpr uint64_t kBeginAddress = kBaseAddress + kBeginIndex * kTypeSize;
data_provider->AddMemory(kBeginAddress, {0x44, 0x33, 0x66, 0x55});
// Data in the value is the pointer to the beginning of the array.
ExprValue value(ptr_type, {0, 0, 0x10, 0, 0, 0, 0, 0});
bool called = false;
Err out_err;
std::vector<ExprValue> result;
ResolveArray(data_provider, value, kBeginIndex, kEndIndex,
[&called, &out_err, &result](const Err& err,
std::vector<ExprValue> values) {
called = true;
out_err = err;
result = std::move(values);
debug_ipc::MessageLoop::Current()->QuitNow();
});
// Should be called async.
EXPECT_FALSE(called);
loop().Run();
EXPECT_TRUE(called);
// Should have returned two values (the overlap of the array and the
// requested range).
ASSERT_EQ(2u, result.size());
EXPECT_EQ(elt_type.get(), result[0].type());
EXPECT_EQ(0x3344, result[0].GetAs<uint16_t>());
EXPECT_EQ(kBaseAddress + kTypeSize, result[0].source().address());
EXPECT_EQ(elt_type.get(), result[1].type());
EXPECT_EQ(0x5566, result[1].GetAs<uint16_t>());
EXPECT_EQ(kBaseAddress + kTypeSize * 2, result[1].source().address());
}
} // namespace zxdb