1 //===-- ABI.cpp -----------------------------------------------------------===//
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 #include "lldb/Target/ABI.h"
10 #include "lldb/Core/PluginManager.h"
11 #include "lldb/Core/Value.h"
12 #include "lldb/Core/ValueObjectConstResult.h"
13 #include "lldb/Expression/ExpressionVariable.h"
14 #include "lldb/Symbol/CompilerType.h"
15 #include "lldb/Symbol/TypeSystem.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/LLDBLog.h"
19 #include "lldb/Utility/Log.h"
20 #include "llvm/MC/TargetRegistry.h"
24 using namespace lldb_private
;
27 ABI::FindPlugin(lldb::ProcessSP process_sp
, const ArchSpec
&arch
) {
29 ABICreateInstance create_callback
;
31 for (uint32_t idx
= 0;
32 (create_callback
= PluginManager::GetABICreateCallbackAtIndex(idx
)) !=
35 abi_sp
= create_callback(process_sp
, arch
);
44 ABI::~ABI() = default;
46 bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name
,
49 const RegisterInfo
*register_info_array
= GetRegisterInfoArray(count
);
50 if (register_info_array
) {
52 for (i
= 0; i
< count
; ++i
) {
53 const char *reg_name
= register_info_array
[i
].name
;
54 if (reg_name
== name
) {
55 info
= register_info_array
[i
];
59 for (i
= 0; i
< count
; ++i
) {
60 const char *reg_alt_name
= register_info_array
[i
].alt_name
;
61 if (reg_alt_name
== name
) {
62 info
= register_info_array
[i
];
70 ValueObjectSP
ABI::GetReturnValueObject(Thread
&thread
, CompilerType
&ast_type
,
71 bool persistent
) const {
72 if (!ast_type
.IsValid())
73 return ValueObjectSP();
75 ValueObjectSP return_valobj_sp
;
77 return_valobj_sp
= GetReturnValueObjectImpl(thread
, ast_type
);
78 if (!return_valobj_sp
)
79 return return_valobj_sp
;
81 // Now turn this into a persistent variable.
82 // FIXME: This code is duplicated from Target::EvaluateExpression, and it is
83 // used in similar form in a couple
84 // of other places. Figure out the correct Create function to do all this
88 Target
&target
= *thread
.CalculateTarget();
89 PersistentExpressionState
*persistent_expression_state
=
90 target
.GetPersistentExpressionStateForLanguage(
91 ast_type
.GetMinimumLanguage());
93 if (!persistent_expression_state
)
96 ConstString persistent_variable_name
=
97 persistent_expression_state
->GetNextPersistentVariableName();
99 lldb::ValueObjectSP const_valobj_sp
;
101 // Check in case our value is already a constant value
102 if (return_valobj_sp
->GetIsConstant()) {
103 const_valobj_sp
= return_valobj_sp
;
104 const_valobj_sp
->SetName(persistent_variable_name
);
107 return_valobj_sp
->CreateConstantValue(persistent_variable_name
);
109 lldb::ValueObjectSP live_valobj_sp
= return_valobj_sp
;
111 return_valobj_sp
= const_valobj_sp
;
113 ExpressionVariableSP
expr_variable_sp(
114 persistent_expression_state
->CreatePersistentVariable(
117 assert(expr_variable_sp
);
119 // Set flags and live data as appropriate
121 const Value
&result_value
= live_valobj_sp
->GetValue();
123 switch (result_value
.GetValueType()) {
124 case Value::ValueType::Invalid
:
126 case Value::ValueType::HostAddress
:
127 case Value::ValueType::FileAddress
:
128 // we odon't do anything with these for now
130 case Value::ValueType::Scalar
:
131 expr_variable_sp
->m_flags
|=
132 ExpressionVariable::EVIsFreezeDried
;
133 expr_variable_sp
->m_flags
|=
134 ExpressionVariable::EVIsLLDBAllocated
;
135 expr_variable_sp
->m_flags
|=
136 ExpressionVariable::EVNeedsAllocation
;
138 case Value::ValueType::LoadAddress
:
139 expr_variable_sp
->m_live_sp
= live_valobj_sp
;
140 expr_variable_sp
->m_flags
|=
141 ExpressionVariable::EVIsProgramReference
;
145 return_valobj_sp
= expr_variable_sp
->GetValueObject();
147 return return_valobj_sp
;
150 ValueObjectSP
ABI::GetReturnValueObject(Thread
&thread
, llvm::Type
&ast_type
,
151 bool persistent
) const {
152 ValueObjectSP return_valobj_sp
;
153 return_valobj_sp
= GetReturnValueObjectImpl(thread
, ast_type
);
154 return return_valobj_sp
;
157 // specialized to work with llvm IR types
159 // for now we will specify a default implementation so that we don't need to
161 lldb::ValueObjectSP
ABI::GetReturnValueObjectImpl(Thread
&thread
,
162 llvm::Type
&ir_type
) const {
163 ValueObjectSP return_valobj_sp
;
165 /* this is a dummy and will only be called if an ABI does not override this */
167 return return_valobj_sp
;
170 bool ABI::PrepareTrivialCall(Thread
&thread
, lldb::addr_t sp
,
171 lldb::addr_t functionAddress
,
172 lldb::addr_t returnAddress
, llvm::Type
&returntype
,
173 llvm::ArrayRef
<ABI::CallArgument
> args
) const {
174 // dummy prepare trivial call
175 llvm_unreachable("Should never get here!");
178 bool ABI::GetFallbackRegisterLocation(
179 const RegisterInfo
*reg_info
,
180 UnwindPlan::Row::RegisterLocation
&unwind_regloc
) {
181 // Did the UnwindPlan fail to give us the caller's stack pointer? The stack
182 // pointer is defined to be the same as THIS frame's CFA, so return the CFA
183 // value as the caller's stack pointer. This is true on x86-32/x86-64 at
185 if (reg_info
->kinds
[eRegisterKindGeneric
] == LLDB_REGNUM_GENERIC_SP
) {
186 unwind_regloc
.SetIsCFAPlusOffset(0);
190 // If a volatile register is being requested, we don't want to forward the
191 // next frame's register contents up the stack -- the register is not
192 // retrievable at this frame.
193 if (RegisterIsVolatile(reg_info
)) {
194 unwind_regloc
.SetUndefined();
201 std::unique_ptr
<llvm::MCRegisterInfo
> ABI::MakeMCRegisterInfo(const ArchSpec
&arch
) {
202 std::string triple
= arch
.GetTriple().getTriple();
203 std::string lookup_error
;
204 const llvm::Target
*target
=
205 llvm::TargetRegistry::lookupTarget(triple
, lookup_error
);
207 LLDB_LOG(GetLog(LLDBLog::Process
),
208 "Failed to create an llvm target for {0}: {1}", triple
,
212 std::unique_ptr
<llvm::MCRegisterInfo
> info_up(
213 target
->createMCRegInfo(triple
));
218 void RegInfoBasedABI::AugmentRegisterInfo(
219 std::vector
<DynamicRegisterInfo::Register
> ®s
) {
220 for (DynamicRegisterInfo::Register
&info
: regs
) {
221 if (info
.regnum_ehframe
!= LLDB_INVALID_REGNUM
&&
222 info
.regnum_dwarf
!= LLDB_INVALID_REGNUM
)
225 RegisterInfo abi_info
;
226 if (!GetRegisterInfoByName(info
.name
.GetStringRef(), abi_info
))
229 if (info
.regnum_ehframe
== LLDB_INVALID_REGNUM
)
230 info
.regnum_ehframe
= abi_info
.kinds
[eRegisterKindEHFrame
];
231 if (info
.regnum_dwarf
== LLDB_INVALID_REGNUM
)
232 info
.regnum_dwarf
= abi_info
.kinds
[eRegisterKindDWARF
];
233 if (info
.regnum_generic
== LLDB_INVALID_REGNUM
)
234 info
.regnum_generic
= abi_info
.kinds
[eRegisterKindGeneric
];
238 void MCBasedABI::AugmentRegisterInfo(
239 std::vector
<DynamicRegisterInfo::Register
> ®s
) {
240 for (DynamicRegisterInfo::Register
&info
: regs
) {
242 std::tie(eh
, dwarf
) = GetEHAndDWARFNums(info
.name
.GetStringRef());
244 if (info
.regnum_ehframe
== LLDB_INVALID_REGNUM
)
245 info
.regnum_ehframe
= eh
;
246 if (info
.regnum_dwarf
== LLDB_INVALID_REGNUM
)
247 info
.regnum_dwarf
= dwarf
;
248 if (info
.regnum_generic
== LLDB_INVALID_REGNUM
)
249 info
.regnum_generic
= GetGenericNum(info
.name
.GetStringRef());
253 std::pair
<uint32_t, uint32_t>
254 MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name
) {
255 std::string mc_name
= GetMCName(name
.str());
256 for (char &c
: mc_name
)
260 for (unsigned reg
= 0; reg
< m_mc_register_info_up
->getNumRegs(); ++reg
) {
261 if (m_mc_register_info_up
->getName(reg
) == mc_name
) {
262 eh
= m_mc_register_info_up
->getDwarfRegNum(reg
, /*isEH=*/true);
263 dwarf
= m_mc_register_info_up
->getDwarfRegNum(reg
, /*isEH=*/false);
267 return std::pair
<uint32_t, uint32_t>(eh
== -1 ? LLDB_INVALID_REGNUM
: eh
,
268 dwarf
== -1 ? LLDB_INVALID_REGNUM
272 void MCBasedABI::MapRegisterName(std::string
&name
, llvm::StringRef from_prefix
,
273 llvm::StringRef to_prefix
) {
274 llvm::StringRef name_ref
= name
;
275 if (!name_ref
.consume_front(from_prefix
))
278 if (name_ref
.empty() || to_integer(name_ref
, _
, 10))
279 name
= (to_prefix
+ name_ref
).str();