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. 4 5 #ifndef BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_ 6 #define BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_ 7 8 #include <stdint.h> 9 10 #include <optional> 11 12 #include "base/base_export.h" 13 #include "base/containers/span.h" 14 #include "base/profiler/chrome_unwind_info_android.h" 15 #include "base/profiler/module_cache.h" 16 #include "base/profiler/register_context.h" 17 #include "base/profiler/unwinder.h" 18 19 namespace base { 20 21 // Chrome unwinder implementation for Android, using ChromeUnwindInfoAndroid, 22 // a separate binary resource. 23 class BASE_EXPORT ChromeUnwinderAndroid : public Unwinder { 24 public: 25 ChromeUnwinderAndroid(const ChromeUnwindInfoAndroid& unwind_info, 26 uintptr_t chrome_module_base_address, 27 uintptr_t text_section_start_address); 28 ChromeUnwinderAndroid(const ChromeUnwinderAndroid&) = delete; 29 ChromeUnwinderAndroid& operator=(const ChromeUnwinderAndroid&) = 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) 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. 44 struct FunctionTableEntry; 45 46 enum class UnwindInstructionResult { 47 kCompleted, // Signals the end of unwind process. 48 kInstructionPending, // Continues to unwind next instruction. 49 kAborted, // Unable to unwind. 50 }; 51 52 // 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. 55 // 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. 64 BASE_EXPORT UnwindInstructionResult 65 ExecuteUnwindInstruction(const uint8_t*& instruction, 66 bool& pc_was_updated, 67 RegisterContext* thread_context); 68 69 // Represents an index that can locate a specific entry on function offset 70 // table. 71 struct FunctionOffsetTableIndex { 72 // Number of 2-byte instructions between the instruction of interest and 73 // function start address. 74 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 80 // Given function offset table entry, finds the first unwind instruction to 81 // execute in unwind instruction table. 82 // 83 // Arguments: 84 // function_offset_table_entry: An entry in function offset table. See 85 // `ChromeUnwindInfoAndroid::function_offset_table` for details. 86 // 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`. 92 BASE_EXPORT uintptr_t 93 GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry( 94 const uint8_t* function_offset_table_entry, 95 int instruction_offset_from_function_start); 96 97 // Given an instruction_byte_offset_from_text_section_start, finds the 98 // corresponding `FunctionOffsetTableIndex`. 99 // 100 // 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. 105 // instruction_byte_offset_from_text_section_start: The distance in bytes 106 // between the instruction of interest and text section start. 107 BASE_EXPORT const std::optional<FunctionOffsetTableIndex> 108 GetFunctionTableIndexFromInstructionOffset( 109 span<const uint32_t> page_start_instructions, 110 span<const FunctionTableEntry> function_offset_table_indices, 111 uint32_t instruction_byte_offset_from_text_section_start); 112 113 } // namespace base 114 115 #endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_ 116