chrome_unwinder_android_v2.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_
  5. #define BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_
  6. #include <stdint.h>
  7. #include "base/base_export.h"
  8. #include "base/containers/span.h"
  9. #include "base/profiler/chrome_unwind_info_android.h"
  10. #include "base/profiler/module_cache.h"
  11. #include "base/profiler/register_context.h"
  12. #include "base/profiler/unwinder.h"
  13. #include "third_party/abseil-cpp/absl/types/optional.h"
  14. namespace base {
  15. // Chrome unwinder implementation for Android, using ChromeUnwindInfoAndroid,
  16. // a separate binary resource. This implementation is intended to replace
  17. // `ChromeUnwinderAndroid`, which uses ArmCfiTable.
  18. class BASE_EXPORT ChromeUnwinderAndroidV2 : public Unwinder {
  19. public:
  20. ChromeUnwinderAndroidV2(const ChromeUnwindInfoAndroid& unwind_info,
  21. uintptr_t chrome_module_base_address,
  22. uintptr_t text_section_start_address);
  23. ChromeUnwinderAndroidV2(const ChromeUnwinderAndroidV2&) = delete;
  24. ChromeUnwinderAndroidV2& operator=(const ChromeUnwinderAndroidV2&) = delete;
  25. // Unwinder:
  26. bool CanUnwindFrom(const Frame& current_frame) const override;
  27. UnwindResult TryUnwind(RegisterContext* thread_context,
  28. uintptr_t stack_top,
  29. std::vector<Frame>* stack) const override;
  30. private:
  31. const ChromeUnwindInfoAndroid unwind_info_;
  32. const uintptr_t chrome_module_base_address_;
  33. const uintptr_t text_section_start_address_;
  34. };
  35. // Following functions are exposed for testing purpose only.
  36. struct FunctionTableEntry;
  37. enum class UnwindInstructionResult {
  38. kCompleted, // Signals the end of unwind process.
  39. kInstructionPending, // Continues to unwind next instruction.
  40. kAborted, // Unable to unwind.
  41. };
  42. // Execute a single unwind instruction on the given thread_context, and moves
  43. // `instruction` to point to next instruction right after the executed
  44. // instruction.
  45. //
  46. // Arguments:
  47. // instruction: The pointer to the instruction to execute. This pointer will
  48. // be advanced by the size of the instruction executed after the
  49. // function call.
  50. // pc_was_updated: Set to true if the pc was updated by the instruction
  51. // execution. Used to decide whether to copy lr to pc on
  52. // COMPLETE.
  53. // thread_context: The thread_context the instruction operates on.
  54. BASE_EXPORT UnwindInstructionResult
  55. ExecuteUnwindInstruction(const uint8_t*& instruction,
  56. bool& pc_was_updated,
  57. RegisterContext* thread_context);
  58. // Represents an index that can locate a specific entry on function offset
  59. // table.
  60. struct FunctionOffsetTableIndex {
  61. // Number of 2-byte instructions between the instruction of interest and
  62. // function start address.
  63. int instruction_offset_from_function_start;
  64. // The byte index of the first offset for the function in the function
  65. // offset table.
  66. uint16_t function_offset_table_byte_index;
  67. };
  68. // Given function offset table entry, finds the first unwind instruction to
  69. // execute in unwind instruction table.
  70. //
  71. // Arguments:
  72. // function_offset_table_entry: An entry in function offset table. See
  73. // `ChromeUnwindInfoAndroid::function_offset_table` for details.
  74. // instruction_offset_from_function_start: Number of 2-byte instructions
  75. // between the instruction of interest and function start address.
  76. //
  77. // Returns:
  78. // The index of the first unwind instruction to execute in
  79. // `ChromeUnwindInfoAndroid::unwind_instruction_table`.
  80. BASE_EXPORT uintptr_t
  81. GetFirstUnwindInstructionIndexFromFunctionOffsetTableEntry(
  82. const uint8_t* function_offset_table_entry,
  83. int instruction_offset_from_function_start);
  84. // Given an instruction_byte_offset_from_text_section_start, finds the
  85. // corresponding `FunctionOffsetTableIndex`.
  86. //
  87. // Arguments:
  88. // page_start_instructions: A list of page_numbers. See
  89. // `ChromeUnwindInfoAndroid::page_table` for details.
  90. // function_offsets_table_indices: A list of `FunctionTableEntry`. See
  91. // `ChromeUnwindInfoAndroid::function_table` for details.
  92. // instruction_byte_offset_from_text_section_start: The distance in bytes
  93. // between the instruction of interest and text section start.
  94. BASE_EXPORT const absl::optional<FunctionOffsetTableIndex>
  95. GetFunctionTableIndexFromInstructionOffset(
  96. span<const uint32_t> page_start_instructions,
  97. span<const FunctionTableEntry> function_offset_table_indices,
  98. uint32_t instruction_byte_offset_from_text_section_start);
  99. } // namespace base
  100. #endif // BASE_PROFILER_CHROME_UNWINDER_ANDROID_V2_H_