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"
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 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 LLDB_PLUGIN_DEFINE(ABISysV_i386)
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 
58 enum dwarf_regnums {
59   dwarf_eax = 0,
60   dwarf_ecx,
61   dwarf_edx,
62   dwarf_ebx,
63   dwarf_esp,
64   dwarf_ebp,
65   dwarf_esi,
66   dwarf_edi,
67   dwarf_eip,
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 
83 bool ABISysV_i386::PrepareTrivialCall(Thread &thread, addr_t sp,
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(
92       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
93   uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
94       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
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()) {
222     error.SetErrorStringWithFormat(
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 
351 ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
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::ValueType::Scalar);
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::ValueType::Scalar);
389     llvm::Optional<uint64_t> byte_size =
390         return_compiler_type.GetByteSize(&thread);
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::ValueType::Scalar);
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(&thread);
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 
587 ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl(
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 
620 bool ABISysV_i386::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
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 
627   UnwindPlan::RowSP row(new UnwindPlan::Row);
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 
642 bool ABISysV_i386::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
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 
650   UnwindPlan::RowSP row(new UnwindPlan::Row);
651   const int32_t ptr_size = 4;
652 
653   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
654   row->SetOffset(0);
655   row->SetUnspecifiedRegistersAreUndefined(true);
656 
657   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
658   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
659   row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
660 
661   unwind_plan.AppendRow(row);
662   unwind_plan.SetSourceName("i386 default unwind plan");
663   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
664   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
665   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
666   return true;
667 }
668 
669 // According to "Register Usage" in reference document (specified on top of
670 // this source file) ebx, ebp, esi, edi and esp registers are preserved i.e.
671 // non-volatile i.e. callee-saved on i386
672 bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
673   if (!reg_info)
674     return false;
675 
676   // Saved registers are ebx, ebp, esi, edi, esp, eip
677   const char *name = reg_info->name;
678   if (name[0] == 'e') {
679     switch (name[1]) {
680     case 'b':
681       if (name[2] == 'x' || name[2] == 'p')
682         return name[3] == '\0';
683       break;
684     case 'd':
685       if (name[2] == 'i')
686         return name[3] == '\0';
687       break;
688     case 'i':
689       if (name[2] == 'p')
690         return name[3] == '\0';
691       break;
692     case 's':
693       if (name[2] == 'i' || name[2] == 'p')
694         return name[3] == '\0';
695       break;
696     }
697   }
698 
699   if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
700     return true;
701   if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
702     return true;
703   if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
704     return true;
705 
706   return false;
707 }
708 
709 void ABISysV_i386::Initialize() {
710   PluginManager::RegisterPlugin(
711       GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
712 }
713 
714 void ABISysV_i386::Terminate() {
715   PluginManager::UnregisterPlugin(CreateInstance);
716 }
717