LLDB  mainline
ABISysV_i386.cpp
Go to the documentation of this file.
1 //===-- ABISysV_i386.cpp --------------------------------------------------===//
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 #include <optional>
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
36 
37 // This source file uses the following document as a reference:
38 //====================================================================
39 // System V Application Binary Interface
40 // Intel386 Architecture Processor Supplement, Version 1.0
41 // Edited by
42 // H.J. Lu, David L Kreitzer, Milind Girkar, Zia Ansari
43 //
44 // (Based on
45 // System V Application Binary Interface,
46 // AMD64 Architecture Processor Supplement,
47 // Edited by
48 // H.J. Lu, Michael Matz, Milind Girkar, Jan Hubicka,
49 // Andreas Jaeger, Mark Mitchell)
50 //
51 // February 3, 2015
52 //====================================================================
53 
54 // DWARF Register Number Mapping
55 // See Table 2.14 of the reference document (specified on top of this file)
56 // Comment: Table 2.14 is followed till 'mm' entries. After that, all entries
57 // are ignored here.
58 
60  dwarf_eax = 0,
69 };
70 
71 // Static Functions
72 
73 ABISP
74 ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
75  if (arch.GetTriple().getVendor() != llvm::Triple::Apple) {
76  if (arch.GetTriple().getArch() == llvm::Triple::x86) {
77  return ABISP(
78  new ABISysV_i386(std::move(process_sp), MakeMCRegisterInfo(arch)));
79  }
80  }
81  return ABISP();
82 }
83 
85  addr_t func_addr, addr_t return_addr,
86  llvm::ArrayRef<addr_t> args) const {
87  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
88 
89  if (!reg_ctx)
90  return false;
91 
92  uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
94  uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
96 
97  // While using register info to write a register value to memory, the
98  // register info just needs to have the correct size of a 32 bit register,
99  // the actual register it pertains to is not important, just the size needs
100  // to be correct. "eax" is used here for this purpose.
101  const RegisterInfo *reg_info_32 = reg_ctx->GetRegisterInfoByName("eax");
102  if (!reg_info_32)
103  return false; // TODO this should actually never happen
104 
105  Status error;
106  RegisterValue reg_value;
107 
108  // Make room for the argument(s) on the stack
109  sp -= 4 * args.size();
110 
111  // SP Alignment
112  sp &= ~(16ull - 1ull); // 16-byte alignment
113 
114  // Write arguments onto the stack
115  addr_t arg_pos = sp;
116  for (addr_t arg : args) {
117  reg_value.SetUInt32(arg);
119  reg_info_32, arg_pos, reg_info_32->byte_size, reg_value);
120  if (error.Fail())
121  return false;
122  arg_pos += 4;
123  }
124 
125  // The return address is pushed onto the stack
126  sp -= 4;
127  reg_value.SetUInt32(return_addr);
129  reg_info_32, sp, reg_info_32->byte_size, reg_value);
130  if (error.Fail())
131  return false;
132 
133  // Setting %esp to the actual stack value.
134  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
135  return false;
136 
137  // Setting %eip to the address of the called function.
138  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, func_addr))
139  return false;
140 
141  return true;
142 }
143 
144 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
145  bool is_signed, Process *process,
146  addr_t &current_stack_argument) {
147  uint32_t byte_size = (bit_width + (8 - 1)) / 8;
148  Status error;
149 
150  if (!process)
151  return false;
152 
153  if (process->ReadScalarIntegerFromMemory(current_stack_argument, byte_size,
154  is_signed, scalar, error)) {
155  current_stack_argument += byte_size;
156  return true;
157  }
158  return false;
159 }
160 
161 bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const {
162  unsigned int num_values = values.GetSize();
163  unsigned int value_index;
164 
165  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
166 
167  if (!reg_ctx)
168  return false;
169 
170  // Get pointer to the first stack argument
171  addr_t sp = reg_ctx->GetSP(0);
172  if (!sp)
173  return false;
174 
175  addr_t current_stack_argument = sp + 4; // jump over return address
176 
177  for (value_index = 0; value_index < num_values; ++value_index) {
178  Value *value = values.GetValueAtIndex(value_index);
179 
180  if (!value)
181  return false;
182 
183  // Currently: Support for extracting values with Clang QualTypes only.
184  CompilerType compiler_type(value->GetCompilerType());
185  std::optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
186  if (bit_size) {
187  bool is_signed;
188  if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
189  ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed,
190  thread.GetProcess().get(), current_stack_argument);
191  } else if (compiler_type.IsPointerType()) {
192  ReadIntegerArgument(value->GetScalar(), *bit_size, false,
193  thread.GetProcess().get(), current_stack_argument);
194  }
195  }
196  }
197  return true;
198 }
199 
200 Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
201  lldb::ValueObjectSP &new_value_sp) {
202  Status error;
203  if (!new_value_sp) {
204  error.SetErrorString("Empty value object for return value.");
205  return error;
206  }
207 
208  CompilerType compiler_type = new_value_sp->GetCompilerType();
209  if (!compiler_type) {
210  error.SetErrorString("Null clang type for return value.");
211  return error;
212  }
213 
214  const uint32_t type_flags = compiler_type.GetTypeInfo();
215  Thread *thread = frame_sp->GetThread().get();
216  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
217  DataExtractor data;
218  Status data_error;
219  size_t num_bytes = new_value_sp->GetData(data, data_error);
220  bool register_write_successful = true;
221 
222  if (data_error.Fail()) {
223  error.SetErrorStringWithFormat(
224  "Couldn't convert return value to raw data: %s",
225  data_error.AsCString());
226  return error;
227  }
228 
229  // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
230  // The terminology 'Fundamental Data Types' used here is adopted from Table
231  // 2.1 of the reference document (specified on top of this file)
232 
233  if (type_flags & eTypeIsPointer) // 'Pointer'
234  {
235  if (num_bytes != sizeof(uint32_t)) {
236  error.SetErrorString("Pointer to be returned is not 4 bytes wide");
237  return error;
238  }
239  lldb::offset_t offset = 0;
240  const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
241  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
242  register_write_successful =
243  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
244  } else if ((type_flags & eTypeIsScalar) ||
245  (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
246  {
247  lldb::offset_t offset = 0;
248  const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
249 
250  if (type_flags & eTypeIsInteger) // 'Integral' except enum
251  {
252  switch (num_bytes) {
253  default:
254  break;
255  case 16:
256  // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
257  // handle it
258  break;
259  case 8: {
260  uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
261  const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
262  uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset);
263  register_write_successful =
264  (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) &&
265  reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high));
266  break;
267  }
268  case 4:
269  case 2:
270  case 1: {
271  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
272  register_write_successful =
273  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
274  break;
275  }
276  }
277  } else if (type_flags & eTypeIsEnumeration) // handles enum
278  {
279  uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
280  register_write_successful =
281  reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
282  } else if (type_flags & eTypeIsFloat) // 'Floating Point'
283  {
284  RegisterValue st0_value, fstat_value, ftag_value;
285  const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
286  const RegisterInfo *fstat_info =
287  reg_ctx->GetRegisterInfoByName("fstat", 0);
288  const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0);
289 
290  /* According to Page 3-12 of document
291  System V Application Binary Interface, Intel386 Architecture Processor
292  Supplement, Fourth Edition
293  To return Floating Point values, all st% registers except st0 should be
294  empty after exiting from
295  a function. This requires setting fstat and ftag registers to specific
296  values.
297  fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't
298  specify the specific
299  value of TOP in case of function return. Hence, we set the TOP field to 7
300  by our choice. */
301  uint32_t value_fstat_u32 = 0x00003800;
302 
303  /* ftag: Implication of setting TOP to 7 and indicating all st% registers
304  empty except st0 is to set
305  7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to
306  0. This is in accordance
307  with the document Intel 64 and IA-32 Architectures Software Developer's
308  Manual, January 2015 */
309  uint32_t value_ftag_u32 = 0x00000080;
310 
311  if (num_bytes <= 12) // handles float, double, long double, __float80
312  {
313  long double value_long_dbl = 0.0;
314  if (num_bytes == 4)
315  value_long_dbl = data.GetFloat(&offset);
316  else if (num_bytes == 8)
317  value_long_dbl = data.GetDouble(&offset);
318  else if (num_bytes == 12)
319  value_long_dbl = data.GetLongDouble(&offset);
320  else {
321  error.SetErrorString("Invalid number of bytes for this return type");
322  return error;
323  }
324  st0_value.SetLongDouble(value_long_dbl);
325  fstat_value.SetUInt32(value_fstat_u32);
326  ftag_value.SetUInt32(value_ftag_u32);
327  register_write_successful =
328  reg_ctx->WriteRegister(st0_info, st0_value) &&
329  reg_ctx->WriteRegister(fstat_info, fstat_value) &&
330  reg_ctx->WriteRegister(ftag_info, ftag_value);
331  } else if (num_bytes == 16) // handles __float128
332  {
333  error.SetErrorString("Implementation is missing for this clang type.");
334  }
335  } else {
336  // Neither 'Integral' nor 'Floating Point'. If flow reaches here then
337  // check type_flags. This type_flags is not a valid type.
338  error.SetErrorString("Invalid clang type");
339  }
340  } else {
341  /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and
342  'Aggregate' data types
343  are yet to be implemented */
344  error.SetErrorString("Currently only Integral and Floating Point clang "
345  "types are supported.");
346  }
347  if (!register_write_successful)
348  error.SetErrorString("Register writing failed");
349  return error;
350 }
351 
353  Thread &thread, CompilerType &return_compiler_type) const {
354  ValueObjectSP return_valobj_sp;
355  Value value;
356 
357  if (!return_compiler_type)
358  return return_valobj_sp;
359 
360  value.SetCompilerType(return_compiler_type);
361 
362  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
363  if (!reg_ctx)
364  return return_valobj_sp;
365 
366  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
367 
368  unsigned eax_id =
369  reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
370  unsigned edx_id =
371  reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
372 
373  // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
374  // The terminology 'Fundamental Data Types' used here is adopted from Table
375  // 2.1 of the reference document (specified on top of this file)
376 
377  if (type_flags & eTypeIsPointer) // 'Pointer'
378  {
379  uint32_t ptr =
380  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
381  0xffffffff;
382  value.SetValueType(Value::ValueType::Scalar);
383  value.GetScalar() = ptr;
384  return_valobj_sp = ValueObjectConstResult::Create(
385  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
386  } else if ((type_flags & eTypeIsScalar) ||
387  (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
388  {
389  value.SetValueType(Value::ValueType::Scalar);
390  std::optional<uint64_t> byte_size =
391  return_compiler_type.GetByteSize(&thread);
392  if (!byte_size)
393  return return_valobj_sp;
394  bool success = false;
395 
396  if (type_flags & eTypeIsInteger) // 'Integral' except enum
397  {
398  const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
399  uint64_t raw_value =
400  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
401  0xffffffff;
402  raw_value |=
403  (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
404  0xffffffff)
405  << 32;
406 
407  switch (*byte_size) {
408  default:
409  break;
410 
411  case 16:
412  // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
413  // handle it
414  break;
415 
416  case 8:
417  if (is_signed)
418  value.GetScalar() = (int64_t)(raw_value);
419  else
420  value.GetScalar() = (uint64_t)(raw_value);
421  success = true;
422  break;
423 
424  case 4:
425  if (is_signed)
426  value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
427  else
428  value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
429  success = true;
430  break;
431 
432  case 2:
433  if (is_signed)
434  value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
435  else
436  value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
437  success = true;
438  break;
439 
440  case 1:
441  if (is_signed)
442  value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
443  else
444  value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
445  success = true;
446  break;
447  }
448 
449  if (success)
450  return_valobj_sp = ValueObjectConstResult::Create(
451  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
452  } else if (type_flags & eTypeIsEnumeration) // handles enum
453  {
454  uint32_t enm =
455  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
456  0xffffffff;
457  value.SetValueType(Value::ValueType::Scalar);
458  value.GetScalar() = enm;
459  return_valobj_sp = ValueObjectConstResult::Create(
460  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
461  } else if (type_flags & eTypeIsFloat) // 'Floating Point'
462  {
463  if (*byte_size <= 12) // handles float, double, long double, __float80
464  {
465  const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
466  RegisterValue st0_value;
467 
468  if (reg_ctx->ReadRegister(st0_info, st0_value)) {
469  DataExtractor data;
470  if (st0_value.GetData(data)) {
471  lldb::offset_t offset = 0;
472  long double value_long_double = data.GetLongDouble(&offset);
473 
474  // float is 4 bytes.
475  if (*byte_size == 4) {
476  float value_float = (float)value_long_double;
477  value.GetScalar() = value_float;
478  success = true;
479  } else if (*byte_size == 8) {
480  // double is 8 bytes
481  // On Android Platform: long double is also 8 bytes It will be
482  // handled here only.
483  double value_double = (double)value_long_double;
484  value.GetScalar() = value_double;
485  success = true;
486  } else if (*byte_size == 12) {
487  // long double and __float80 are 12 bytes on i386.
488  value.GetScalar() = value_long_double;
489  success = true;
490  }
491  }
492  }
493 
494  if (success)
495  return_valobj_sp = ValueObjectConstResult::Create(
496  thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
497  } else if (*byte_size == 16) // handles __float128
498  {
499  lldb::addr_t storage_addr = (uint32_t)(
500  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
501  0xffffffff);
502  return_valobj_sp = ValueObjectMemory::Create(
503  &thread, "", Address(storage_addr, nullptr), return_compiler_type);
504  }
505  } else // Neither 'Integral' nor 'Floating Point'
506  {
507  // If flow reaches here then check type_flags This type_flags is
508  // unhandled
509  }
510  } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
511  {
512  // ToDo: Yet to be implemented
513  } else if (type_flags & eTypeIsVector) // 'Packed'
514  {
515  std::optional<uint64_t> byte_size =
516  return_compiler_type.GetByteSize(&thread);
517  if (byte_size && *byte_size > 0) {
518  const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
519  if (vec_reg == nullptr)
520  vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
521 
522  if (vec_reg) {
523  if (*byte_size <= vec_reg->byte_size) {
524  ProcessSP process_sp(thread.GetProcess());
525  if (process_sp) {
526  std::unique_ptr<DataBufferHeap> heap_data_up(
527  new DataBufferHeap(*byte_size, 0));
528  const ByteOrder byte_order = process_sp->GetByteOrder();
529  RegisterValue reg_value;
530  if (reg_ctx->ReadRegister(vec_reg, reg_value)) {
531  Status error;
532  if (reg_value.GetAsMemoryData(*vec_reg, heap_data_up->GetBytes(),
533  heap_data_up->GetByteSize(),
534  byte_order, error)) {
535  DataExtractor data(DataBufferSP(heap_data_up.release()),
536  byte_order,
537  process_sp->GetTarget()
538  .GetArchitecture()
539  .GetAddressByteSize());
540  return_valobj_sp = ValueObjectConstResult::Create(
541  &thread, return_compiler_type, ConstString(""), data);
542  }
543  }
544  }
545  } else if (*byte_size <= vec_reg->byte_size * 2) {
546  const RegisterInfo *vec_reg2 =
547  reg_ctx->GetRegisterInfoByName("xmm1", 0);
548  if (vec_reg2) {
549  ProcessSP process_sp(thread.GetProcess());
550  if (process_sp) {
551  std::unique_ptr<DataBufferHeap> heap_data_up(
552  new DataBufferHeap(*byte_size, 0));
553  const ByteOrder byte_order = process_sp->GetByteOrder();
554  RegisterValue reg_value;
555  RegisterValue reg_value2;
556  if (reg_ctx->ReadRegister(vec_reg, reg_value) &&
557  reg_ctx->ReadRegister(vec_reg2, reg_value2)) {
558 
559  Status error;
560  if (reg_value.GetAsMemoryData(
561  *vec_reg, heap_data_up->GetBytes(), vec_reg->byte_size,
562  byte_order, error) &&
563  reg_value2.GetAsMemoryData(
564  *vec_reg2,
565  heap_data_up->GetBytes() + vec_reg->byte_size,
566  heap_data_up->GetByteSize() - vec_reg->byte_size,
567  byte_order, error)) {
568  DataExtractor data(DataBufferSP(heap_data_up.release()),
569  byte_order,
570  process_sp->GetTarget()
571  .GetArchitecture()
572  .GetAddressByteSize());
573  return_valobj_sp = ValueObjectConstResult::Create(
574  &thread, return_compiler_type, ConstString(""), data);
575  }
576  }
577  }
578  }
579  }
580  }
581  }
582  } else // 'Decimal Floating Point'
583  {
584  // ToDo: Yet to be implemented
585  }
586  return return_valobj_sp;
587 }
588 
590  Thread &thread, CompilerType &return_compiler_type) const {
591  ValueObjectSP return_valobj_sp;
592 
593  if (!return_compiler_type)
594  return return_valobj_sp;
595 
596  ExecutionContext exe_ctx(thread.shared_from_this());
597  return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
598  if (return_valobj_sp)
599  return return_valobj_sp;
600 
601  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
602  if (!reg_ctx_sp)
603  return return_valobj_sp;
604 
605  if (return_compiler_type.IsAggregateType()) {
606  unsigned eax_id =
607  reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
608  lldb::addr_t storage_addr = (uint32_t)(
609  thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
610  0xffffffff);
611  return_valobj_sp = ValueObjectMemory::Create(
612  &thread, "", Address(storage_addr, nullptr), return_compiler_type);
613  }
614 
615  return return_valobj_sp;
616 }
617 
618 // This defines CFA as esp+4
619 // The saved pc is at CFA-4 (i.e. esp+0)
620 // The saved esp is CFA+0
621 
623  unwind_plan.Clear();
624  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
625 
626  uint32_t sp_reg_num = dwarf_esp;
627  uint32_t pc_reg_num = dwarf_eip;
628 
630  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
631  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
632  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
633  unwind_plan.AppendRow(row);
634  unwind_plan.SetSourceName("i386 at-func-entry default");
635  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
636  return true;
637 }
638 
639 // This defines CFA as ebp+8
640 // The saved pc is at CFA-4 (i.e. ebp+4)
641 // The saved ebp is at CFA-8 (i.e. ebp+0)
642 // The saved esp is CFA+0
643 
645  unwind_plan.Clear();
646  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
647 
648  uint32_t fp_reg_num = dwarf_ebp;
649  uint32_t sp_reg_num = dwarf_esp;
650  uint32_t pc_reg_num = dwarf_eip;
651 
653  const int32_t ptr_size = 4;
654 
655  row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
656  row->SetOffset(0);
657  row->SetUnspecifiedRegistersAreUndefined(true);
658 
659  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
660  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
661  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
662 
663  unwind_plan.AppendRow(row);
664  unwind_plan.SetSourceName("i386 default unwind plan");
665  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
668  return true;
669 }
670 
671 // According to "Register Usage" in reference document (specified on top of
672 // this source file) ebx, ebp, esi, edi and esp registers are preserved i.e.
673 // non-volatile i.e. callee-saved on i386
674 bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
675  if (!reg_info)
676  return false;
677 
678  // Saved registers are ebx, ebp, esi, edi, esp, eip
679  const char *name = reg_info->name;
680  if (name[0] == 'e') {
681  switch (name[1]) {
682  case 'b':
683  if (name[2] == 'x' || name[2] == 'p')
684  return name[3] == '\0';
685  break;
686  case 'd':
687  if (name[2] == 'i')
688  return name[3] == '\0';
689  break;
690  case 'i':
691  if (name[2] == 'p')
692  return name[3] == '\0';
693  break;
694  case 's':
695  if (name[2] == 'i' || name[2] == 'p')
696  return name[3] == '\0';
697  break;
698  }
699  }
700 
701  if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
702  return true;
703  if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
704  return true;
705  if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
706  return true;
707 
708  return false;
709 }
710 
712  PluginManager::RegisterPlugin(
713  GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
714 }
715 
717  PluginManager::UnregisterPlugin(CreateInstance);
718 }
lldb_private::RegisterContext::WriteRegister
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
lldb_private::ArchSpec
Definition: ArchSpec.h:32
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb_private::RegisterContext::WriteRegisterValueToMemory
virtual Status WriteRegisterValueToMemory(const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue &reg_value)
Definition: RegisterContext.cpp:368
lldb_private::Process::ReadScalarIntegerFromMemory
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
Definition: Process.cpp:2225
lldb_private::UnwindPlan::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:437
lldb::eRegisterKindDWARF
@ eRegisterKindDWARF
the register numbers seen DWARF
Definition: lldb-enumerations.h:230
lldb_private::CompilerType::GetByteSize
std::optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
Definition: CompilerType.cpp:560
lldb_private::Value
Definition: Value.h:38
lldb_private::Value::SetValueType
void SetValueType(ValueType value_type)
Definition: Value.h:89
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:231
dwarf_ecx
@ dwarf_ecx
Definition: ABISysV_i386.cpp:61
lldb_private::ValueList::GetValueAtIndex
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:670
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:490
lldb_private::RegisterContext::ReadRegister
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
lldb_private::Scalar
Definition: Scalar.h:34
lldb_private::Process
Definition: Process.h:338
dwarf_ebp
@ dwarf_ebp
Definition: ABISysV_i386.cpp:65
Module.h
lldb_private::RegisterContext::ConvertRegisterKindToRegisterNumber
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
Definition: RegisterContext.cpp:268
ABISysV_i386.h
lldb_private::UnwindPlan::SetUnwindPlanForSignalTrap
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:502
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
RegisterValue.h
lldb_private::ValueList
Definition: Value.h:157
dwarf_regnums
dwarf_regnums
Definition: ABISysV_mips.cpp:39
StackFrame.h
lldb_private::RegisterValue::GetAsMemoryData
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: RegisterValue.cpp:38
ValueObjectMemory.h
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
lldb_private::CompilerType::IsAggregateType
bool IsAggregateType() const
Definition: CompilerType.cpp:32
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
dwarf_esp
@ dwarf_esp
Definition: ABISysV_i386.cpp:64
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
lldb_private::ValueList::GetSize
size_t GetSize()
Definition: Value.cpp:668
dwarf_esi
@ dwarf_esi
Definition: ABISysV_i386.cpp:66
dwarf_edx
@ dwarf_edx
Definition: ABISysV_i386.cpp:62
Process.h
lldb_private::CompilerType::IsIntegerOrEnumerationType
bool IsIntegerOrEnumerationType(bool &is_signed) const
Definition: CompilerType.cpp:179
lldb_private::Value::SetCompilerType
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:252
ABISysV_i386::Terminate
static void Terminate()
Definition: ABISysV_i386.cpp:716
Target.h
ABISysV_i386::GetArgumentValues
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
Definition: ABISysV_i386.cpp:161
lldb_private::Value::GetScalar
const Scalar & GetScalar() const
Definition: Value.h:112
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
dwarf_eip
@ dwarf_eip
Definition: ABISysV_i386.cpp:68
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:235
ABISysV_i386::SetReturnValueObject
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
Definition: ABISysV_i386.cpp:200
lldb_private::DataExtractor
Definition: DataExtractor.h:48
Log.h
lldb_private::Thread
Definition: Thread.h:61
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
lldb_private::DataExtractor::GetMaxU32
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
Definition: DataExtractor.cpp:518
lldb_private::DataExtractor::GetDouble
double GetDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:626
lldb_private::RegisterValue::GetData
bool GetData(DataExtractor &data) const
Definition: RegisterValue.cpp:34
lldb_private::UnwindPlan::SetSourcedFromCompiler
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:478
ValueObjectRegister.h
lldb_private::ConstString
Definition: ConstString.h:39
ABISysV_i386::Initialize
static void Initialize()
Definition: ABISysV_i386.cpp:711
ABISysV_i386::GetReturnValueObjectSimple
lldb::ValueObjectSP GetReturnValueObjectSimple(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const
Definition: ABISysV_i386.cpp:352
ABISysV_i386::RegisterIsCalleeSaved
bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info)
Definition: ABISysV_i386.cpp:674
ABISysV_i386::CreateFunctionEntryUnwindPlan
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_i386.cpp:622
ReadIntegerArgument
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width, bool is_signed, Process *process, addr_t &current_stack_argument)
Definition: ABISysV_i386.cpp:144
sp
@ sp
Definition: CompactUnwindInfo.cpp:1249
lldb_private::DataExtractor::GetFloat
float GetFloat(lldb::offset_t *offset_ptr) const
Extract a float from *offset_ptr.
Definition: DataExtractor.cpp:622
Thread.h
UnwindPlan.h
lldb_private::RegisterContext::GetSP
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
Definition: RegisterContext.cpp:152
lldb_private::RegisterContext
Definition: RegisterContext.h:17
ValueObjectConstResult.h
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
lldb_private::CompilerType::GetBitSize
std::optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
Definition: CompilerType.cpp:552
lldb_private::RegisterValue::SetUInt32
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
Definition: RegisterValue.h:200
ABISysV_i386::GetReturnValueObjectImpl
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &type) const override
Definition: ABISysV_i386.cpp:589
lldb_private::UnwindPlan::Clear
void Clear()
Definition: UnwindPlan.h:508
lldb_private::Status
Definition: Status.h:44
lldb_private::RegisterContext::WriteRegisterFromUnsigned
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
Definition: RegisterContext.cpp:205
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
ABISysV_i386::CreateDefaultUnwindPlan
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
Definition: ABISysV_i386.cpp:644
lldb_private::Address
Definition: Address.h:59
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:52
lldb_private::CompilerType::IsPointerType
bool IsPointerType(CompilerType *pointee_type=nullptr) const
Definition: CompilerType.cpp:183
lldb_private::CompilerType::GetTypeInfo
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
Definition: CompilerType.cpp:337
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
dwarf_ebx
@ dwarf_ebx
Definition: ABISysV_i386.cpp:63
ABISysV_i386::CreateInstance
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
Definition: ABISysV_i386.cpp:74
uint16_t
PluginManager.h
DataExtractor.h
lldb_private::CompilerType
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
lldb_private::Value::GetCompilerType
const CompilerType & GetCompilerType()
Definition: Value.cpp:223
ABISysV_i386::PrepareTrivialCall
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
Definition: ABISysV_i386.cpp:84
dwarf_edi
@ dwarf_edi
Definition: ABISysV_i386.cpp:67
Status.h
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetLongDouble
long double GetLongDouble(lldb::offset_t *offset_ptr) const
Definition: DataExtractor.cpp:630
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:51
ConstString.h
lldb_private::RegisterValue::SetLongDouble
void SetLongDouble(long double f)
Definition: RegisterValue.h:227
LLDB_PLUGIN_DEFINE
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
ABISysV_i386
Definition: ABISysV_i386.h:15
dwarf_eax
@ dwarf_eax
Definition: ABISysV_i386.cpp:60
lldb_private::Thread::GetStackFrameAtIndex
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb_private::DataBufferHeap
Definition: DataBufferHeap.h:30
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
RegisterContext.h
Value.h
lldb_private::RegisterContext::GetRegisterInfoByName
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
Definition: RegisterContext.cpp:52
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:139
lldb_private::Status::AsCString
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130