1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
base / profiler / chrome_unwind_info_android_32_unittest.cc [blame]
// 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 <tuple>
#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 <class T,
size_t E1,
size_t E2,
typename InternalPtrType1,
typename InternalPtrType2>
void ExpectSpanSizeAndContentsEqual(span<T, E1, InternalPtrType1> actual,
span<T, E2, InternalPtrType2> 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<const uint8_t*>(&unwind_info.page_table[0]));
ASSERT_EQ(&data[128],
reinterpret_cast<const uint8_t*>(&unwind_info.function_table[0]));
ASSERT_EQ(&data[192], reinterpret_cast<const uint8_t*>(
&unwind_info.function_offset_table[0]));
ASSERT_EQ(&data[256], reinterpret_cast<const uint8_t*>(
&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