123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_
- #define BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_
- #include <stdint.h>
- #include "base/base_export.h"
- #include "base/containers/span.h"
- namespace base {
- // Represents each entry in the function table (i.e. the second level of the
- // function address table).
- struct FunctionTableEntry {
- // The offset into the 128kb page containing this function. Indexed by bits
- // 1-16 of the pc offset from the start of the text section.
- uint16_t function_start_address_page_instruction_offset;
- // The byte index of the first offset for the function in the function
- // offset table.
- uint16_t function_offset_table_byte_index;
- };
- // The header at the start of the unwind info resource, with offsets/sizes for
- // the tables contained within the resource.
- //
- // The unwind info provides 4 tables which can translate an instruction address
- // to a set of unwind instructions to unwind the function frame the instruction
- // belongs to.
- //
- // `page_table` and `function_table` together locates which function the
- // instruction address belongs to given an instruction address.
- //
- // `function_offset_table` and `unwind_instruction_table` together locates
- // which sets of unwind instructions to execute given the function info
- // obtained from `page_table` and `function_table`, and the offset between the
- // instruction address and function start address.
- //
- // Design Doc:
- // https://docs.google.com/document/d/1IYTmGCJZoiQ242xPUZX1fATD6ivsjU1TAt_fPv74ocs/edit?usp=sharing
- struct BASE_EXPORT ChromeUnwindInfoHeaderAndroid {
- // The offset in bytes from the start of the unwind info resource to the
- // page table (i.e. the first level of the function address table). The page
- // table represents discrete 128kb 'pages' of memory in the text section,
- // each of which contains functions. The page table is indexed by bits 17
- // and greater of the pc offset from the start of the text section.
- // Indexing into page_table produces an index of function_table.
- uint32_t page_table_byte_offset;
- uint32_t page_table_entries;
- // The offset in bytes from the start of the unwind info resource to the
- // function table (i.e. the second level of the function address table). The
- // function table represents the individual functions within a 128kb page.
- // Each function is represented as a `FunctionTableEntry`. The relevant entry
- // for a pc offset from the start of the text section is the one with the
- // largest function_start_address_page_instruction_offset <= (pc_offset >> 1)
- // & 0xffff.
- uint32_t function_table_byte_offset;
- uint32_t function_table_entries;
- // The offset in bytes from the start of the unwind info resource to the
- // function offset table. The function offset table represents the pc
- // offsets from the start of each function along with indices into the
- // unwind instructions for the offsets. The pc offsets and unwind indices
- // are represented as (ULEB128, ULEB128) pairs in decreasing order of
- // offset. Distinct sequences of (offset, index) pairs are concatenated in
- // the table.
- uint32_t function_offset_table_byte_offset;
- uint32_t function_offset_table_size_in_bytes;
- // The offset in bytes from the start of the unwind info resource to the
- // unwind instruction table. The unwind instruction table represents
- // distinct sequences of ARM compact unwind instructions[1] used across all
- // functions in Chrome. The compact unwind instruction is a byte-oriented
- // variable length encoding so is indexed by byte position.
- // 1. See Exception handling ABI for the ARM architecture ABI, §9.3.
- // https://developer.arm.com/documentation/ihi0038/b.
- uint32_t unwind_instruction_table_byte_offset;
- uint32_t unwind_instruction_table_size_in_bytes;
- };
- struct BASE_EXPORT ChromeUnwindInfoAndroid {
- ChromeUnwindInfoAndroid(span<const uint8_t> unwind_instruction_table,
- span<const uint8_t> function_offset_table,
- span<const FunctionTableEntry> function_table,
- span<const uint32_t> page_table);
- ~ChromeUnwindInfoAndroid();
- ChromeUnwindInfoAndroid(const ChromeUnwindInfoAndroid& other);
- ChromeUnwindInfoAndroid& operator=(const ChromeUnwindInfoAndroid& other);
- ChromeUnwindInfoAndroid(ChromeUnwindInfoAndroid&& other);
- ChromeUnwindInfoAndroid& operator=(ChromeUnwindInfoAndroid&& other);
- // Unwind instruction table is expected to have following memory layout:
- // +-----------------------------+
- // | <--1 byte---> |
- // +-----------------------------+
- // | pop {r4, r5, lr} | <- FUNC1 offset 10
- // +-----------------------------+
- // | add sp, 16 | <- FUNC1 offset 4
- // +-----------------------------+
- // | mov pc, lr | <- FUNC1 offset 0 (COMPLETE)
- // +-----------------------------+
- // | pop {r4, r11} [byte 1/2] | <- FUNC2 offset 8
- // +-----------------------------+
- // | pop {r4, r11} [byte 2/2] |
- // +-----------------------------+
- // | ... |
- // +-----------------------------+
- // Because we are unwinding the function, the next unwind instruction to
- // execute always has smaller function offset.
- // The function offsets are often discontinuous as not all instructions in
- // the function have corresponding unwind instructions.
- //
- // See Exception handling ABI for the ARM architecture ABI, §9.3.
- // https://developer.arm.com/documentation/ihi0038/b.
- // for details in unwind instruction encoding.
- // Only following instruction encodings are handled:
- // - 00xxxxxx
- // - 01xxxxxx
- // - 1000iiii iiiiiiii
- // - 1001nnnn
- // - 10100nnn
- // - 10101nnn
- // - 10110000
- // - 10110010 uleb128
- span<const uint8_t> unwind_instruction_table;
- // Function offset table is expected to have following memory layout:
- // +---------------------+---------------------+
- // | <-----ULEB128-----> | <-----ULEB128-----> |
- // +---------------------+---------------------+
- // | Offset | Unwind Index |
- // +---------------------+---------------------+-----
- // | 8 | XXX | |
- // +---------------------+---------------------+ |
- // | 3 | YYY |Function 1
- // +---------------------+---------------------+ |
- // | 0 | ZZZ | |
- // +---------------------+---------------------+-----
- // | 5 | AAA | |
- // +---------------------+---------------------+Function 2
- // | 0 | BBB | |
- // +---------------------+---------------------+-----
- // | ... | .... |
- // +---------------------+---------------------+
- // The function offset table contains [offset, unwind index] pairs, where
- // - offset: offset from function start address of an instruction that affects
- // the unwind state, measured in two-byte instructions.
- // - unwind index: unwind instruction location in unwind instruction table.
- //
- // Note:
- // - Each function always ends at 0 offset, which corresponds to a terminal
- // instruction in unwind instruction table.
- // - Within each function section, offset strictly decreases. By doing so,
- // each function's own terminal instruction will serve as termination
- // condition when searching in the table.
- span<const uint8_t> function_offset_table;
- // The function table represents the individual functions within a 128kb page.
- // The relevant entry for an instruction offset from the start of the text
- // section is the one with the largest function_start_address_page_offset <=
- // instruction_byte_offset_from_text_section_start.
- //
- // Function table is expected to have following memory layout:
- // +--------------------+--------------------+
- // | <-----2 byte-----> | <-----2 byte-----> |
- // +--------------------+--------------------+
- // | Page Offset | Offset Table Index |
- // +--------------------+--------------------+-----
- // | 10 | XXX | |
- // +--------------------+--------------------+ |
- // | ... | ... |Page 0x100
- // +--------------------+--------------------+ |
- // | 65500 | ZZZ | |
- // +--------------------+--------------------+-----
- // | 200 | AAA | |
- // +--------------------+--------------------+ |
- // | ... | ... |Page 0x101
- // +--------------------+--------------------+ |
- // | 65535 | BBB | |
- // +--------------------+--------------------+-----
- //
- // Note:
- // - Within each page, `Page Offset` strictly increases.
- // - Each `FunctionTableEntry` represents a function where the start
- // address falls into the page memory address range.
- span<const FunctionTableEntry> function_table;
- // The page table represents discrete 128kb 'pages' of memory in the text
- // section, each of which contains functions. The page table is indexed by
- // bits 17 and greater of the pc offset from the start of the text section.
- // Indexing into page_table produces an index of function_table.
- //
- // The page table is expected to have following memory layout:
- // +----------------+
- // | <-- 4 byte --> |
- // +----------------+
- // | 0 |
- // +----------------+
- // | 18 |
- // +----------------+
- // | 18 |
- // +----------------+
- // | 80 |
- // +----------------+
- // | ... |
- // +----------------+
- // Note:
- // - The page start instructions in page table non-strictly increases, i.e
- // empty page is allowed.
- span<const uint32_t> page_table;
- };
- // Creates `ChromeUnwindInfoAndroid` struct based on binary `data` assuming
- // `data` starts with `ChromeUnwindInfoHeaderAndroid`.
- BASE_EXPORT ChromeUnwindInfoAndroid
- CreateChromeUnwindInfoAndroid(span<const uint8_t> data);
- } // namespace base
- #endif // BASE_PROFILER_CHROME_UNWIND_INFO_ANDROID_H_
|