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_UNWINDER_ANDROID_H_
6 #define BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_
10 #include "base/base_export.h"
11 #include "base/containers/span.h"
12 #include "base/profiler/chrome_unwind_info_android.h"
13 #include "base/profiler/module_cache.h"
14 #include "base/profiler/register_context.h"
15 #include "base/profiler/unwinder.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
20 // Chrome unwinder implementation for Android, using ChromeUnwindInfoAndroid,
21 // a separate binary resource.
22 class BASE_EXPORT ChromeUnwinderAndroid : public Unwinder {
24 ChromeUnwinderAndroid(const ChromeUnwindInfoAndroid& unwind_info,
25 uintptr_t chrome_module_base_address,
26 uintptr_t text_section_start_address);
27 ChromeUnwinderAndroid(const ChromeUnwinderAndroid&) = delete;
28 ChromeUnwinderAndroid& operator=(const ChromeUnwinderAndroid&) = delete;
31 bool CanUnwindFrom(const Frame& current_frame) const override;
32 UnwindResult TryUnwind(RegisterContext* thread_context,
34 std::vector<Frame>* stack) override;
37 const ChromeUnwindInfoAndroid unwind_info_;
38 const uintptr_t chrome_module_base_address_;
39 const uintptr_t text_section_start_address_;
42 // Following functions are exposed for testing purpose only.
43 struct FunctionTableEntry;
45 enum class UnwindInstructionResult {
46 kCompleted, // Signals the end of unwind process.
47 kInstructionPending, // Continues to unwind next instruction.
48 kAborted, // Unable to unwind.
51 // Execute a single unwind instruction on the given thread_context, and moves
52 // `instruction` to point to next instruction right after the executed
56 // instruction: The pointer to the instruction to execute. This pointer will
57 // be advanced by the size of the instruction executed after the
59 // pc_was_updated: Set to true if the pc was updated by the instruction
60 // execution. Used to decide whether to copy lr to pc on
62 // thread_context: The thread_context the instruction operates on.
63 BASE_EXPORT UnwindInstructionResult
64 ExecuteUnwindInstruction(const uint8_t*& instruction,
66 RegisterContext* thread_context);
68 // Represents an index that can locate a specific entry on function offset
70 struct FunctionOffsetTableIndex {
71 // Number of 2-byte instructions between the instruction of interest and
72 // function start address.
73 int instruction_offset_from_function_start;
74 // The byte index of the first offset for the function in the function
76 uint16_t function_offset_table_byte_index;
79 // Given function offset table entry, finds the first unwind instruction to
80 // execute in unwind instruction table.
83 // function_offset_table_entry: An entry in function offset table. See
84 // `ChromeUnwindInfoAndroid::function_offset_table` for details.
85 // instruction_offset_from_function_start: Number of 2-byte instructions
86 // between the instruction of interest and function start address.
89 // The index of the first unwind instruction to execute in
90 // `ChromeUnwindInfoAndroid::unwind_instruction_table`.
92 GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry(
93 const uint8_t* function_offset_table_entry,
94 int instruction_offset_from_function_start);
96 // Given an instruction_byte_offset_from_text_section_start, finds the
97 // corresponding `FunctionOffsetTableIndex`.
100 // page_start_instructions: A list of page_numbers. See
101 // `ChromeUnwindInfoAndroid::page_table` for details.
102 // function_offsets_table_indices: A list of `FunctionTableEntry`. See
103 // `ChromeUnwindInfoAndroid::function_table` for details.
104 // instruction_byte_offset_from_text_section_start: The distance in bytes
105 // between the instruction of interest and text section start.
106 BASE_EXPORT const absl::optional<FunctionOffsetTableIndex>
107 GetFunctionTableIndexFromInstructionOffset(
108 span<const uint32_t> page_start_instructions,
109 span<const FunctionTableEntry> function_offset_table_indices,
110 uint32_t instruction_byte_offset_from_text_section_start);
114 #endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_