blob: 42a90e7eda6d52c770210c1a2d79b10069ec2032 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2021 The Chromium Authors
Charlie Hud5c14032021-08-26 21:45:592// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Charlie Hue0a13a72021-09-24 21:57:395#ifndef BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_
6#define BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_
Charlie Hud5c14032021-08-26 21:45:597
8#include <stdint.h>
9
10#include "base/base_export.h"
Charlie Hu235c6b72021-09-13 20:50:0111#include "base/containers/span.h"
Charlie Hu78e00402021-10-13 06:10:4312#include "base/profiler/chrome_unwind_info_android.h"
13#include "base/profiler/module_cache.h"
Charlie Hud5c14032021-08-26 21:45:5914#include "base/profiler/register_context.h"
Charlie Hu78e00402021-10-13 06:10:4315#include "base/profiler/unwinder.h"
Charlie Hu235c6b72021-09-13 20:50:0116#include "third_party/abseil-cpp/absl/types/optional.h"
Charlie Hud5c14032021-08-26 21:45:5917
18namespace base {
19
Charlie Hu78e00402021-10-13 06:10:4320// Chrome unwinder implementation for Android, using ChromeUnwindInfoAndroid,
21// a separate binary resource. This implementation is intended to replace
22// `ChromeUnwinderAndroid`, which uses ArmCfiTable.
23class BASE_EXPORT ChromeUnwinderAndroidV2 : public Unwinder {
24 public:
25 ChromeUnwinderAndroidV2(const ChromeUnwindInfoAndroid& unwind_info,
26 uintptr_t chrome_module_base_address,
27 uintptr_t text_section_start_address);
28 ChromeUnwinderAndroidV2(const ChromeUnwinderAndroidV2&) = delete;
29 ChromeUnwinderAndroidV2& operator=(const ChromeUnwinderAndroidV2&) = delete;
30
31 // Unwinder:
32 bool CanUnwindFrom(const Frame& current_frame) const override;
33 UnwindResult TryUnwind(RegisterContext* thread_context,
34 uintptr_t stack_top,
35 std::vector<Frame>* stack) const override;
36
37 private:
38 const ChromeUnwindInfoAndroid unwind_info_;
39 const uintptr_t chrome_module_base_address_;
40 const uintptr_t text_section_start_address_;
41};
42
43// Following functions are exposed for testing purpose only.
Charlie Hu027f8a12021-09-23 23:25:1944struct FunctionTableEntry;
45
Charlie Hu82c2ed352021-09-14 17:58:5546enum class UnwindInstructionResult {
47 kCompleted, // Signals the end of unwind process.
48 kInstructionPending, // Continues to unwind next instruction.
49 kAborted, // Unable to unwind.
Charlie Hud5c14032021-08-26 21:45:5950};
51
Charlie Hu027f8a12021-09-23 23:25:1952// Execute a single unwind instruction on the given thread_context, and moves
53// `instruction` to point to next instruction right after the executed
54// instruction.
Charlie Hu01b7e662021-09-13 14:51:3655//
56// Arguments:
57// instruction: The pointer to the instruction to execute. This pointer will
58// be advanced by the size of the instruction executed after the
59// function call.
60// pc_was_updated: Set to true if the pc was updated by the instruction
61// execution. Used to decide whether to copy lr to pc on
62// COMPLETE.
63// thread_context: The thread_context the instruction operates on.
Charlie Hud5c14032021-08-26 21:45:5964BASE_EXPORT UnwindInstructionResult
65ExecuteUnwindInstruction(const uint8_t*& instruction,
Charlie Hu01b7e662021-09-13 14:51:3666 bool& pc_was_updated,
Charlie Hud5c14032021-08-26 21:45:5967 RegisterContext* thread_context);
Charlie Huf36b2f62021-09-01 22:31:2068
Charlie Hu235c6b72021-09-13 20:50:0169// Represents an index that can locate a specific entry on function offset
70// table.
71struct FunctionOffsetTableIndex {
72 // Number of 2-byte instructions between the instruction of interest and
Charlie Hu78e00402021-10-13 06:10:4373 // function start address.
Charlie Hu235c6b72021-09-13 20:50:0174 int instruction_offset_from_function_start;
75 // The byte index of the first offset for the function in the function
76 // offset table.
77 uint16_t function_offset_table_byte_index;
78};
79
Charlie Hu78e00402021-10-13 06:10:4380// Given function offset table entry, finds the first unwind instruction to
81// execute in unwind instruction table.
Charlie Huf36b2f62021-09-01 22:31:2082//
Charlie Huf36b2f62021-09-01 22:31:2083// Arguments:
Charlie Hu78e00402021-10-13 06:10:4384// function_offset_table_entry: An entry in function offset table. See
Charlie Hu027f8a12021-09-23 23:25:1985// `ChromeUnwindInfoAndroid::function_offset_table` for details.
Charlie Hu78e00402021-10-13 06:10:4386// instruction_offset_from_function_start: Number of 2-byte instructions
87// between the instruction of interest and function start address.
88//
89// Returns:
90// The index of the first unwind instruction to execute in
91// `ChromeUnwindInfoAndroid::unwind_instruction_table`.
92BASE_EXPORT uintptr_t
93GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry(
94 const uint8_t* function_offset_table_entry,
95 int instruction_offset_from_function_start);
Charlie Hu235c6b72021-09-13 20:50:0196
Charlie Hud3028512021-10-13 18:34:2197// Given an instruction_byte_offset_from_text_section_start, finds the
98// corresponding `FunctionOffsetTableIndex`.
Charlie Hu235c6b72021-09-13 20:50:0199//
Charlie Hu027f8a12021-09-23 23:25:19100// Arguments:
101// page_start_instructions: A list of page_numbers. See
102// `ChromeUnwindInfoAndroid::page_table` for details.
103// function_offsets_table_indices: A list of `FunctionTableEntry`. See
104// `ChromeUnwindInfoAndroid::function_table` for details.
Charlie Hud3028512021-10-13 18:34:21105// instruction_byte_offset_from_text_section_start: The distance in bytes
106// between the instruction of interest and text section start.
Charlie Hu235c6b72021-09-13 20:50:01107BASE_EXPORT const absl::optional<FunctionOffsetTableIndex>
108GetFunctionTableIndexFromInstructionOffset(
109 span<const uint32_t> page_start_instructions,
110 span<const FunctionTableEntry> function_offset_table_indices,
Charlie Hud3028512021-10-13 18:34:21111 uint32_t instruction_byte_offset_from_text_section_start);
Charlie Hu235c6b72021-09-13 20:50:01112
Charlie Hud5c14032021-08-26 21:45:59113} // namespace base
114
Charlie Hue0a13a72021-09-24 21:57:39115#endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_