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_32_H_ 6 #define BASE_PROFILER_CHROME_UNWINDER_ANDROID_32_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_32.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 32-bit ARM, using 22 // ChromeUnwindInfoAndroid32, a separate binary resource. 23 class BASE_EXPORT ChromeUnwinderAndroid32 : public Unwinder { 24 public: 25 ChromeUnwinderAndroid32(const ChromeUnwindInfoAndroid32& unwind_info, 26 uintptr_t chrome_module_base_address, 27 uintptr_t text_section_start_address); 28 ChromeUnwinderAndroid32(const ChromeUnwinderAndroid32&) = delete; 29 ChromeUnwinderAndroid32& operator=(const ChromeUnwinderAndroid32&) = delete; 30 31 // Unwinder: 32 bool CanUnwindFrom(const Frame& current_frame) const override; 33 UnwindResult TryUnwind(UnwinderStateCapture* capture_state, 34 RegisterContext* thread_context, 35 uintptr_t stack_top, 36 std::vector<Frame>* stack) override; 37 38 private: 39 const ChromeUnwindInfoAndroid32 unwind_info_; 40 const uintptr_t chrome_module_base_address_; 41 const uintptr_t text_section_start_address_; 42 }; 43 44 // Following functions are exposed for testing purpose only. 45 struct FunctionTableEntry; 46 47 enum class UnwindInstructionResult { 48 kCompleted, // Signals the end of unwind process. 49 kInstructionPending, // Continues to unwind next instruction. 50 kAborted, // Unable to unwind. 51 }; 52 53 // Execute a single unwind instruction on the given thread_context, and moves 54 // `instruction` to point to next instruction right after the executed 55 // instruction. 56 // 57 // Arguments: 58 // instruction: The pointer to the instruction to execute. This pointer will 59 // be advanced by the size of the instruction executed after the 60 // function call. 61 // pc_was_updated: Set to true if the pc was updated by the instruction 62 // execution. Used to decide whether to copy lr to pc on 63 // COMPLETE. 64 // thread_context: The thread_context the instruction operates on. 65 BASE_EXPORT UnwindInstructionResult 66 ExecuteUnwindInstruction(const uint8_t*& instruction, 67 bool& pc_was_updated, 68 RegisterContext* thread_context); 69 70 // Represents an index that can locate a specific entry on function offset 71 // table. 72 struct FunctionOffsetTableIndex { 73 // Number of 2-byte instructions between the instruction of interest and 74 // function start address. 75 int instruction_offset_from_function_start; 76 // The byte index of the first offset for the function in the function 77 // offset table. 78 uint16_t function_offset_table_byte_index; 79 }; 80 81 // Given function offset table entry, finds the first unwind instruction to 82 // execute in unwind instruction table. 83 // 84 // Arguments: 85 // function_offset_table_entry: An entry in function offset table. See 86 // `ChromeUnwindInfoAndroid32::function_offset_table` for details. 87 // instruction_offset_from_function_start: Number of 2-byte instructions 88 // between the instruction of interest and function start address. 89 // 90 // Returns: 91 // The index of the first unwind instruction to execute in 92 // `ChromeUnwindInfoAndroid32::unwind_instruction_table`. 93 BASE_EXPORT uintptr_t 94 GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry( 95 const uint8_t* function_offset_table_entry, 96 int instruction_offset_from_function_start); 97 98 // Given an instruction_byte_offset_from_text_section_start, finds the 99 // corresponding `FunctionOffsetTableIndex`. 100 // 101 // Arguments: 102 // page_start_instructions: A list of page_numbers. See 103 // `ChromeUnwindInfoAndroid32::page_table` for details. 104 // function_offsets_table_indices: A list of `FunctionTableEntry`. See 105 // `ChromeUnwindInfoAndroid32::function_table` for details. 106 // instruction_byte_offset_from_text_section_start: The distance in bytes 107 // between the instruction of interest and text section start. 108 BASE_EXPORT const std::optional<FunctionOffsetTableIndex> 109 GetFunctionTableIndexFromInstructionOffset( 110 span<const uint32_t> page_start_instructions, 111 span<const FunctionTableEntry> function_offset_table_indices, 112 uint32_t instruction_byte_offset_from_text_section_start); 113 114 } // namespace base 115 116 #endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_32_H_ 117