1 // Copyright 2021 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.
5 #ifndef BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_
6 #define BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_
10 #include "base/base_export.h"
11 #include "base/containers/span.h"
15 // Represents each entry in the function table (i.e. the second level of the
16 // function address table).
17 struct FunctionTableEntry {
18 // The offset into the 128kb page containing this function. Indexed by bits
19 // 1-16 of the pc offset from the start of the text section.
20 uint16_t function_start_address_page_instruction_offset;
22 // The byte index of the first offset for the function in the function
24 uint16_t function_offset_table_byte_index;
27 // The header at the start of the unwind info resource, with offsets/sizes for
28 // the tables contained within the resource.
30 // The unwind info provides 4 tables which can translate an instruction address
31 // to a set of unwind instructions to unwind the function frame the instruction
34 // `page_table` and `function_table` together locates which function the
35 // instruction address belongs to given an instruction address.
37 // `function_offset_table` and `unwind_instruction_table` together locates
38 // which sets of unwind instructions to execute given the function info
39 // obtained from `page_table` and `function_table`, and the offset between the
40 // instruction address and function start address.
43 // https://docs.google.com/document/d/1IYTmGCJZoiQ242xPUZX1fATD6ivsjU1TAt_fPv74ocs/edit?usp=sharing
44 struct BASE_EXPORT ChromeUnwindInfoHeaderAndroid {
45 // The offset in bytes from the start of the unwind info resource to the
46 // page table (i.e. the first level of the function address table). The page
47 // table represents discrete 128kb 'pages' of memory in the text section,
48 // each of which contains functions. The page table is indexed by bits 17
49 // and greater of the pc offset from the start of the text section.
50 // Indexing into page_table produces an index of function_table.
51 uint32_t page_table_byte_offset;
52 uint32_t page_table_entries;
54 // The offset in bytes from the start of the unwind info resource to the
55 // function table (i.e. the second level of the function address table). The
56 // function table represents the individual functions within a 128kb page.
57 // Each function is represented as a `FunctionTableEntry`. The relevant entry
58 // for a pc offset from the start of the text section is the one with the
59 // largest function_start_address_page_instruction_offset <= (pc_offset >> 1)
61 uint32_t function_table_byte_offset;
62 uint32_t function_table_entries;
64 // The offset in bytes from the start of the unwind info resource to the
65 // function offset table. The function offset table represents the pc
66 // offsets from the start of each function along with indices into the
67 // unwind instructions for the offsets. The pc offsets and unwind indices
68 // are represented as (ULEB128, ULEB128) pairs in decreasing order of
69 // offset. Distinct sequences of (offset, index) pairs are concatenated in
71 uint32_t function_offset_table_byte_offset;
72 uint32_t function_offset_table_size_in_bytes;
74 // The offset in bytes from the start of the unwind info resource to the
75 // unwind instruction table. The unwind instruction table represents
76 // distinct sequences of ARM compact unwind instructions[1] used across all
77 // functions in Chrome. The compact unwind instruction is a byte-oriented
78 // variable length encoding so is indexed by byte position.
79 // 1. See Exception handling ABI for the ARM architecture ABI, §9.3.
80 // https://developer.arm.com/documentation/ihi0038/b.
81 uint32_t unwind_instruction_table_byte_offset;
82 uint32_t unwind_instruction_table_size_in_bytes;
85 struct BASE_EXPORT ChromeUnwindInfoAndroid {
86 ChromeUnwindInfoAndroid(span<const uint8_t> unwind_instruction_table,
87 span<const uint8_t> function_offset_table,
88 span<const FunctionTableEntry> function_table,
89 span<const uint32_t> page_table);
90 ~ChromeUnwindInfoAndroid();
91 ChromeUnwindInfoAndroid(const ChromeUnwindInfoAndroid& other);
92 ChromeUnwindInfoAndroid& operator=(const ChromeUnwindInfoAndroid& other);
94 ChromeUnwindInfoAndroid(ChromeUnwindInfoAndroid&& other);
95 ChromeUnwindInfoAndroid& operator=(ChromeUnwindInfoAndroid&& other);
97 // Unwind instruction table is expected to have following memory layout:
98 // +-----------------------------+
100 // +-----------------------------+
101 // | pop {r4, r5, lr} | <- FUNC1 offset 10
102 // +-----------------------------+
103 // | add sp, 16 | <- FUNC1 offset 4
104 // +-----------------------------+
105 // | mov pc, lr | <- FUNC1 offset 0 (COMPLETE)
106 // +-----------------------------+
107 // | pop {r4, r11} [byte 1/2] | <- FUNC2 offset 8
108 // +-----------------------------+
109 // | pop {r4, r11} [byte 2/2] |
110 // +-----------------------------+
112 // +-----------------------------+
113 // Because we are unwinding the function, the next unwind instruction to
114 // execute always has smaller function offset.
115 // The function offsets are often discontinuous as not all instructions in
116 // the function have corresponding unwind instructions.
118 // See Exception handling ABI for the ARM architecture ABI, §9.3.
119 // https://developer.arm.com/documentation/ihi0038/b.
120 // for details in unwind instruction encoding.
121 // Only following instruction encodings are handled:
124 // - 1000iiii iiiiiiii
129 // - 10110010 uleb128
130 span<const uint8_t> unwind_instruction_table;
132 // Function offset table is expected to have following memory layout:
133 // +---------------------+---------------------+
134 // | <-----ULEB128-----> | <-----ULEB128-----> |
135 // +---------------------+---------------------+
136 // | Offset | Unwind Index |
137 // +---------------------+---------------------+-----
139 // +---------------------+---------------------+ |
140 // | 3 | YYY |Function 1
141 // +---------------------+---------------------+ |
143 // +---------------------+---------------------+-----
145 // +---------------------+---------------------+Function 2
147 // +---------------------+---------------------+-----
149 // +---------------------+---------------------+
150 // The function offset table contains [offset, unwind index] pairs, where
151 // - offset: offset from function start address of an instruction that affects
152 // the unwind state, measured in two-byte instructions.
153 // - unwind index: unwind instruction location in unwind instruction table.
156 // - Each function always ends at 0 offset, which corresponds to a terminal
157 // instruction in unwind instruction table.
158 // - Within each function section, offset strictly decreases. By doing so,
159 // each function's own terminal instruction will serve as termination
160 // condition when searching in the table.
161 span<const uint8_t> function_offset_table;
163 // The function table represents the individual functions within a 128kb page.
164 // The relevant entry for an instruction offset from the start of the text
165 // section is the one with the largest function_start_address_page_offset <=
166 // instruction_byte_offset_from_text_section_start.
168 // Function table is expected to have following memory layout:
169 // +--------------------+--------------------+
170 // | <-----2 byte-----> | <-----2 byte-----> |
171 // +--------------------+--------------------+
172 // | Page Offset | Offset Table Index |
173 // +--------------------+--------------------+-----
175 // +--------------------+--------------------+ |
176 // | ... | ... |Page 0x100
177 // +--------------------+--------------------+ |
179 // +--------------------+--------------------+-----
181 // +--------------------+--------------------+ |
182 // | ... | ... |Page 0x101
183 // +--------------------+--------------------+ |
185 // +--------------------+--------------------+-----
188 // - Within each page, `Page Offset` strictly increases.
189 // - Each `FunctionTableEntry` represents a function where the start
190 // address falls into the page memory address range.
191 span<const FunctionTableEntry> function_table;
193 // The page table represents discrete 128kb 'pages' of memory in the text
194 // section, each of which contains functions. The page table is indexed by
195 // bits 17 and greater of the pc offset from the start of the text section.
196 // Indexing into page_table produces an index of function_table.
198 // The page table is expected to have following memory layout:
199 // +----------------+
200 // | <-- 4 byte --> |
201 // +----------------+
203 // +----------------+
205 // +----------------+
207 // +----------------+
209 // +----------------+
211 // +----------------+
213 // - The page start instructions in page table non-strictly increases, i.e
214 // empty page is allowed.
215 span<const uint32_t> page_table;
218 // Creates `ChromeUnwindInfoAndroid` struct based on binary `data` assuming
219 // `data` starts with `ChromeUnwindInfoHeaderAndroid`.
220 BASE_EXPORT ChromeUnwindInfoAndroid
221 CreateChromeUnwindInfoAndroid(span<const uint8_t> data);
225 #endif // BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_