UnwindPlan.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. //===-- UnwindPlan.h --------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLDB_SYMBOL_UNWINDPLAN_H
  9. #define LLDB_SYMBOL_UNWINDPLAN_H
  10. #include <map>
  11. #include <memory>
  12. #include <vector>
  13. #include "lldb/Core/AddressRange.h"
  14. #include "lldb/Utility/ConstString.h"
  15. #include "lldb/Utility/Stream.h"
  16. #include "lldb/lldb-private.h"
  17. namespace lldb_private {
  18. // The UnwindPlan object specifies how to unwind out of a function - where this
  19. // function saves the caller's register values before modifying them (for non-
  20. // volatile aka saved registers) and how to find this frame's Canonical Frame
  21. // Address (CFA) or Aligned Frame Address (AFA).
  22. // CFA is a DWARF's Canonical Frame Address.
  23. // Most commonly, registers are saved on the stack, offset some bytes from the
  24. // Canonical Frame Address, or CFA, which is the starting address of this
  25. // function's stack frame (the CFA is same as the eh_frame's CFA, whatever that
  26. // may be on a given architecture). The CFA address for the stack frame does
  27. // not change during the lifetime of the function.
  28. // AFA is an artificially introduced Aligned Frame Address.
  29. // It is used only for stack frames with realignment (e.g. when some of the
  30. // locals has an alignment requirement higher than the stack alignment right
  31. // after the function call). It is used to access register values saved on the
  32. // stack after the realignment (and so they are inaccessible through the CFA).
  33. // AFA usually equals the stack pointer value right after the realignment.
  34. // Internally, the UnwindPlan is structured as a vector of register locations
  35. // organized by code address in the function, showing which registers have been
  36. // saved at that point and where they are saved. It can be thought of as the
  37. // expanded table form of the DWARF CFI encoded information.
  38. // Other unwind information sources will be converted into UnwindPlans before
  39. // being added to a FuncUnwinders object. The unwind source may be an eh_frame
  40. // FDE, a DWARF debug_frame FDE, or assembly language based prologue analysis.
  41. // The UnwindPlan is the canonical form of this information that the unwinder
  42. // code will use when walking the stack.
  43. class UnwindPlan {
  44. public:
  45. class Row {
  46. public:
  47. class RegisterLocation {
  48. public:
  49. enum RestoreType {
  50. unspecified, // not specified, we may be able to assume this
  51. // is the same register. gcc doesn't specify all
  52. // initial values so we really don't know...
  53. undefined, // reg is not available, e.g. volatile reg
  54. same, // reg is unchanged
  55. atCFAPlusOffset, // reg = deref(CFA + offset)
  56. isCFAPlusOffset, // reg = CFA + offset
  57. atAFAPlusOffset, // reg = deref(AFA + offset)
  58. isAFAPlusOffset, // reg = AFA + offset
  59. inOtherRegister, // reg = other reg
  60. atDWARFExpression, // reg = deref(eval(dwarf_expr))
  61. isDWARFExpression // reg = eval(dwarf_expr)
  62. };
  63. RegisterLocation() : m_type(unspecified), m_location() {}
  64. bool operator==(const RegisterLocation &rhs) const;
  65. bool operator!=(const RegisterLocation &rhs) const {
  66. return !(*this == rhs);
  67. }
  68. void SetUnspecified() { m_type = unspecified; }
  69. void SetUndefined() { m_type = undefined; }
  70. void SetSame() { m_type = same; }
  71. bool IsSame() const { return m_type == same; }
  72. bool IsUnspecified() const { return m_type == unspecified; }
  73. bool IsUndefined() const { return m_type == undefined; }
  74. bool IsCFAPlusOffset() const { return m_type == isCFAPlusOffset; }
  75. bool IsAtCFAPlusOffset() const { return m_type == atCFAPlusOffset; }
  76. bool IsAFAPlusOffset() const { return m_type == isAFAPlusOffset; }
  77. bool IsAtAFAPlusOffset() const { return m_type == atAFAPlusOffset; }
  78. bool IsInOtherRegister() const { return m_type == inOtherRegister; }
  79. bool IsAtDWARFExpression() const { return m_type == atDWARFExpression; }
  80. bool IsDWARFExpression() const { return m_type == isDWARFExpression; }
  81. void SetAtCFAPlusOffset(int32_t offset) {
  82. m_type = atCFAPlusOffset;
  83. m_location.offset = offset;
  84. }
  85. void SetIsCFAPlusOffset(int32_t offset) {
  86. m_type = isCFAPlusOffset;
  87. m_location.offset = offset;
  88. }
  89. void SetAtAFAPlusOffset(int32_t offset) {
  90. m_type = atAFAPlusOffset;
  91. m_location.offset = offset;
  92. }
  93. void SetIsAFAPlusOffset(int32_t offset) {
  94. m_type = isAFAPlusOffset;
  95. m_location.offset = offset;
  96. }
  97. void SetInRegister(uint32_t reg_num) {
  98. m_type = inOtherRegister;
  99. m_location.reg_num = reg_num;
  100. }
  101. uint32_t GetRegisterNumber() const {
  102. if (m_type == inOtherRegister)
  103. return m_location.reg_num;
  104. return LLDB_INVALID_REGNUM;
  105. }
  106. RestoreType GetLocationType() const { return m_type; }
  107. int32_t GetOffset() const {
  108. switch(m_type)
  109. {
  110. case atCFAPlusOffset:
  111. case isCFAPlusOffset:
  112. case atAFAPlusOffset:
  113. case isAFAPlusOffset:
  114. return m_location.offset;
  115. default:
  116. return 0;
  117. }
  118. }
  119. void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const {
  120. if (m_type == atDWARFExpression || m_type == isDWARFExpression) {
  121. *opcodes = m_location.expr.opcodes;
  122. len = m_location.expr.length;
  123. } else {
  124. *opcodes = nullptr;
  125. len = 0;
  126. }
  127. }
  128. void SetAtDWARFExpression(const uint8_t *opcodes, uint32_t len);
  129. void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len);
  130. const uint8_t *GetDWARFExpressionBytes() {
  131. if (m_type == atDWARFExpression || m_type == isDWARFExpression)
  132. return m_location.expr.opcodes;
  133. return nullptr;
  134. }
  135. int GetDWARFExpressionLength() {
  136. if (m_type == atDWARFExpression || m_type == isDWARFExpression)
  137. return m_location.expr.length;
  138. return 0;
  139. }
  140. void Dump(Stream &s, const UnwindPlan *unwind_plan,
  141. const UnwindPlan::Row *row, Thread *thread, bool verbose) const;
  142. private:
  143. RestoreType m_type; // How do we locate this register?
  144. union {
  145. // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
  146. int32_t offset;
  147. // For m_type == inOtherRegister
  148. uint32_t reg_num; // The register number
  149. // For m_type == atDWARFExpression or m_type == isDWARFExpression
  150. struct {
  151. const uint8_t *opcodes;
  152. uint16_t length;
  153. } expr;
  154. } m_location;
  155. };
  156. class FAValue {
  157. public:
  158. enum ValueType {
  159. unspecified, // not specified
  160. isRegisterPlusOffset, // FA = register + offset
  161. isRegisterDereferenced, // FA = [reg]
  162. isDWARFExpression, // FA = eval(dwarf_expr)
  163. isRaSearch, // FA = SP + offset + ???
  164. };
  165. FAValue() : m_type(unspecified), m_value() {}
  166. bool operator==(const FAValue &rhs) const;
  167. bool operator!=(const FAValue &rhs) const { return !(*this == rhs); }
  168. void SetUnspecified() { m_type = unspecified; }
  169. bool IsUnspecified() const { return m_type == unspecified; }
  170. void SetRaSearch(int32_t offset) {
  171. m_type = isRaSearch;
  172. m_value.ra_search_offset = offset;
  173. }
  174. bool IsRegisterPlusOffset() const {
  175. return m_type == isRegisterPlusOffset;
  176. }
  177. void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset) {
  178. m_type = isRegisterPlusOffset;
  179. m_value.reg.reg_num = reg_num;
  180. m_value.reg.offset = offset;
  181. }
  182. bool IsRegisterDereferenced() const {
  183. return m_type == isRegisterDereferenced;
  184. }
  185. void SetIsRegisterDereferenced(uint32_t reg_num) {
  186. m_type = isRegisterDereferenced;
  187. m_value.reg.reg_num = reg_num;
  188. }
  189. bool IsDWARFExpression() const { return m_type == isDWARFExpression; }
  190. void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len) {
  191. m_type = isDWARFExpression;
  192. m_value.expr.opcodes = opcodes;
  193. m_value.expr.length = len;
  194. }
  195. uint32_t GetRegisterNumber() const {
  196. if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset)
  197. return m_value.reg.reg_num;
  198. return LLDB_INVALID_REGNUM;
  199. }
  200. ValueType GetValueType() const { return m_type; }
  201. int32_t GetOffset() const {
  202. switch (m_type) {
  203. case isRegisterPlusOffset:
  204. return m_value.reg.offset;
  205. case isRaSearch:
  206. return m_value.ra_search_offset;
  207. default:
  208. return 0;
  209. }
  210. }
  211. void IncOffset(int32_t delta) {
  212. if (m_type == isRegisterPlusOffset)
  213. m_value.reg.offset += delta;
  214. }
  215. void SetOffset(int32_t offset) {
  216. if (m_type == isRegisterPlusOffset)
  217. m_value.reg.offset = offset;
  218. }
  219. void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const {
  220. if (m_type == isDWARFExpression) {
  221. *opcodes = m_value.expr.opcodes;
  222. len = m_value.expr.length;
  223. } else {
  224. *opcodes = nullptr;
  225. len = 0;
  226. }
  227. }
  228. const uint8_t *GetDWARFExpressionBytes() {
  229. if (m_type == isDWARFExpression)
  230. return m_value.expr.opcodes;
  231. return nullptr;
  232. }
  233. int GetDWARFExpressionLength() {
  234. if (m_type == isDWARFExpression)
  235. return m_value.expr.length;
  236. return 0;
  237. }
  238. void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const;
  239. private:
  240. ValueType m_type; // How do we compute CFA value?
  241. union {
  242. struct {
  243. // For m_type == isRegisterPlusOffset or m_type ==
  244. // isRegisterDereferenced
  245. uint32_t reg_num; // The register number
  246. // For m_type == isRegisterPlusOffset
  247. int32_t offset;
  248. } reg;
  249. // For m_type == isDWARFExpression
  250. struct {
  251. const uint8_t *opcodes;
  252. uint16_t length;
  253. } expr;
  254. // For m_type == isRaSearch
  255. int32_t ra_search_offset;
  256. } m_value;
  257. }; // class FAValue
  258. Row();
  259. bool operator==(const Row &rhs) const;
  260. bool GetRegisterInfo(uint32_t reg_num,
  261. RegisterLocation &register_location) const;
  262. void SetRegisterInfo(uint32_t reg_num,
  263. const RegisterLocation register_location);
  264. void RemoveRegisterInfo(uint32_t reg_num);
  265. lldb::addr_t GetOffset() const { return m_offset; }
  266. void SetOffset(lldb::addr_t offset) { m_offset = offset; }
  267. void SlideOffset(lldb::addr_t offset) { m_offset += offset; }
  268. FAValue &GetCFAValue() { return m_cfa_value; }
  269. FAValue &GetAFAValue() { return m_afa_value; }
  270. bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset,
  271. bool can_replace);
  272. bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset,
  273. bool can_replace);
  274. bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace,
  275. bool can_replace_only_if_unspecified);
  276. bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace);
  277. bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num,
  278. bool can_replace);
  279. bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace);
  280. // When this UnspecifiedRegistersAreUndefined mode is
  281. // set, any register that is not specified by this Row will
  282. // be described as Undefined.
  283. // This will prevent the unwinder from iterating down the
  284. // stack looking for a spill location, or a live register value
  285. // at frame 0.
  286. // It would be used for an UnwindPlan row where we can't track
  287. // spilled registers -- for instance a jitted stack frame where
  288. // we have no unwind information or start address -- and registers
  289. // MAY have been spilled and overwritten, so providing the
  290. // spilled/live value from a newer frame may show an incorrect value.
  291. void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef) {
  292. m_unspecified_registers_are_undefined = unspec_is_undef;
  293. }
  294. bool GetUnspecifiedRegistersAreUndefined() {
  295. return m_unspecified_registers_are_undefined;
  296. }
  297. void Clear();
  298. void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread,
  299. lldb::addr_t base_addr) const;
  300. protected:
  301. typedef std::map<uint32_t, RegisterLocation> collection;
  302. lldb::addr_t m_offset; // Offset into the function for this row
  303. FAValue m_cfa_value;
  304. FAValue m_afa_value;
  305. collection m_register_locations;
  306. bool m_unspecified_registers_are_undefined;
  307. }; // class Row
  308. typedef std::shared_ptr<Row> RowSP;
  309. UnwindPlan(lldb::RegisterKind reg_kind)
  310. : m_row_list(), m_plan_valid_address_range(), m_register_kind(reg_kind),
  311. m_return_addr_register(LLDB_INVALID_REGNUM), m_source_name(),
  312. m_plan_is_sourced_from_compiler(eLazyBoolCalculate),
  313. m_plan_is_valid_at_all_instruction_locations(eLazyBoolCalculate),
  314. m_plan_is_for_signal_trap(eLazyBoolCalculate),
  315. m_lsda_address(), m_personality_func_addr() {}
  316. // Performs a deep copy of the plan, including all the rows (expensive).
  317. UnwindPlan(const UnwindPlan &rhs)
  318. : m_plan_valid_address_range(rhs.m_plan_valid_address_range),
  319. m_register_kind(rhs.m_register_kind),
  320. m_return_addr_register(rhs.m_return_addr_register),
  321. m_source_name(rhs.m_source_name),
  322. m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler),
  323. m_plan_is_valid_at_all_instruction_locations(
  324. rhs.m_plan_is_valid_at_all_instruction_locations),
  325. m_plan_is_for_signal_trap(rhs.m_plan_is_for_signal_trap),
  326. m_lsda_address(rhs.m_lsda_address),
  327. m_personality_func_addr(rhs.m_personality_func_addr) {
  328. m_row_list.reserve(rhs.m_row_list.size());
  329. for (const RowSP &row_sp : rhs.m_row_list)
  330. m_row_list.emplace_back(new Row(*row_sp));
  331. }
  332. ~UnwindPlan() = default;
  333. void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const;
  334. void AppendRow(const RowSP &row_sp);
  335. void InsertRow(const RowSP &row_sp, bool replace_existing = false);
  336. // Returns a pointer to the best row for the given offset into the function's
  337. // instructions. If offset is -1 it indicates that the function start is
  338. // unknown - the final row in the UnwindPlan is returned. In practice, the
  339. // UnwindPlan for a function with no known start address will be the
  340. // architectural default UnwindPlan which will only have one row.
  341. UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const;
  342. lldb::RegisterKind GetRegisterKind() const { return m_register_kind; }
  343. void SetRegisterKind(lldb::RegisterKind kind) { m_register_kind = kind; }
  344. void SetReturnAddressRegister(uint32_t regnum) {
  345. m_return_addr_register = regnum;
  346. }
  347. uint32_t GetReturnAddressRegister(void) { return m_return_addr_register; }
  348. uint32_t GetInitialCFARegister() const {
  349. if (m_row_list.empty())
  350. return LLDB_INVALID_REGNUM;
  351. return m_row_list.front()->GetCFAValue().GetRegisterNumber();
  352. }
  353. // This UnwindPlan may not be valid at every address of the function span.
  354. // For instance, a FastUnwindPlan will not be valid at the prologue setup
  355. // instructions - only in the body of the function.
  356. void SetPlanValidAddressRange(const AddressRange &range);
  357. const AddressRange &GetAddressRange() const {
  358. return m_plan_valid_address_range;
  359. }
  360. bool PlanValidAtAddress(Address addr);
  361. bool IsValidRowIndex(uint32_t idx) const;
  362. const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const;
  363. const UnwindPlan::RowSP GetLastRow() const;
  364. lldb_private::ConstString GetSourceName() const;
  365. void SetSourceName(const char *);
  366. // Was this UnwindPlan emitted by a compiler?
  367. lldb_private::LazyBool GetSourcedFromCompiler() const {
  368. return m_plan_is_sourced_from_compiler;
  369. }
  370. // Was this UnwindPlan emitted by a compiler?
  371. void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler) {
  372. m_plan_is_sourced_from_compiler = from_compiler;
  373. }
  374. // Is this UnwindPlan valid at all instructions? If not, then it is assumed
  375. // valid at call sites, e.g. for exception handling.
  376. lldb_private::LazyBool GetUnwindPlanValidAtAllInstructions() const {
  377. return m_plan_is_valid_at_all_instruction_locations;
  378. }
  379. // Is this UnwindPlan valid at all instructions? If not, then it is assumed
  380. // valid at call sites, e.g. for exception handling.
  381. void SetUnwindPlanValidAtAllInstructions(
  382. lldb_private::LazyBool valid_at_all_insn) {
  383. m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
  384. }
  385. // Is this UnwindPlan for a signal trap frame? If so, then its saved pc
  386. // may have been set manually by the signal dispatch code and therefore
  387. // not follow a call to the child frame.
  388. lldb_private::LazyBool GetUnwindPlanForSignalTrap() const {
  389. return m_plan_is_for_signal_trap;
  390. }
  391. void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap) {
  392. m_plan_is_for_signal_trap = is_for_signal_trap;
  393. }
  394. int GetRowCount() const;
  395. void Clear() {
  396. m_row_list.clear();
  397. m_plan_valid_address_range.Clear();
  398. m_register_kind = lldb::eRegisterKindDWARF;
  399. m_source_name.Clear();
  400. m_plan_is_sourced_from_compiler = eLazyBoolCalculate;
  401. m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate;
  402. m_plan_is_for_signal_trap = eLazyBoolCalculate;
  403. m_lsda_address.Clear();
  404. m_personality_func_addr.Clear();
  405. }
  406. const RegisterInfo *GetRegisterInfo(Thread *thread, uint32_t reg_num) const;
  407. Address GetLSDAAddress() const { return m_lsda_address; }
  408. void SetLSDAAddress(Address lsda_addr) { m_lsda_address = lsda_addr; }
  409. Address GetPersonalityFunctionPtr() const { return m_personality_func_addr; }
  410. void SetPersonalityFunctionPtr(Address presonality_func_ptr) {
  411. m_personality_func_addr = presonality_func_ptr;
  412. }
  413. private:
  414. typedef std::vector<RowSP> collection;
  415. collection m_row_list;
  416. AddressRange m_plan_valid_address_range;
  417. lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers
  418. // are in terms of - will need to be
  419. // translated to lldb native reg nums at unwind time
  420. uint32_t m_return_addr_register; // The register that has the return address
  421. // for the caller frame
  422. // e.g. the lr on arm
  423. lldb_private::ConstString
  424. m_source_name; // for logging, where this UnwindPlan originated from
  425. lldb_private::LazyBool m_plan_is_sourced_from_compiler;
  426. lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
  427. lldb_private::LazyBool m_plan_is_for_signal_trap;
  428. Address m_lsda_address; // Where the language specific data area exists in the
  429. // module - used
  430. // in exception handling.
  431. Address m_personality_func_addr; // The address of a pointer to the
  432. // personality function - used in
  433. // exception handling.
  434. }; // class UnwindPlan
  435. } // namespace lldb_private
  436. #endif // LLDB_SYMBOL_UNWINDPLAN_H