blob: d6b073c15af8c59a847ad8d3d77b4efc19d5fa49 [file] [log] [blame]
Charlie Hud5c14032021-08-26 21:45:591// 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
5#ifndef BASE_PROFILER_CHROME_UNWIND_TABLE_ANDROID_H_
6#define BASE_PROFILER_CHROME_UNWIND_TABLE_ANDROID_H_
7
8#include <stdint.h>
9
10#include "base/base_export.h"
11#include "base/profiler/register_context.h"
12
13namespace base {
14
15enum UnwindInstructionResult {
16 COMPLETED, // Signals the end of unwind process.
17 INSTRUCTION_PENDING, // Continues to unwind next instruction.
18 STACK_POINTER_OUT_OF_BOUNDS, // Stack pointer is out of bounds after
19 // execution of unwind instruction.
20};
21
22// Execute a single unwind instruction on the given thread_context,
23// and moves `instruction` to point to next instruction right after the executed
24// instruction if the executed result is `INSTRUCTION_PENDING`.
25//
26// See Exception handling ABI for the ARM architecture ABI, ยง9.3.
27// https://developer.arm.com/documentation/ihi0038/b.
28// for details in unwind instruction encoding.
29// Only following instruction encodings are handled:
30// - 00xxxxxx
31// - 01xxxxxx
Charlie Hu01b7e662021-09-13 14:51:3632// - 1000iiii iiiiiiii
Charlie Hud5c14032021-08-26 21:45:5933// - 1001nnnn
34// - 10100nnn
35// - 10101nnn
36// - 10110000
37// - 10110010 uleb128
38//
39// Unwind instruction table is expected to have following memory layout:
40// +----------------+
41// | <--1 byte---> |
42// +----------------+
43// | INST_PENDING | <- FUNC1 offset 10
44// +----------------+
45// | INST_PENDING | <- FUNC1 offset 4
46// +----------------+
47// | COMPLETE | <- FUNC1 offset 0
48// +----------------+
49// | INST_PENDING | <- FUNC2 offset 8
50// +----------------+
51// | ... |
52// +----------------+
53// Because we are unwinding the function, the next unwind instruction to
54// execute always have smaller function offset.
55// The function offsets are often discontinuous as not all instructions in
56// the function have corresponding unwind instructions.
Charlie Hu01b7e662021-09-13 14:51:3657//
58// Arguments:
59// instruction: The pointer to the instruction to execute. This pointer will
60// be advanced by the size of the instruction executed after the
61// function call.
62// pc_was_updated: Set to true if the pc was updated by the instruction
63// execution. Used to decide whether to copy lr to pc on
64// COMPLETE.
65// thread_context: The thread_context the instruction operates on.
Charlie Hud5c14032021-08-26 21:45:5966BASE_EXPORT UnwindInstructionResult
67ExecuteUnwindInstruction(const uint8_t*& instruction,
Charlie Hu01b7e662021-09-13 14:51:3668 bool& pc_was_updated,
Charlie Hud5c14032021-08-26 21:45:5969 RegisterContext* thread_context);
Charlie Huf36b2f62021-09-01 22:31:2070
71// Given
72// - function_offset_table_byte_index
73// - instruction_offset_from_function_start
74// finds the instruction to execute on unwind instruction table.
75//
76// Function offset table is expected to have following memory layout:
77// +---------------------+---------------------+
78// | <-----ULEB128-----> | <-----ULEB128-----> |
79// +---------------------+---------------------+
80// | Offset | Unwind Index |
81// +---------------------+---------------------+-----
82// | 8 | XXX | |
83// +---------------------+---------------------+ |
84// | 3 | YYY |Function 1
85// +---------------------+---------------------+ |
86// | 0 | ZZZ | |
87// +---------------------+---------------------+-----
88// | 5 | AAA | |
89// +---------------------+---------------------+Function 2
90// | 0 | BBB | |
91// +---------------------+---------------------+-----
92// | ... | .... |
93// +---------------------+---------------------+
94//
95// The function offset table contains [offset, unwind index] pairs, where
96// - offset: offset from function start address of an instruction that affects
97// the unwind state, measured in two-byte instructions.
98// - unwind index: unwind instruction location on unwind instruction table.
99//
100// Note:
101// - Each function always ends at 0 offset, which correspond to a COMPLETE
102// instruction on unwind instruction table.
103// - Within each function section, offset strictly decreases. By doing so,
104// each function's own COMPLETE instruction will serve as termination
105// condition when searching in the table.
106//
107// Arguments:
108// unwind_instruction_table: The table that stores a list of unwind
109// instructions
110// function_offset_table: Explained above.
111// function_offset_table_byte_index: The byte index of the first offset for the
112// function in the function offset table.
113// instruction_offset_from_function_start: (pc - function_start_address) >> 1.
114BASE_EXPORT const uint8_t* GetFirstUnwindInstructionFromInstructionOffset(
115 const uint8_t* unwind_instruction_table,
116 const uint8_t* function_offset_table,
117 uint16_t function_offset_table_byte_index,
118 uint32_t instruction_offset_from_function_start);
Charlie Hud5c14032021-08-26 21:45:59119} // namespace base
120
121#endif // BASE_PROFILER_CHROME_UNWIND_TABLE_ANDROID_H_