// Copyright 2019 The Chromium 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 "base/profiler/chrome_unwind_info_android.h" #include #include "base/test/gtest_util.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { bool operator==(const FunctionTableEntry& e1, const FunctionTableEntry& e2) { return std::tie(e1.function_start_address_page_instruction_offset, e1.function_offset_table_byte_index) == std::tie(e2.function_start_address_page_instruction_offset, e2.function_offset_table_byte_index); } template void ExpectSpanSizeAndContentsEqual(span actual, span expected) { EXPECT_EQ(actual.size(), expected.size()); if (actual.size() != expected.size()) { return; } for (size_t i = 0; i < actual.size(); i++) { EXPECT_EQ(actual[i], expected[i]); } } TEST(ChromeUnwindInfoAndroidTest, CreateUnwindInfo) { ChromeUnwindInfoHeaderAndroid header = { /* page_table_byte_offset */ 64, /* page_table_entries */ 1, /* function_table_byte_offset */ 128, /* function_table_entries */ 2, /* function_offset_table_byte_offset */ 192, /* function_offset_table_size_in_bytes */ 3, /* unwind_instruction_table_byte_offset */ 256, /* unwind_instruction_table_size_in_bytes */ 4, }; uint8_t data[512] = {}; // Note: `CreateChromeUnwindInfoAndroid` is not expected to verify the content // of each unwind table. const uint32_t page_table[] = {1}; const FunctionTableEntry function_table[] = {{0, 2}, {0, 3}}; const uint8_t function_offset_table[] = {3, 3, 3}; const uint8_t unwind_instruction_table[] = {4, 4, 4, 4}; ASSERT_LT(sizeof(ChromeUnwindInfoHeaderAndroid), 64ul); memcpy(&data[0], &header, sizeof(ChromeUnwindInfoHeaderAndroid)); memcpy(&data[header.page_table_byte_offset], page_table, sizeof(page_table)); memcpy(&data[header.function_table_byte_offset], function_table, sizeof(function_table)); memcpy(&data[header.function_offset_table_byte_offset], function_offset_table, sizeof(function_offset_table)); memcpy(&data[header.unwind_instruction_table_byte_offset], unwind_instruction_table, sizeof(unwind_instruction_table)); ChromeUnwindInfoAndroid unwind_info = CreateChromeUnwindInfoAndroid(data); ASSERT_EQ(&data[64], reinterpret_cast(&unwind_info.page_table[0])); ASSERT_EQ(&data[128], reinterpret_cast(&unwind_info.function_table[0])); ASSERT_EQ(&data[192], reinterpret_cast( &unwind_info.function_offset_table[0])); ASSERT_EQ(&data[256], reinterpret_cast( &unwind_info.unwind_instruction_table[0])); ExpectSpanSizeAndContentsEqual(unwind_info.page_table, make_span(page_table)); ExpectSpanSizeAndContentsEqual(unwind_info.function_table, make_span(function_table)); ExpectSpanSizeAndContentsEqual(unwind_info.function_offset_table, make_span(function_offset_table)); ExpectSpanSizeAndContentsEqual(unwind_info.unwind_instruction_table, make_span(unwind_instruction_table)); } } // namespace base