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/Log.h"
19 #include "llvm/MC/TargetRegistry.h"
23 using namespace lldb_private
;
26 ABI::FindPlugin(lldb::ProcessSP process_sp
, const ArchSpec
&arch
) {
28 ABICreateInstance create_callback
;
30 for (uint32_t idx
= 0;
31 (create_callback
= PluginManager::GetABICreateCallbackAtIndex(idx
)) !=
34 abi_sp
= create_callback(process_sp
, arch
);
43 ABI::~ABI() = default;
45 bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name
,
48 const RegisterInfo
*register_info_array
= GetRegisterInfoArray(count
);
49 if (register_info_array
) {
51 for (i
= 0; i
< count
; ++i
) {
52 const char *reg_name
= register_info_array
[i
].name
;
53 if (reg_name
== name
) {
54 info
= register_info_array
[i
];
58 for (i
= 0; i
< count
; ++i
) {
59 const char *reg_alt_name
= register_info_array
[i
].alt_name
;
60 if (reg_alt_name
== name
) {
61 info
= register_info_array
[i
];
69 ValueObjectSP
ABI::GetReturnValueObject(Thread
&thread
, CompilerType
&ast_type
,
70 bool persistent
) const {
71 if (!ast_type
.IsValid())
72 return ValueObjectSP();
74 ValueObjectSP return_valobj_sp
;
76 return_valobj_sp
= GetReturnValueObjectImpl(thread
, ast_type
);
77 if (!return_valobj_sp
)
78 return return_valobj_sp
;
80 // Now turn this into a persistent variable.
81 // FIXME: This code is duplicated from Target::EvaluateExpression, and it is
82 // used in similar form in a couple
83 // of other places. Figure out the correct Create function to do all this
87 Target
&target
= *thread
.CalculateTarget();
88 PersistentExpressionState
*persistent_expression_state
=
89 target
.GetPersistentExpressionStateForLanguage(
90 ast_type
.GetMinimumLanguage());
92 if (!persistent_expression_state
)
95 ConstString persistent_variable_name
=
96 persistent_expression_state
->GetNextPersistentVariableName();
98 lldb::ValueObjectSP const_valobj_sp
;
100 // Check in case our value is already a constant value
101 if (return_valobj_sp
->GetIsConstant()) {
102 const_valobj_sp
= return_valobj_sp
;
103 const_valobj_sp
->SetName(persistent_variable_name
);
106 return_valobj_sp
->CreateConstantValue(persistent_variable_name
);
108 lldb::ValueObjectSP live_valobj_sp
= return_valobj_sp
;
110 return_valobj_sp
= const_valobj_sp
;
112 ExpressionVariableSP
expr_variable_sp(
113 persistent_expression_state
->CreatePersistentVariable(
116 assert(expr_variable_sp
);
118 // Set flags and live data as appropriate
120 const Value
&result_value
= live_valobj_sp
->GetValue();
122 switch (result_value
.GetValueType()) {
123 case Value::ValueType::Invalid
:
125 case Value::ValueType::HostAddress
:
126 case Value::ValueType::FileAddress
:
127 // we odon't do anything with these for now
129 case Value::ValueType::Scalar
:
130 expr_variable_sp
->m_flags
|=
131 ExpressionVariable::EVIsFreezeDried
;
132 expr_variable_sp
->m_flags
|=
133 ExpressionVariable::EVIsLLDBAllocated
;
134 expr_variable_sp
->m_flags
|=
135 ExpressionVariable::EVNeedsAllocation
;
137 case Value::ValueType::LoadAddress
:
138 expr_variable_sp
->m_live_sp
= live_valobj_sp
;
139 expr_variable_sp
->m_flags
|=
140 ExpressionVariable::EVIsProgramReference
;
144 return_valobj_sp
= expr_variable_sp
->GetValueObject();
146 return return_valobj_sp
;
149 ValueObjectSP
ABI::GetReturnValueObject(Thread
&thread
, llvm::Type
&ast_type
,
150 bool persistent
) const {
151 ValueObjectSP return_valobj_sp
;
152 return_valobj_sp
= GetReturnValueObjectImpl(thread
, ast_type
);
153 return return_valobj_sp
;
156 // specialized to work with llvm IR types
158 // for now we will specify a default implementation so that we don't need to
160 lldb::ValueObjectSP
ABI::GetReturnValueObjectImpl(Thread
&thread
,
161 llvm::Type
&ir_type
) const {
162 ValueObjectSP return_valobj_sp
;
164 /* this is a dummy and will only be called if an ABI does not override this */
166 return return_valobj_sp
;
169 bool ABI::PrepareTrivialCall(Thread
&thread
, lldb::addr_t sp
,
170 lldb::addr_t functionAddress
,
171 lldb::addr_t returnAddress
, llvm::Type
&returntype
,
172 llvm::ArrayRef
<ABI::CallArgument
> args
) const {
173 // dummy prepare trivial call
174 llvm_unreachable("Should never get here!");
177 bool ABI::GetFallbackRegisterLocation(
178 const RegisterInfo
*reg_info
,
179 UnwindPlan::Row::RegisterLocation
&unwind_regloc
) {
180 // Did the UnwindPlan fail to give us the caller's stack pointer? The stack
181 // pointer is defined to be the same as THIS frame's CFA, so return the CFA
182 // value as the caller's stack pointer. This is true on x86-32/x86-64 at
184 if (reg_info
->kinds
[eRegisterKindGeneric
] == LLDB_REGNUM_GENERIC_SP
) {
185 unwind_regloc
.SetIsCFAPlusOffset(0);
189 // If a volatile register is being requested, we don't want to forward the
190 // next frame's register contents up the stack -- the register is not
191 // retrievable at this frame.
192 if (RegisterIsVolatile(reg_info
)) {
193 unwind_regloc
.SetUndefined();
200 std::unique_ptr
<llvm::MCRegisterInfo
> ABI::MakeMCRegisterInfo(const ArchSpec
&arch
) {
201 std::string triple
= arch
.GetTriple().getTriple();
202 std::string lookup_error
;
203 const llvm::Target
*target
=
204 llvm::TargetRegistry::lookupTarget(triple
, lookup_error
);
206 LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS
),
207 "Failed to create an llvm target for {0}: {1}", triple
,
211 std::unique_ptr
<llvm::MCRegisterInfo
> info_up(
212 target
->createMCRegInfo(triple
));
217 void RegInfoBasedABI::AugmentRegisterInfo(
218 std::vector
<DynamicRegisterInfo::Register
> ®s
) {
219 for (DynamicRegisterInfo::Register
&info
: regs
) {
220 if (info
.regnum_ehframe
!= LLDB_INVALID_REGNUM
&&
221 info
.regnum_dwarf
!= LLDB_INVALID_REGNUM
)
224 RegisterInfo abi_info
;
225 if (!GetRegisterInfoByName(info
.name
.GetStringRef(), abi_info
))
228 if (info
.regnum_ehframe
== LLDB_INVALID_REGNUM
)
229 info
.regnum_ehframe
= abi_info
.kinds
[eRegisterKindEHFrame
];
230 if (info
.regnum_dwarf
== LLDB_INVALID_REGNUM
)
231 info
.regnum_dwarf
= abi_info
.kinds
[eRegisterKindDWARF
];
232 if (info
.regnum_generic
== LLDB_INVALID_REGNUM
)
233 info
.regnum_generic
= abi_info
.kinds
[eRegisterKindGeneric
];
237 void MCBasedABI::AugmentRegisterInfo(
238 std::vector
<DynamicRegisterInfo::Register
> ®s
) {
239 for (DynamicRegisterInfo::Register
&info
: regs
) {
241 std::tie(eh
, dwarf
) = GetEHAndDWARFNums(info
.name
.GetStringRef());
243 if (info
.regnum_ehframe
== LLDB_INVALID_REGNUM
)
244 info
.regnum_ehframe
= eh
;
245 if (info
.regnum_dwarf
== LLDB_INVALID_REGNUM
)
246 info
.regnum_dwarf
= dwarf
;
247 if (info
.regnum_generic
== LLDB_INVALID_REGNUM
)
248 info
.regnum_generic
= GetGenericNum(info
.name
.GetStringRef());
252 std::pair
<uint32_t, uint32_t>
253 MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name
) {
254 std::string mc_name
= GetMCName(name
.str());
255 for (char &c
: mc_name
)
259 for (unsigned reg
= 0; reg
< m_mc_register_info_up
->getNumRegs(); ++reg
) {
260 if (m_mc_register_info_up
->getName(reg
) == mc_name
) {
261 eh
= m_mc_register_info_up
->getDwarfRegNum(reg
, /*isEH=*/true);
262 dwarf
= m_mc_register_info_up
->getDwarfRegNum(reg
, /*isEH=*/false);
266 return std::pair
<uint32_t, uint32_t>(eh
== -1 ? LLDB_INVALID_REGNUM
: eh
,
267 dwarf
== -1 ? LLDB_INVALID_REGNUM
271 void MCBasedABI::MapRegisterName(std::string
&name
, llvm::StringRef from_prefix
,
272 llvm::StringRef to_prefix
) {
273 llvm::StringRef name_ref
= name
;
274 if (!name_ref
.consume_front(from_prefix
))
277 if (name_ref
.empty() || to_integer(name_ref
, _
, 10))
278 name
= (to_prefix
+ name_ref
).str();