1 //===-- x86AssemblyInspectionEngine.h ---------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H
10 #define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H
12 #include "llvm-c/Disassembler.h"
14 #include "lldb/Utility/ArchSpec.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/lldb-enumerations.h"
17 #include "lldb/lldb-forward.h"
18 #include "lldb/lldb-private.h"
23 namespace lldb_private
{
25 // x86AssemblyInspectionEngine - a class which will take a buffer of bytes
26 // of i386/x86_64 instructions and create an UnwindPlan based on those
27 // assembly instructions.
28 class x86AssemblyInspectionEngine
{
32 x86AssemblyInspectionEngine(const lldb_private::ArchSpec
&arch
);
35 ~x86AssemblyInspectionEngine();
37 /// One of the two initialize methods that can be called on this object;
38 /// they must be called before any of the assembly inspection methods
39 /// are called. This one should be used if the caller has access to a
40 /// valid RegisterContext.
41 void Initialize(lldb::RegisterContextSP
®_ctx
);
43 /// One of the two initialize methods that can be called on this object;
44 /// they must be called before any of the assembly inspection methods
45 /// are called. This one takes a vector of register name and lldb
47 struct lldb_reg_info
{
48 const char *name
= nullptr;
49 uint32_t lldb_regnum
= LLDB_INVALID_REGNUM
;
50 lldb_reg_info() = default;
52 void Initialize(std::vector
<lldb_reg_info
> ®_info
);
54 /// Create an UnwindPlan for a "non-call site" stack frame situation.
55 /// This is usually when this function/method is currently executing, and may
57 /// a location where exception-handling style unwind information (eh_frame,
58 /// compact unwind info, arm unwind info)
60 /// \p data is a pointer to the instructions for the function
61 /// \p size is the size of the instruction buffer above
62 /// \p func_range is the start Address and size of the function, to be
63 /// included in the UnwindPlan
64 /// \p unwind_plan is the unwind plan that this method creates
65 /// \returns true if it was able to create an UnwindPlan; false if not.
67 GetNonCallSiteUnwindPlanFromAssembly(uint8_t *data
, size_t size
,
68 lldb_private::AddressRange
&func_range
,
69 lldb_private::UnwindPlan
&unwind_plan
);
71 /// Take an existing UnwindPlan, probably from eh_frame which may be missing
73 /// of the epilogue instructions, and add the epilogue description to it based
75 /// instructions in the function.
77 /// The \p unwind_plan 's register numbers must be converted into the lldb
78 /// register numbering
79 /// scheme OR a RegisterContext must be provided in \p reg_ctx. If the \p
81 /// register numbers are already in lldb register numbering, \p reg_ctx may be
83 /// \returns true if the \p unwind_plan was updated, false if it was not.
84 bool AugmentUnwindPlanFromCallSite(uint8_t *data
, size_t size
,
85 lldb_private::AddressRange
&func_range
,
86 lldb_private::UnwindPlan
&unwind_plan
,
87 lldb::RegisterContextSP
®_ctx
);
89 bool FindFirstNonPrologueInstruction(uint8_t *data
, size_t size
,
93 bool nonvolatile_reg_p(int machine_regno
);
94 bool push_rbp_pattern_p();
95 bool push_0_pattern_p();
96 bool push_imm_pattern_p();
97 bool push_extended_pattern_p();
98 bool push_misc_reg_p();
99 bool mov_rsp_rbp_pattern_p();
100 bool mov_rsp_rbx_pattern_p();
101 bool mov_rbp_rsp_pattern_p();
102 bool mov_rbx_rsp_pattern_p();
103 bool sub_rsp_pattern_p(int &amount
);
104 bool add_rsp_pattern_p(int &amount
);
105 bool lea_rsp_pattern_p(int &amount
);
106 bool lea_rbp_rsp_pattern_p(int &amount
);
107 bool lea_rbx_rsp_pattern_p(int &amount
);
108 bool and_rsp_pattern_p();
109 bool push_reg_p(int ®no
);
110 bool pop_reg_p(int ®no
);
111 bool pop_rbp_pattern_p();
112 bool pop_misc_reg_p();
113 bool leave_pattern_p();
114 bool call_next_insn_pattern_p();
115 bool mov_reg_to_local_stack_frame_p(int ®no
, int &rbp_offset
);
116 bool ret_pattern_p();
118 bool pc_rel_branch_or_jump_p (const int instruction_length
, int &offset
);
119 bool non_local_branch_p (const lldb::addr_t current_func_text_offset
,
120 const lldb_private::AddressRange
&func_range
,
121 const int instruction_length
);
122 bool local_branch_p (const lldb::addr_t current_func_text_offset
,
123 const lldb_private::AddressRange
&func_range
,
124 const int instruction_length
,
125 lldb::addr_t
&target_insn_offset
);
126 uint16_t extract_2(uint8_t *b
);
127 int16_t extract_2_signed(uint8_t *b
);
128 uint32_t extract_4(uint8_t *b
);
129 int32_t extract_4_signed(uint8_t *b
);
131 bool instruction_length(uint8_t *insn
, int &length
, uint32_t buffer_remaining_bytes
);
133 bool machine_regno_to_lldb_regno(int machine_regno
, uint32_t &lldb_regno
);
135 enum CPU
{ k_i386
, k_x86_64
, k_cpu_unspecified
};
137 enum i386_register_numbers
{
149 enum x86_64_register_numbers
{
169 enum { kMaxInstructionByteSize
= 32 };
173 uint32_t m_machine_ip_regnum
;
174 uint32_t m_machine_sp_regnum
;
175 uint32_t m_machine_fp_regnum
;
176 uint32_t m_machine_alt_fp_regnum
;
177 uint32_t m_lldb_ip_regnum
;
178 uint32_t m_lldb_sp_regnum
;
179 uint32_t m_lldb_fp_regnum
;
180 uint32_t m_lldb_alt_fp_regnum
;
182 typedef std::map
<uint32_t, lldb_reg_info
> MachineRegnumToNameAndLLDBRegnum
;
184 MachineRegnumToNameAndLLDBRegnum m_reg_map
;
186 lldb_private::ArchSpec m_arch
;
190 bool m_register_map_initialized
;
192 ::LLVMDisasmContextRef m_disasm_context
;
194 x86AssemblyInspectionEngine(const x86AssemblyInspectionEngine
&) = delete;
195 const x86AssemblyInspectionEngine
&
196 operator=(const x86AssemblyInspectionEngine
&) = delete;
199 } // namespace lldb_private
201 #endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_X86_X86ASSEMBLYINSPECTIONENGINE_H