1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/profiler/chrome_unwind_info_android.h"
6
7 #include <tuple>
8
9 #include "base/test/gtest_util.h"
10 #include "build/build_config.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace base {
14
operator ==(const FunctionTableEntry & e1,const FunctionTableEntry & e2)15 bool operator==(const FunctionTableEntry& e1, const FunctionTableEntry& e2) {
16 return std::tie(e1.function_start_address_page_instruction_offset,
17 e1.function_offset_table_byte_index) ==
18 std::tie(e2.function_start_address_page_instruction_offset,
19 e2.function_offset_table_byte_index);
20 }
21
22 template <class T, size_t E1, size_t E2>
ExpectSpanSizeAndContentsEqual(span<T,E1> actual,span<T,E2> expected)23 void ExpectSpanSizeAndContentsEqual(span<T, E1> actual, span<T, E2> expected) {
24 EXPECT_EQ(actual.size(), expected.size());
25 if (actual.size() != expected.size()) {
26 return;
27 }
28
29 for (size_t i = 0; i < actual.size(); i++) {
30 EXPECT_EQ(actual[i], expected[i]);
31 }
32 }
33
TEST(ChromeUnwindInfoAndroidTest,CreateUnwindInfo)34 TEST(ChromeUnwindInfoAndroidTest, CreateUnwindInfo) {
35 ChromeUnwindInfoHeaderAndroid header = {
36 /* page_table_byte_offset */ 64,
37 /* page_table_entries */ 1,
38
39 /* function_table_byte_offset */ 128,
40 /* function_table_entries */ 2,
41
42 /* function_offset_table_byte_offset */ 192,
43 /* function_offset_table_size_in_bytes */ 3,
44
45 /* unwind_instruction_table_byte_offset */ 256,
46 /* unwind_instruction_table_size_in_bytes */ 4,
47 };
48
49 uint8_t data[512] = {};
50 // Note: `CreateChromeUnwindInfoAndroid` is not expected to verify the content
51 // of each unwind table.
52 const uint32_t page_table[] = {1};
53 const FunctionTableEntry function_table[] = {{0, 2}, {0, 3}};
54 const uint8_t function_offset_table[] = {3, 3, 3};
55 const uint8_t unwind_instruction_table[] = {4, 4, 4, 4};
56
57 ASSERT_LT(sizeof(ChromeUnwindInfoHeaderAndroid), 64ul);
58 memcpy(&data[0], &header, sizeof(ChromeUnwindInfoHeaderAndroid));
59
60 memcpy(&data[header.page_table_byte_offset], page_table, sizeof(page_table));
61 memcpy(&data[header.function_table_byte_offset], function_table,
62 sizeof(function_table));
63 memcpy(&data[header.function_offset_table_byte_offset], function_offset_table,
64 sizeof(function_offset_table));
65 memcpy(&data[header.unwind_instruction_table_byte_offset],
66 unwind_instruction_table, sizeof(unwind_instruction_table));
67
68 ChromeUnwindInfoAndroid unwind_info = CreateChromeUnwindInfoAndroid(data);
69
70 ASSERT_EQ(&data[64],
71 reinterpret_cast<const uint8_t*>(&unwind_info.page_table[0]));
72 ASSERT_EQ(&data[128],
73 reinterpret_cast<const uint8_t*>(&unwind_info.function_table[0]));
74 ASSERT_EQ(&data[192], reinterpret_cast<const uint8_t*>(
75 &unwind_info.function_offset_table[0]));
76 ASSERT_EQ(&data[256], reinterpret_cast<const uint8_t*>(
77 &unwind_info.unwind_instruction_table[0]));
78
79 ExpectSpanSizeAndContentsEqual(unwind_info.page_table, make_span(page_table));
80 ExpectSpanSizeAndContentsEqual(unwind_info.function_table,
81 make_span(function_table));
82 ExpectSpanSizeAndContentsEqual(unwind_info.function_offset_table,
83 make_span(function_offset_table));
84 ExpectSpanSizeAndContentsEqual(unwind_info.unwind_instruction_table,
85 make_span(unwind_instruction_table));
86 }
87
88 } // namespace base
89