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