chrome_unwind_info_android.h 10 KB

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