• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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