// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifdef UNSAFE_BUFFERS_BUILD // TODO(crbug.com/40284755): Remove this and use spans. #pragma allow_unsafe_buffers #endif #include "base/profiler/chrome_unwind_info_android_32.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(ChromeUnwindInfoAndroid32Test, CreateUnwindInfo) { ChromeUnwindInfoAndroid32Header 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: `CreateChromeUnwindInfoAndroid32` 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(ChromeUnwindInfoAndroid32Header), 64ul); memcpy(&data[0], &header, sizeof(ChromeUnwindInfoAndroid32Header)); 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)); ChromeUnwindInfoAndroid32 unwind_info = CreateChromeUnwindInfoAndroid32(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, span(page_table)); ExpectSpanSizeAndContentsEqual(unwind_info.function_table, span(function_table)); ExpectSpanSizeAndContentsEqual(unwind_info.function_offset_table, span(function_offset_table)); ExpectSpanSizeAndContentsEqual(unwind_info.unwind_instruction_table, span(unwind_instruction_table)); } } // namespace base