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 "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" 17 18 namespace base { 19 20 // Chrome unwinder implementation for Android, using ChromeUnwindInfoAndroid, 21 // a separate binary resource. 22 class BASE_EXPORT ChromeUnwinderAndroid : public Unwinder { 23 public: 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; 29 30 // Unwinder: 31 bool CanUnwindFrom(const Frame& current_frame) const override; 32 UnwindResult TryUnwind(RegisterContext* thread_context, 33 uintptr_t stack_top, 34 std::vector<Frame>* stack) override; 35 36 private: 37 const ChromeUnwindInfoAndroid unwind_info_; 38 const uintptr_t chrome_module_base_address_; 39 const uintptr_t text_section_start_address_; 40 }; 41 42 // Following functions are exposed for testing purpose only. 43 struct FunctionTableEntry; 44 45 enum class UnwindInstructionResult { 46 kCompleted, // Signals the end of unwind process. 47 kInstructionPending, // Continues to unwind next instruction. 48 kAborted, // Unable to unwind. 49 }; 50 51 // Execute a single unwind instruction on the given thread_context, and moves 52 // `instruction` to point to next instruction right after the executed 53 // instruction. 54 // 55 // Arguments: 56 // instruction: The pointer to the instruction to execute. This pointer will 57 // be advanced by the size of the instruction executed after the 58 // function call. 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 61 // COMPLETE. 62 // thread_context: The thread_context the instruction operates on. 63 BASE_EXPORT UnwindInstructionResult 64 ExecuteUnwindInstruction(const uint8_t*& instruction, 65 bool& pc_was_updated, 66 RegisterContext* thread_context); 67 68 // Represents an index that can locate a specific entry on function offset 69 // table. 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 75 // offset table. 76 uint16_t function_offset_table_byte_index; 77 }; 78 79 // Given function offset table entry, finds the first unwind instruction to 80 // execute in unwind instruction table. 81 // 82 // Arguments: 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. 87 // 88 // Returns: 89 // The index of the first unwind instruction to execute in 90 // `ChromeUnwindInfoAndroid::unwind_instruction_table`. 91 BASE_EXPORT uintptr_t 92 GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry( 93 const uint8_t* function_offset_table_entry, 94 int instruction_offset_from_function_start); 95 96 // Given an instruction_byte_offset_from_text_section_start, finds the 97 // corresponding `FunctionOffsetTableIndex`. 98 // 99 // Arguments: 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); 111 112 } // namespace base 113 114 #endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_H_ 115