LLDB  mainline
ABISysV_i386.cpp
Go to the documentation of this file.
1 //===----------------------- ABISysV_i386.cpp -------------------*- 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 #include "ABISysV_i386.h"
9 
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/Triple.h"
12 
13 #include "lldb/Core/Module.h"
15 #include "lldb/Core/Value.h"
19 #include "lldb/Symbol/UnwindPlan.h"
20 #include "lldb/Target/Process.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/Log.h"
29 #include "lldb/Utility/Status.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // This source file uses the following document as a reference:
35 //====================================================================
36 // System V Application Binary Interface
37 // Intel386 Architecture Processor Supplement, Version 1.0
38 // Edited by
39 // H.J. Lu, David L Kreitzer, Milind Girkar, Zia Ansari
40 //
41 // (Based on
42 // System V Application Binary Interface,
43 // AMD64 Architecture Processor Supplement,
44 // Edited by
45 // H.J. Lu, Michael Matz, Milind Girkar, Jan Hubicka,
46 // Andreas Jaeger, Mark Mitchell)
47 //
48 // February 3, 2015
49 //====================================================================
50 
51 // DWARF Register Number Mapping
52 // See Table 2.14 of the reference document (specified on top of this file)
53 // Comment: Table 2.14 is followed till 'mm' entries. After that, all entries
54 // are ignored here.
55 
57  dwarf_eax = 0,
67 
68  dwarf_st0 = 11,
76 
77  dwarf_xmm0 = 21,
93 
94  dwarf_mm0 = 29,
102 
103  dwarf_bnd0 = 101,
107 };
108 
109 static RegisterInfo g_register_infos[] = {
110  // clang-format off
111  //NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE INVAL DYN EXPR SZ
112  //========== ======= == === ============= ==================== =================== =================== ========================= =================== =================== ======= ======= ======== ==
113  {"eax", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
114  {"ebx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
115  {"ecx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_ecx, dwarf_ecx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
116  {"edx", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edx, dwarf_edx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
117  {"esi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_esi, dwarf_esi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
118  {"edi", nullptr, 4, 0, eEncodingUint, eFormatHex, {dwarf_edi, dwarf_edi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
119  {"ebp", "fp", 4, 0, eEncodingUint, eFormatHex, {dwarf_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
120  {"esp", "sp", 4, 0, eEncodingUint, eFormatHex, {dwarf_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
121  {"eip", "pc", 4, 0, eEncodingUint, eFormatHex, {dwarf_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
122  {"eflags", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
123  {"cs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
124  {"ss", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
125  {"ds", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
126  {"es", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
127  {"fs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
128  {"gs", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
129  {"st0", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
130  {"st1", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
131  {"st2", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
132  {"st3", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
133  {"st4", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
134  {"st5", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
135  {"st6", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
136  {"st7", nullptr, 10, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_st7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
137  {"fctrl", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
138  {"fstat", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
139  {"ftag", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
140  {"fiseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
141  {"fioff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
142  {"foseg", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
143  {"fooff", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
144  {"fop", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
145  {"xmm0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
146  {"xmm1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
147  {"xmm2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
148  {"xmm3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
149  {"xmm4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
150  {"xmm5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
151  {"xmm6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
152  {"xmm7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
153  {"mxcsr", nullptr, 4, 0, eEncodingUint, eFormatHex, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
154  {"ymm0", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
155  {"ymm1", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
156  {"ymm2", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
157  {"ymm3", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
158  {"ymm4", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
159  {"ymm5", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
160  {"ymm6", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
161  {"ymm7", nullptr, 32, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
162  {"bnd0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
163  {"bnd1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
164  {"bnd2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
165  {"bnd3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt64,{dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
166  {"bndcfgu", nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0},
167  {"bndstatus",nullptr, 8, 0, eEncodingVector, eFormatVectorOfUInt8, {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, nullptr, 0}
168  // clang-format on
169 };
170 
172  llvm::array_lengthof(g_register_infos);
174 
175 const lldb_private::RegisterInfo *
177  // Make the C-string names and alt_names for the register infos into const
178  // C-string values by having the ConstString unique the names in the global
179  // constant C-string pool.
182  for (uint32_t i = 0; i < k_num_register_infos; ++i) {
183  if (g_register_infos[i].name)
184  g_register_infos[i].name =
186  if (g_register_infos[i].alt_name)
187  g_register_infos[i].alt_name =
188  ConstString(g_register_infos[i].alt_name).GetCString();
189  }
190  }
191  count = k_num_register_infos;
192  return g_register_infos;
193 }
194 
195 // Static Functions
196 
197 ABISP
198 ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
199  if (arch.GetTriple().getVendor() != llvm::Triple::Apple) {
200  if (arch.GetTriple().getArch() == llvm::Triple::x86) {
201  return ABISP(new ABISysV_i386(process_sp));
202  }
203  }
204  return ABISP();
205 }
206 
208  addr_t func_addr, addr_t return_addr,
209  llvm::ArrayRef<addr_t> args) const {
210  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
211 
212  if (!reg_ctx)
213  return false;
214 
215  uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
217  uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
219 
220  // While using register info to write a register value to memory, the
221  // register info just needs to have the correct size of a 32 bit register,
222  // the actual register it pertains to is not important, just the size needs
223  // to be correct. "eax" is used here for this purpose.
224  const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
225  if (!reg_info_32)
226  return false; // TODO this should actually never happen
227 
228  Status error;
229  RegisterValue reg_value;
230 
231  // Make room for the argument(s) on the stack
232  sp -= 4 * args.size();
233 
234  // SP Alignment
235  sp &= ~(16ull - 1ull); // 16-byte alignment
236 
237  // Write arguments onto the stack
238  addr_t arg_pos = sp;
239  for (addr_t arg : args) {
240  reg_value.SetUInt32(arg);
241  error = reg_ctx->WriteRegisterValueToMemory(
242  reg_info_32, arg_pos, reg_info_32->byte_size, reg_value);
243  if (error.Fail())
244  return false;
245  arg_pos += 4;
246  }
247 
248  // The return address is pushed onto the stack
249  sp -= 4;
250  reg_value.SetUInt32(return_addr);
251  error = reg_ctx->WriteRegisterValueToMemory(
252  reg_info_32, sp, reg_info_32->byte_size, reg_value);
253  if (error.Fail())
254  return false;
255 
256  // Setting %esp to the actual stack value.
257  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
258  return false;
259 
260  // Setting %eip to the address of the called function.
261  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr))
262  return false;
263 
264  return true;
265 }
266 
267 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
268  bool is_signed, Process *process,
269  addr_t &current_stack_argument) {
270  uint32_t byte_size = (bit_width + (8 - 1)) / 8;
271  Status error;
272 
273  if (!process)
274  return false;
275 
276  if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size,
277  is_signed, scalar, error)) {
278  current_stack_argument += byte_size;
279  return true;
280  }
281  return false;
282 }
283 
284 bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const {
285  unsigned int num_values = values.GetSize();
286  unsigned int value_index;
287 
288  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
289 
290  if (!reg_ctx)
291  return false;
292 
293  // Get pointer to the first stack argument
294  addr_t sp = reg_ctx->GetSP(0);
295  if (!sp)
296  return false;
297 
298  addr_t current_stack_argument = sp + 4; // jump over return address
299 
300  for (value_index = 0; value_index < num_values; ++value_index) {
301  Value *value = values.GetValueAtIndex(value_index);
302 
303  if (!value)
304  return false;
305 
306  // Currently: Support for extracting values with Clang QualTypes only.
307  CompilerType compiler_type(value->GetCompilerType());
308  llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
309  if (bit_size) {
310  bool is_signed;
311  if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
312  ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed,
313  thread.GetProcess().get(), current_stack_argument);
314  } else if (compiler_type.IsPointerType()) {
315  ReadIntegerArgument(value->GetScalar(), *bit_size, false,
316  thread.GetProcess().get(), current_stack_argument);
317  }
318  }
319  }
320  return true;
321 }
322 
323 Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
324  lldb::ValueObjectSP &new_value_sp) {
325  Status error;
326  if (!new_value_sp) {
327  error.SetErrorString("Empty value object for return value.");
328  return error;
329  }
330 
331  CompilerType compiler_type = new_value_sp->GetCompilerType();
332  if (!compiler_type) {
333  error.SetErrorString("Null clang type for return value.");
334  return error;
335  }
336 
337  const uint32_t type_flags = compiler_type.GetTypeInfo();
338  Thread *thread = frame_sp->GetThread().get();
339  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
340  DataExtractor data;
341  Status data_error;
342  size_t num_bytes = new_value_sp->GetData(data, data_error);
343  bool register_write_successful = true;
344 
345  if (data_error.Fail()) {
347  "Couldn't convert return value to raw data: %s",
348  data_error.AsCString());
349  return error;
350  }
351 
352  // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
353  // The terminology 'Fundamental Data Types' used here is adopted from Table
354  // 2.1 of the reference document (specified on top of this file)
355 
356  if (type_flags & eTypeIsPointer) // 'Pointer'
357  {
358  if (num_bytes != sizeof(uint32_t)) {
359  error.SetErrorString("Pointer to be returned is not 4 bytes wide");
360  return error;
361  }
362  lldb::offset_t offset = 0;
363  const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
364  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
365  register_write_successful =
366  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
367  } else if ((type_flags & eTypeIsScalar) ||
368  (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
369  {
370  lldb::offset_t offset = 0;
371  const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
372 
373  if (type_flags & eTypeIsInteger) // 'Integral' except enum
374  {
375  switch (num_bytes) {
376  default:
377  break;
378  case 16:
379  // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
380  // handle it
381  break;
382  case 8: {
383  uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
384  const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
385  uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset);
386  register_write_successful =
387  (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) &&
388  reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high));
389  break;
390  }
391  case 4:
392  case 2:
393  case 1: {
394  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
395  register_write_successful =
396  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
397  break;
398  }
399  }
400  } else if (type_flags & eTypeIsEnumeration) // handles enum
401  {
402  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
403  register_write_successful =
404  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
405  } else if (type_flags & eTypeIsFloat) // 'Floating Point'
406  {
407  RegisterValue st0_value, fstat_value, ftag_value;
408  const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
409  const RegisterInfo *fstat_info =
410  reg_ctx->GetRegisterInfoByName("fstat", 0);
411  const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0);
412 
413  /* According to Page 3-12 of document
414  System V Application Binary Interface, Intel386 Architecture Processor
415  Supplement, Fourth Edition
416  To return Floating Point values, all st% registers except st0 should be
417  empty after exiting from
418  a function. This requires setting fstat and ftag registers to specific
419  values.
420  fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't
421  specify the specific
422  value of TOP in case of function return. Hence, we set the TOP field to 7
423  by our choice. */
424  uint32_t value_fstat_u32 = 0x00003800;
425 
426  /* ftag: Implication of setting TOP to 7 and indicating all st% registers
427  empty except st0 is to set
428  7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to
429  0. This is in accordance
430  with the document Intel 64 and IA-32 Architectures Software Developer's
431  Manual, January 2015 */
432  uint32_t value_ftag_u32 = 0x00000080;
433 
434  if (num_bytes <= 12) // handles float, double, long double, __float80
435  {
436  long double value_long_dbl = 0.0;
437  if (num_bytes == 4)
438  value_long_dbl = data.GetFloat(&offset);
439  else if (num_bytes == 8)
440  value_long_dbl = data.GetDouble(&offset);
441  else if (num_bytes == 12)
442  value_long_dbl = data.GetLongDouble(&offset);
443  else {
444  error.SetErrorString("Invalid number of bytes for this return type");
445  return error;
446  }
447  st0_value.SetLongDouble(value_long_dbl);
448  fstat_value.SetUInt32(value_fstat_u32);
449  ftag_value.SetUInt32(value_ftag_u32);
450  register_write_successful =
451  reg_ctx->WriteRegister(st0_info, st0_value) &&
452  reg_ctx->WriteRegister(fstat_info, fstat_value) &&
453  reg_ctx->WriteRegister(ftag_info, ftag_value);
454  } else if (num_bytes == 16) // handles __float128
455  {
456  error.SetErrorString("Implementation is missing for this clang type.");
457  }
458  } else {
459  // Neither 'Integral' nor 'Floating Point'. If flow reaches here then
460  // check type_flags. This type_flags is not a valid type.
461  error.SetErrorString("Invalid clang type");
462  }
463  } else {
464  /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and
465  'Aggregate' data types
466  are yet to be implemented */
467  error.SetErrorString("Currently only Integral and Floating Point clang "
468  "types are supported.");
469  }
470  if (!register_write_successful)
471  error.SetErrorString("Register writing failed");
472  return error;
473 }
474 
476  Thread &thread, CompilerType &return_compiler_type) const {
477  ValueObjectSP return_valobj_sp;
478  Value value;
479 
480  if (!return_compiler_type)
481  return return_valobj_sp;
482 
483  value.SetCompilerType(return_compiler_type);
484 
485  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
486  if (!reg_ctx)
487  return return_valobj_sp;
488 
489  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
490 
491  unsigned eax_id =
492  reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
493  unsigned edx_id =
494  reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
495 
496  // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
497  // The terminology 'Fundamental Data Types' used here is adopted from Table
498  // 2.1 of the reference document (specified on top of this file)
499 
500  if (type_flags & eTypeIsPointer) // 'Pointer'
501  {
502  uint32_t ptr =
503  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
504  0xffffffff;
505  value.SetValueType(Value::eValueTypeScalar);
506  value.GetScalar() = ptr;
507  return_valobj_sp = ValueObjectConstResult::Create(
508  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
509  } else if ((type_flags & eTypeIsScalar) ||
510  (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
511  {
512  value.SetValueType(Value::eValueTypeScalar);
513  llvm::Optional<uint64_t> byte_size =
514  return_compiler_type.GetByteSize(nullptr);
515  if (!byte_size)
516  return return_valobj_sp;
517  bool success = false;
518 
519  if (type_flags & eTypeIsInteger) // 'Integral' except enum
520  {
521  const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
522  uint64_t raw_value =
523  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
524  0xffffffff;
525  raw_value |=
526  (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
527  0xffffffff)
528  << 32;
529 
530  switch (*byte_size) {
531  default:
532  break;
533 
534  case 16:
535  // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
536  // handle it
537  break;
538 
539  case 8:
540  if (is_signed)
541  value.GetScalar() = (int64_t)(raw_value);
542  else
543  value.GetScalar() = (uint64_t)(raw_value);
544  success = true;
545  break;
546 
547  case 4:
548  if (is_signed)
549  value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
550  else
551  value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
552  success = true;
553  break;
554 
555  case 2:
556  if (is_signed)
557  value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
558  else
559  value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
560  success = true;
561  break;
562 
563  case 1:
564  if (is_signed)
565  value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
566  else
567  value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
568  success = true;
569  break;
570  }
571 
572  if (success)
573  return_valobj_sp = ValueObjectConstResult::Create(
574  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
575  } else if (type_flags & eTypeIsEnumeration) // handles enum
576  {
577  uint32_t enm =
578  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
579  0xffffffff;
580  value.SetValueType(Value::eValueTypeScalar);
581  value.GetScalar() = enm;
582  return_valobj_sp = ValueObjectConstResult::Create(
583  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
584  } else if (type_flags & eTypeIsFloat) // 'Floating Point'
585  {
586  if (*byte_size <= 12) // handles float, double, long double, __float80
587  {
588  const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
589  RegisterValue st0_value;
590 
591  if (reg_ctx->ReadRegister(st0_info, st0_value)) {
592  DataExtractor data;
593  if (st0_value.GetData(data)) {
594  lldb::offset_t offset = 0;
595  long double value_long_double = data.GetLongDouble(&offset);
596 
597  // float is 4 bytes.
598  if (*byte_size == 4) {
599  float value_float = (float)value_long_double;
600  value.GetScalar() = value_float;
601  success = true;
602  } else if (*byte_size == 8) {
603  // double is 8 bytes
604  // On Android Platform: long double is also 8 bytes It will be
605  // handled here only.
606  double value_double = (double)value_long_double;
607  value.GetScalar() = value_double;
608  success = true;
609  } else if (*byte_size == 12) {
610  // long double and __float80 are 12 bytes on i386.
611  value.GetScalar() = value_long_double;
612  success = true;
613  }
614  }
615  }
616 
617  if (success)
618  return_valobj_sp = ValueObjectConstResult::Create(
619  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
620  } else if (*byte_size == 16) // handles __float128
621  {
622  lldb::addr_t storage_addr = (uint32_t)(
623  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
624  0xffffffff);
625  return_valobj_sp = ValueObjectMemory::Create(
626  &thread, "", Address(storage_addr, nullptr), return_compiler_type);
627  }
628  } else // Neither 'Integral' nor 'Floating Point'
629  {
630  // If flow reaches here then check type_flags This type_flags is
631  // unhandled
632  }
633  } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
634  {
635  // ToDo: Yet to be implemented
636  } else if (type_flags & eTypeIsVector) // 'Packed'
637  {
638  llvm::Optional<uint64_t> byte_size =
639  return_compiler_type.GetByteSize(nullptr);
640  if (byte_size && *byte_size > 0) {
641  const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
642  if (vec_reg == nullptr)
643  vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
644 
645  if (vec_reg) {
646  if (*byte_size <= vec_reg->byte_size) {
647  ProcessSP process_sp(thread.GetProcess());
648  if (process_sp) {
649  std::unique_ptr<DataBufferHeap> heap_data_up(
650  new DataBufferHeap(*byte_size, 0));
651  const ByteOrder byte_order = process_sp->GetByteOrder();
652  RegisterValue reg_value;
653  if (reg_ctx->ReadRegister(vec_reg, reg_value)) {
654  Status error;
655  if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(),
656  heap_data_up->GetByteSize(),
657  byte_order, error)) {
658  DataExtractor data(DataBufferSP(heap_data_up.release()),
659  byte_order,
660  process_sp->GetTarget()
661  .GetArchitecture()
662  .GetAddressByteSize());
663  return_valobj_sp = ValueObjectConstResult::Create(
664  &thread, return_compiler_type, ConstString(""), data);
665  }
666  }
667  }
668  } else if (*byte_size <= vec_reg->byte_size * 2) {
669  const RegisterInfo *vec_reg2 =
670  reg_ctx->GetRegisterInfoByName("xmm1", 0);
671  if (vec_reg2) {
672  ProcessSP process_sp(thread.GetProcess());
673  if (process_sp) {
674  std::unique_ptr<DataBufferHeap> heap_data_up(
675  new DataBufferHeap(*byte_size, 0));
676  const ByteOrder byte_order = process_sp->GetByteOrder();
677  RegisterValue reg_value;
678  RegisterValue reg_value2;
679  if (reg_ctx->ReadRegister(vec_reg, reg_value) &&
680  reg_ctx->ReadRegister(vec_reg2, reg_value2)) {
681 
682  Status error;
683  if (reg_value.GetAsMemoryData(vec_reg, heap_data_up->GetBytes(),
684  vec_reg->byte_size, byte_order,
685  error) &&
686  reg_value2.GetAsMemoryData(
687  vec_reg2, heap_data_up->GetBytes() + vec_reg->byte_size,
688  heap_data_up->GetByteSize() - vec_reg->byte_size,
689  byte_order, error)) {
690  DataExtractor data(DataBufferSP(heap_data_up.release()),
691  byte_order,
692  process_sp->GetTarget()
693  .GetArchitecture()
694  .GetAddressByteSize());
695  return_valobj_sp = ValueObjectConstResult::Create(
696  &thread, return_compiler_type, ConstString(""), data);
697  }
698  }
699  }
700  }
701  }
702  }
703  }
704  } else // 'Decimal Floating Point'
705  {
706  // ToDo: Yet to be implemented
707  }
708  return return_valobj_sp;
709 }
710 
712  Thread &thread, CompilerType &return_compiler_type) const {
713  ValueObjectSP return_valobj_sp;
714 
715  if (!return_compiler_type)
716  return return_valobj_sp;
717 
718  ExecutionContext exe_ctx(thread.shared_from_this());
719  return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
720  if (return_valobj_sp)
721  return return_valobj_sp;
722 
723  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
724  if (!reg_ctx_sp)
725  return return_valobj_sp;
726 
727  if (return_compiler_type.IsAggregateType()) {
728  unsigned eax_id =
729  reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
730  lldb::addr_t storage_addr = (uint32_t)(
731  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
732  0xffffffff);
733  return_valobj_sp = ValueObjectMemory::Create(
734  &thread, "", Address(storage_addr, nullptr), return_compiler_type);
735  }
736 
737  return return_valobj_sp;
738 }
739 
740 // This defines CFA as esp+4
741 // The saved pc is at CFA-4 (i.e. esp+0)
742 // The saved esp is CFA+0
743 
745  unwind_plan.Clear();
746  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
747 
748  uint32_t sp_reg_num = dwarf_esp;
749  uint32_t pc_reg_num = dwarf_eip;
750 
752  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
753  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
754  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
755  unwind_plan.AppendRow(row);
756  unwind_plan.SetSourceName("i386 at-func-entry default");
757  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
758  return true;
759 }
760 
761 // This defines CFA as ebp+8
762 // The saved pc is at CFA-4 (i.e. ebp+4)
763 // The saved ebp is at CFA-8 (i.e. ebp+0)
764 // The saved esp is CFA+0
765 
767  unwind_plan.Clear();
768  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
769 
770  uint32_t fp_reg_num = dwarf_ebp;
771  uint32_t sp_reg_num = dwarf_esp;
772  uint32_t pc_reg_num = dwarf_eip;
773 
775  const int32_t ptr_size = 4;
776 
777  row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
778  row->SetOffset(0);
779 
780  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
781  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
782  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
783 
784  unwind_plan.AppendRow(row);
785  unwind_plan.SetSourceName("i386 default unwind plan");
786  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
788  return true;
789 }
790 
791 // According to "Register Usage" in reference document (specified on top of
792 // this source file) ebx, ebp, esi, edi and esp registers are preserved i.e.
793 // non-volatile i.e. callee-saved on i386
794 bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
795  if (!reg_info)
796  return false;
797 
798  // Saved registers are ebx, ebp, esi, edi, esp, eip
799  const char *name = reg_info->name;
800  if (name[0] == 'e') {
801  switch (name[1]) {
802  case 'b':
803  if (name[2] == 'x' || name[2] == 'p')
804  return name[3] == '\0';
805  break;
806  case 'd':
807  if (name[2] == 'i')
808  return name[3] == '\0';
809  break;
810  case 'i':
811  if (name[2] == 'p')
812  return name[3] == '\0';
813  break;
814  case 's':
815  if (name[2] == 'i' || name[2] == 'p')
816  return name[3] == '\0';
817  break;
818  }
819  }
820 
821  if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
822  return true;
823  if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
824  return true;
825  if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
826  return true;
827 
828  return false;
829 }
830 
832  PluginManager::RegisterPlugin(
833  GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
834 }
835 
837  PluginManager::UnregisterPlugin(CreateInstance);
838 }
839 
840 // PluginInterface protocol
841 
843  static ConstString g_name("sysv-i386");
844  return g_name;
845 }
846 
848  return GetPluginNameStatic();
849 }
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
An data extractor class.
Definition: DataExtractor.h:47
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:542
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
static lldb_private::ConstString GetPluginNameStatic()
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)=0
Convert from a given register numbering scheme to the lldb register numbering scheme.
An architecture specification class.
Definition: ArchSpec.h:32
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:701
void SetValueType(ValueType value_type)
Definition: Value.h:154
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
llvm::Optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
A subclass of DataBuffer that stores a data buffer on the heap.
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t functionAddress, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
static bool g_register_info_names_constified
long double GetLongDouble(lldb::offset_t *offset_ptr) const
void SetLongDouble(long double f)
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define UINT32_MAX
Definition: lldb-defines.h:31
uint64_t offset_t
Definition: lldb-types.h:87
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:366
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:355
virtual lldb::RegisterContextSP GetRegisterContext()=0
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
double GetDouble(lldb::offset_t *offset_ptr) const
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
const CompilerType & GetCompilerType()
Definition: Value.cpp:239
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:408
A section + offset based address class.
Definition: Address.h:80
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
static void Terminate()
dwarf_regnums
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Process *process, addr_t &current_stack_argument)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:461
static const uint32_t k_num_register_infos
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::ConstString GetPluginName() override
bool GetData(DataExtractor &data) const
static RegisterInfo g_register_infos[]
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
llvm::Optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
Definition: SBAddress.h:15
static void Initialize()
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
const Scalar & GetScalar() const
Definition: Value.h:178
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
Definition: Process.cpp:2302
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:395
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:449
An error handling class.
Definition: Status.h:44
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90