xref: /openbsd-src/gnu/llvm/lldb/source/Target/ABI.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- ABI.cpp -----------------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Target/ABI.h"
10061da546Spatrick #include "lldb/Core/PluginManager.h"
11061da546Spatrick #include "lldb/Core/Value.h"
12061da546Spatrick #include "lldb/Core/ValueObjectConstResult.h"
13061da546Spatrick #include "lldb/Expression/ExpressionVariable.h"
14061da546Spatrick #include "lldb/Symbol/CompilerType.h"
15061da546Spatrick #include "lldb/Symbol/TypeSystem.h"
16061da546Spatrick #include "lldb/Target/Target.h"
17061da546Spatrick #include "lldb/Target/Thread.h"
18*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
19061da546Spatrick #include "lldb/Utility/Log.h"
20*f6aab3d8Srobert #include "llvm/MC/TargetRegistry.h"
21dda28197Spatrick #include <cctype>
22061da546Spatrick 
23061da546Spatrick using namespace lldb;
24061da546Spatrick using namespace lldb_private;
25061da546Spatrick 
26061da546Spatrick ABISP
FindPlugin(lldb::ProcessSP process_sp,const ArchSpec & arch)27061da546Spatrick ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) {
28061da546Spatrick   ABISP abi_sp;
29061da546Spatrick   ABICreateInstance create_callback;
30061da546Spatrick 
31061da546Spatrick   for (uint32_t idx = 0;
32061da546Spatrick        (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) !=
33061da546Spatrick        nullptr;
34061da546Spatrick        ++idx) {
35061da546Spatrick     abi_sp = create_callback(process_sp, arch);
36061da546Spatrick 
37061da546Spatrick     if (abi_sp)
38061da546Spatrick       return abi_sp;
39061da546Spatrick   }
40061da546Spatrick   abi_sp.reset();
41061da546Spatrick   return abi_sp;
42061da546Spatrick }
43061da546Spatrick 
44061da546Spatrick ABI::~ABI() = default;
45061da546Spatrick 
GetRegisterInfoByName(llvm::StringRef name,RegisterInfo & info)46be691f3bSpatrick bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name,
47be691f3bSpatrick                                             RegisterInfo &info) {
48061da546Spatrick   uint32_t count = 0;
49061da546Spatrick   const RegisterInfo *register_info_array = GetRegisterInfoArray(count);
50061da546Spatrick   if (register_info_array) {
51061da546Spatrick     uint32_t i;
52061da546Spatrick     for (i = 0; i < count; ++i) {
53dda28197Spatrick       const char *reg_name = register_info_array[i].name;
54be691f3bSpatrick       if (reg_name == name) {
55061da546Spatrick         info = register_info_array[i];
56061da546Spatrick         return true;
57061da546Spatrick       }
58061da546Spatrick     }
59061da546Spatrick     for (i = 0; i < count; ++i) {
60dda28197Spatrick       const char *reg_alt_name = register_info_array[i].alt_name;
61be691f3bSpatrick       if (reg_alt_name == name) {
62061da546Spatrick         info = register_info_array[i];
63061da546Spatrick         return true;
64061da546Spatrick       }
65061da546Spatrick     }
66061da546Spatrick   }
67061da546Spatrick   return false;
68061da546Spatrick }
69061da546Spatrick 
GetReturnValueObject(Thread & thread,CompilerType & ast_type,bool persistent) const70061da546Spatrick ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
71061da546Spatrick                                         bool persistent) const {
72061da546Spatrick   if (!ast_type.IsValid())
73061da546Spatrick     return ValueObjectSP();
74061da546Spatrick 
75061da546Spatrick   ValueObjectSP return_valobj_sp;
76061da546Spatrick 
77061da546Spatrick   return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
78061da546Spatrick   if (!return_valobj_sp)
79061da546Spatrick     return return_valobj_sp;
80061da546Spatrick 
81061da546Spatrick   // Now turn this into a persistent variable.
82061da546Spatrick   // FIXME: This code is duplicated from Target::EvaluateExpression, and it is
83061da546Spatrick   // used in similar form in a couple
84061da546Spatrick   // of other places.  Figure out the correct Create function to do all this
85061da546Spatrick   // work.
86061da546Spatrick 
87061da546Spatrick   if (persistent) {
88061da546Spatrick     Target &target = *thread.CalculateTarget();
89061da546Spatrick     PersistentExpressionState *persistent_expression_state =
90061da546Spatrick         target.GetPersistentExpressionStateForLanguage(
91061da546Spatrick             ast_type.GetMinimumLanguage());
92061da546Spatrick 
93061da546Spatrick     if (!persistent_expression_state)
94061da546Spatrick       return {};
95061da546Spatrick 
96061da546Spatrick     ConstString persistent_variable_name =
97dda28197Spatrick         persistent_expression_state->GetNextPersistentVariableName();
98061da546Spatrick 
99061da546Spatrick     lldb::ValueObjectSP const_valobj_sp;
100061da546Spatrick 
101061da546Spatrick     // Check in case our value is already a constant value
102061da546Spatrick     if (return_valobj_sp->GetIsConstant()) {
103061da546Spatrick       const_valobj_sp = return_valobj_sp;
104061da546Spatrick       const_valobj_sp->SetName(persistent_variable_name);
105061da546Spatrick     } else
106061da546Spatrick       const_valobj_sp =
107061da546Spatrick           return_valobj_sp->CreateConstantValue(persistent_variable_name);
108061da546Spatrick 
109061da546Spatrick     lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
110061da546Spatrick 
111061da546Spatrick     return_valobj_sp = const_valobj_sp;
112061da546Spatrick 
113061da546Spatrick     ExpressionVariableSP expr_variable_sp(
114061da546Spatrick         persistent_expression_state->CreatePersistentVariable(
115061da546Spatrick             return_valobj_sp));
116061da546Spatrick 
117061da546Spatrick     assert(expr_variable_sp);
118061da546Spatrick 
119061da546Spatrick     // Set flags and live data as appropriate
120061da546Spatrick 
121061da546Spatrick     const Value &result_value = live_valobj_sp->GetValue();
122061da546Spatrick 
123061da546Spatrick     switch (result_value.GetValueType()) {
124be691f3bSpatrick     case Value::ValueType::Invalid:
125be691f3bSpatrick       return {};
126be691f3bSpatrick     case Value::ValueType::HostAddress:
127be691f3bSpatrick     case Value::ValueType::FileAddress:
128be691f3bSpatrick       // we odon't do anything with these for now
129061da546Spatrick       break;
130be691f3bSpatrick     case Value::ValueType::Scalar:
131061da546Spatrick       expr_variable_sp->m_flags |=
132061da546Spatrick           ExpressionVariable::EVIsFreezeDried;
133061da546Spatrick       expr_variable_sp->m_flags |=
134061da546Spatrick           ExpressionVariable::EVIsLLDBAllocated;
135061da546Spatrick       expr_variable_sp->m_flags |=
136061da546Spatrick           ExpressionVariable::EVNeedsAllocation;
137061da546Spatrick       break;
138be691f3bSpatrick     case Value::ValueType::LoadAddress:
139061da546Spatrick       expr_variable_sp->m_live_sp = live_valobj_sp;
140061da546Spatrick       expr_variable_sp->m_flags |=
141061da546Spatrick           ExpressionVariable::EVIsProgramReference;
142061da546Spatrick       break;
143061da546Spatrick     }
144061da546Spatrick 
145061da546Spatrick     return_valobj_sp = expr_variable_sp->GetValueObject();
146061da546Spatrick   }
147061da546Spatrick   return return_valobj_sp;
148061da546Spatrick }
149061da546Spatrick 
GetReturnValueObject(Thread & thread,llvm::Type & ast_type,bool persistent) const150061da546Spatrick ValueObjectSP ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type,
151061da546Spatrick                                         bool persistent) const {
152061da546Spatrick   ValueObjectSP return_valobj_sp;
153061da546Spatrick   return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
154061da546Spatrick   return return_valobj_sp;
155061da546Spatrick }
156061da546Spatrick 
157061da546Spatrick // specialized to work with llvm IR types
158061da546Spatrick //
159061da546Spatrick // for now we will specify a default implementation so that we don't need to
160061da546Spatrick // modify other ABIs
GetReturnValueObjectImpl(Thread & thread,llvm::Type & ir_type) const161061da546Spatrick lldb::ValueObjectSP ABI::GetReturnValueObjectImpl(Thread &thread,
162061da546Spatrick                                                   llvm::Type &ir_type) const {
163061da546Spatrick   ValueObjectSP return_valobj_sp;
164061da546Spatrick 
165061da546Spatrick   /* this is a dummy and will only be called if an ABI does not override this */
166061da546Spatrick 
167061da546Spatrick   return return_valobj_sp;
168061da546Spatrick }
169061da546Spatrick 
PrepareTrivialCall(Thread & thread,lldb::addr_t sp,lldb::addr_t functionAddress,lldb::addr_t returnAddress,llvm::Type & returntype,llvm::ArrayRef<ABI::CallArgument> args) const170061da546Spatrick bool ABI::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
171061da546Spatrick                              lldb::addr_t functionAddress,
172061da546Spatrick                              lldb::addr_t returnAddress, llvm::Type &returntype,
173061da546Spatrick                              llvm::ArrayRef<ABI::CallArgument> args) const {
174061da546Spatrick   // dummy prepare trivial call
175061da546Spatrick   llvm_unreachable("Should never get here!");
176061da546Spatrick }
177061da546Spatrick 
GetFallbackRegisterLocation(const RegisterInfo * reg_info,UnwindPlan::Row::RegisterLocation & unwind_regloc)178061da546Spatrick bool ABI::GetFallbackRegisterLocation(
179061da546Spatrick     const RegisterInfo *reg_info,
180061da546Spatrick     UnwindPlan::Row::RegisterLocation &unwind_regloc) {
181061da546Spatrick   // Did the UnwindPlan fail to give us the caller's stack pointer? The stack
182061da546Spatrick   // pointer is defined to be the same as THIS frame's CFA, so return the CFA
183061da546Spatrick   // value as the caller's stack pointer.  This is true on x86-32/x86-64 at
184061da546Spatrick   // least.
185061da546Spatrick   if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) {
186061da546Spatrick     unwind_regloc.SetIsCFAPlusOffset(0);
187061da546Spatrick     return true;
188061da546Spatrick   }
189061da546Spatrick 
190061da546Spatrick   // If a volatile register is being requested, we don't want to forward the
191061da546Spatrick   // next frame's register contents up the stack -- the register is not
192061da546Spatrick   // retrievable at this frame.
193061da546Spatrick   if (RegisterIsVolatile(reg_info)) {
194061da546Spatrick     unwind_regloc.SetUndefined();
195061da546Spatrick     return true;
196061da546Spatrick   }
197061da546Spatrick 
198061da546Spatrick   return false;
199061da546Spatrick }
200061da546Spatrick 
MakeMCRegisterInfo(const ArchSpec & arch)201061da546Spatrick std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) {
202061da546Spatrick   std::string triple = arch.GetTriple().getTriple();
203061da546Spatrick   std::string lookup_error;
204061da546Spatrick   const llvm::Target *target =
205061da546Spatrick       llvm::TargetRegistry::lookupTarget(triple, lookup_error);
206061da546Spatrick   if (!target) {
207*f6aab3d8Srobert     LLDB_LOG(GetLog(LLDBLog::Process),
208061da546Spatrick              "Failed to create an llvm target for {0}: {1}", triple,
209061da546Spatrick              lookup_error);
210061da546Spatrick     return nullptr;
211061da546Spatrick   }
212061da546Spatrick   std::unique_ptr<llvm::MCRegisterInfo> info_up(
213061da546Spatrick       target->createMCRegInfo(triple));
214061da546Spatrick   assert(info_up);
215061da546Spatrick   return info_up;
216061da546Spatrick }
217061da546Spatrick 
AugmentRegisterInfo(std::vector<DynamicRegisterInfo::Register> & regs)218*f6aab3d8Srobert void RegInfoBasedABI::AugmentRegisterInfo(
219*f6aab3d8Srobert     std::vector<DynamicRegisterInfo::Register> &regs) {
220*f6aab3d8Srobert   for (DynamicRegisterInfo::Register &info : regs) {
221*f6aab3d8Srobert     if (info.regnum_ehframe != LLDB_INVALID_REGNUM &&
222*f6aab3d8Srobert         info.regnum_dwarf != LLDB_INVALID_REGNUM)
223*f6aab3d8Srobert       continue;
224061da546Spatrick 
225061da546Spatrick     RegisterInfo abi_info;
226*f6aab3d8Srobert     if (!GetRegisterInfoByName(info.name.GetStringRef(), abi_info))
227*f6aab3d8Srobert       continue;
228061da546Spatrick 
229*f6aab3d8Srobert     if (info.regnum_ehframe == LLDB_INVALID_REGNUM)
230*f6aab3d8Srobert       info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame];
231*f6aab3d8Srobert     if (info.regnum_dwarf == LLDB_INVALID_REGNUM)
232*f6aab3d8Srobert       info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF];
233*f6aab3d8Srobert     if (info.regnum_generic == LLDB_INVALID_REGNUM)
234*f6aab3d8Srobert       info.regnum_generic = abi_info.kinds[eRegisterKindGeneric];
235*f6aab3d8Srobert   }
236061da546Spatrick }
237dda28197Spatrick 
AugmentRegisterInfo(std::vector<DynamicRegisterInfo::Register> & regs)238*f6aab3d8Srobert void MCBasedABI::AugmentRegisterInfo(
239*f6aab3d8Srobert     std::vector<DynamicRegisterInfo::Register> &regs) {
240*f6aab3d8Srobert   for (DynamicRegisterInfo::Register &info : regs) {
241dda28197Spatrick     uint32_t eh, dwarf;
242*f6aab3d8Srobert     std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name.GetStringRef());
243dda28197Spatrick 
244*f6aab3d8Srobert     if (info.regnum_ehframe == LLDB_INVALID_REGNUM)
245*f6aab3d8Srobert       info.regnum_ehframe = eh;
246*f6aab3d8Srobert     if (info.regnum_dwarf == LLDB_INVALID_REGNUM)
247*f6aab3d8Srobert       info.regnum_dwarf = dwarf;
248*f6aab3d8Srobert     if (info.regnum_generic == LLDB_INVALID_REGNUM)
249*f6aab3d8Srobert       info.regnum_generic = GetGenericNum(info.name.GetStringRef());
250*f6aab3d8Srobert   }
251dda28197Spatrick }
252dda28197Spatrick 
253dda28197Spatrick std::pair<uint32_t, uint32_t>
GetEHAndDWARFNums(llvm::StringRef name)254dda28197Spatrick MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) {
255dda28197Spatrick   std::string mc_name = GetMCName(name.str());
256dda28197Spatrick   for (char &c : mc_name)
257dda28197Spatrick     c = std::toupper(c);
258dda28197Spatrick   int eh = -1;
259dda28197Spatrick   int dwarf = -1;
260dda28197Spatrick   for (unsigned reg = 0; reg < m_mc_register_info_up->getNumRegs(); ++reg) {
261dda28197Spatrick     if (m_mc_register_info_up->getName(reg) == mc_name) {
262dda28197Spatrick       eh = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/true);
263dda28197Spatrick       dwarf = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/false);
264dda28197Spatrick       break;
265dda28197Spatrick     }
266dda28197Spatrick   }
267dda28197Spatrick   return std::pair<uint32_t, uint32_t>(eh == -1 ? LLDB_INVALID_REGNUM : eh,
268dda28197Spatrick                                        dwarf == -1 ? LLDB_INVALID_REGNUM
269dda28197Spatrick                                                    : dwarf);
270dda28197Spatrick }
271dda28197Spatrick 
MapRegisterName(std::string & name,llvm::StringRef from_prefix,llvm::StringRef to_prefix)272dda28197Spatrick void MCBasedABI::MapRegisterName(std::string &name, llvm::StringRef from_prefix,
273dda28197Spatrick                                  llvm::StringRef to_prefix) {
274dda28197Spatrick   llvm::StringRef name_ref = name;
275dda28197Spatrick   if (!name_ref.consume_front(from_prefix))
276dda28197Spatrick     return;
277dda28197Spatrick   uint64_t _;
278dda28197Spatrick   if (name_ref.empty() || to_integer(name_ref, _, 10))
279dda28197Spatrick     name = (to_prefix + name_ref).str();
280dda28197Spatrick }
281