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/TargetParser/Triple.h"
12 
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/Value.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/Core/ValueObjectMemory.h"
18 #include "lldb/Core/ValueObjectRegister.h"
19 #include "lldb/Symbol/UnwindPlan.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/RegisterContext.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Utility/ConstString.h"
26 #include "lldb/Utility/DataExtractor.h"
27 #include "lldb/Utility/Log.h"
28 #include "lldb/Utility/RegisterValue.h"
29 #include "lldb/Utility/Status.h"
30 #include <optional>
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 LLDB_PLUGIN_DEFINE(ABISysV_i386)
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 
59 enum dwarf_regnums {
60   dwarf_eax = 0,
61   dwarf_ecx,
62   dwarf_edx,
63   dwarf_ebx,
64   dwarf_esp,
65   dwarf_ebp,
66   dwarf_esi,
67   dwarf_edi,
68   dwarf_eip,
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 
84 bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
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(
93       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
94   uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
95       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
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);
118     error = reg_ctx->WriteRegisterValueToMemory(
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);
128   error = reg_ctx->WriteRegisterValueToMemory(
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 
352 ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
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 
589 ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl(
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 
622 bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
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 
629   UnwindPlan::RowSP row(new UnwindPlan::Row);
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 
644 bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
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 
652   UnwindPlan::RowSP row(new UnwindPlan::Row);
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);
666   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
667   unwind_plan.SetUnwindPlanForSignalTrap(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 
711 void ABISysV_i386::Initialize() {
712   PluginManager::RegisterPlugin(
713       GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
714 }
715 
716 void ABISysV_i386::Terminate() {
717   PluginManager::UnregisterPlugin(CreateInstance);
718 }
719