xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/Symbol/UnwindPlan.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/RegisterContext.h"
19 #include "lldb/Target/StackFrame.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Target/Thread.h"
22 #include "lldb/Utility/ConstString.h"
23 #include "lldb/Utility/DataExtractor.h"
24 #include "lldb/Utility/Log.h"
25 #include "lldb/Utility/RegisterValue.h"
26 #include "lldb/Utility/Status.h"
27 #include "lldb/ValueObject/ValueObjectConstResult.h"
28 #include "lldb/ValueObject/ValueObjectMemory.h"
29 #include "lldb/ValueObject/ValueObjectRegister.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
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)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 
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t func_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const84 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 
ReadIntegerArgument(Scalar & scalar,unsigned int bit_width,bool is_signed,Process * process,addr_t & current_stack_argument)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 
GetArgumentValues(Thread & thread,ValueList & values) const161 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 =
186         llvm::expectedToOptional(compiler_type.GetBitSize(&thread));
187     if (bit_size) {
188       bool is_signed;
189       if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
190         ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed,
191                             thread.GetProcess().get(), current_stack_argument);
192       } else if (compiler_type.IsPointerType()) {
193         ReadIntegerArgument(value->GetScalar(), *bit_size, false,
194                             thread.GetProcess().get(), current_stack_argument);
195       }
196     }
197   }
198   return true;
199 }
200 
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)201 Status ABISysV_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
202                                           lldb::ValueObjectSP &new_value_sp) {
203   Status error;
204   if (!new_value_sp) {
205     error = Status::FromErrorString("Empty value object for return value.");
206     return error;
207   }
208 
209   CompilerType compiler_type = new_value_sp->GetCompilerType();
210   if (!compiler_type) {
211     error = Status::FromErrorString("Null clang type for return value.");
212     return error;
213   }
214 
215   const uint32_t type_flags = compiler_type.GetTypeInfo();
216   Thread *thread = frame_sp->GetThread().get();
217   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
218   DataExtractor data;
219   Status data_error;
220   size_t num_bytes = new_value_sp->GetData(data, data_error);
221   bool register_write_successful = true;
222 
223   if (data_error.Fail()) {
224     error = Status::FromErrorStringWithFormat(
225         "Couldn't convert return value to raw data: %s",
226         data_error.AsCString());
227     return error;
228   }
229 
230   // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
231   // The terminology 'Fundamental Data Types' used here is adopted from Table
232   // 2.1 of the reference document (specified on top of this file)
233 
234   if (type_flags & eTypeIsPointer) // 'Pointer'
235   {
236     if (num_bytes != sizeof(uint32_t)) {
237       error =
238           Status::FromErrorString("Pointer to be returned is not 4 bytes wide");
239       return error;
240     }
241     lldb::offset_t offset = 0;
242     const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
243     uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
244     register_write_successful =
245         reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
246   } else if ((type_flags & eTypeIsScalar) ||
247              (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
248   {
249     lldb::offset_t offset = 0;
250     const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
251 
252     if (type_flags & eTypeIsInteger) // 'Integral' except enum
253     {
254       switch (num_bytes) {
255       default:
256         break;
257       case 16:
258         // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
259         // handle it
260         break;
261       case 8: {
262         uint32_t raw_value_low = data.GetMaxU32(&offset, 4);
263         const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
264         uint32_t raw_value_high = data.GetMaxU32(&offset, num_bytes - offset);
265         register_write_successful =
266             (reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value_low) &&
267              reg_ctx->WriteRegisterFromUnsigned(edx_info, raw_value_high));
268         break;
269       }
270       case 4:
271       case 2:
272       case 1: {
273         uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
274         register_write_successful =
275             reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
276         break;
277       }
278       }
279     } else if (type_flags & eTypeIsEnumeration) // handles enum
280     {
281       uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
282       register_write_successful =
283           reg_ctx->WriteRegisterFromUnsigned(eax_info, raw_value);
284     } else if (type_flags & eTypeIsFloat) // 'Floating Point'
285     {
286       RegisterValue st0_value, fstat_value, ftag_value;
287       const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
288       const RegisterInfo *fstat_info =
289           reg_ctx->GetRegisterInfoByName("fstat", 0);
290       const RegisterInfo *ftag_info = reg_ctx->GetRegisterInfoByName("ftag", 0);
291 
292       /* According to Page 3-12 of document
293       System V Application Binary Interface, Intel386 Architecture Processor
294       Supplement, Fourth Edition
295       To return Floating Point values, all st% registers except st0 should be
296       empty after exiting from
297       a function. This requires setting fstat and ftag registers to specific
298       values.
299       fstat: The TOP field of fstat should be set to a value [0,7]. ABI doesn't
300       specify the specific
301       value of TOP in case of function return. Hence, we set the TOP field to 7
302       by our choice. */
303       uint32_t value_fstat_u32 = 0x00003800;
304 
305       /* ftag: Implication of setting TOP to 7 and indicating all st% registers
306       empty except st0 is to set
307       7th bit of 4th byte of FXSAVE area to 1 and all other bits of this byte to
308       0. This is in accordance
309       with the document Intel 64 and IA-32 Architectures Software Developer's
310       Manual, January 2015 */
311       uint32_t value_ftag_u32 = 0x00000080;
312 
313       if (num_bytes <= 12) // handles float, double, long double, __float80
314       {
315         long double value_long_dbl = 0.0;
316         if (num_bytes == 4)
317           value_long_dbl = data.GetFloat(&offset);
318         else if (num_bytes == 8)
319           value_long_dbl = data.GetDouble(&offset);
320         else if (num_bytes == 12)
321           value_long_dbl = data.GetLongDouble(&offset);
322         else {
323           error = Status::FromErrorString(
324               "Invalid number of bytes for this return type");
325           return error;
326         }
327         st0_value.SetLongDouble(value_long_dbl);
328         fstat_value.SetUInt32(value_fstat_u32);
329         ftag_value.SetUInt32(value_ftag_u32);
330         register_write_successful =
331             reg_ctx->WriteRegister(st0_info, st0_value) &&
332             reg_ctx->WriteRegister(fstat_info, fstat_value) &&
333             reg_ctx->WriteRegister(ftag_info, ftag_value);
334       } else if (num_bytes == 16) // handles __float128
335       {
336         error = Status::FromErrorString(
337             "Implementation is missing for this clang type.");
338       }
339     } else {
340       // Neither 'Integral' nor 'Floating Point'. If flow reaches here then
341       // check type_flags. This type_flags is not a valid type.
342       error = Status::FromErrorString("Invalid clang type");
343     }
344   } else {
345     /* 'Complex Floating Point', 'Packed', 'Decimal Floating Point' and
346     'Aggregate' data types
347     are yet to be implemented */
348     error = Status::FromErrorString(
349         "Currently only Integral and Floating Point clang "
350         "types are supported.");
351   }
352   if (!register_write_successful)
353     error = Status::FromErrorString("Register writing failed");
354   return error;
355 }
356 
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const357 ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
358     Thread &thread, CompilerType &return_compiler_type) const {
359   ValueObjectSP return_valobj_sp;
360   Value value;
361 
362   if (!return_compiler_type)
363     return return_valobj_sp;
364 
365   value.SetCompilerType(return_compiler_type);
366 
367   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
368   if (!reg_ctx)
369     return return_valobj_sp;
370 
371   const uint32_t type_flags = return_compiler_type.GetTypeInfo();
372 
373   unsigned eax_id =
374       reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
375   unsigned edx_id =
376       reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
377 
378   // Following "IF ELSE" block categorizes various 'Fundamental Data Types'.
379   // The terminology 'Fundamental Data Types' used here is adopted from Table
380   // 2.1 of the reference document (specified on top of this file)
381 
382   if (type_flags & eTypeIsPointer) // 'Pointer'
383   {
384     uint32_t ptr =
385         thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
386         0xffffffff;
387     value.SetValueType(Value::ValueType::Scalar);
388     value.GetScalar() = ptr;
389     return_valobj_sp = ValueObjectConstResult::Create(
390         thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
391   } else if ((type_flags & eTypeIsScalar) ||
392              (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
393   {
394     value.SetValueType(Value::ValueType::Scalar);
395     std::optional<uint64_t> byte_size =
396         llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
397     if (!byte_size)
398       return return_valobj_sp;
399     bool success = false;
400 
401     if (type_flags & eTypeIsInteger) // 'Integral' except enum
402     {
403       const bool is_signed = ((type_flags & eTypeIsSigned) != 0);
404       uint64_t raw_value =
405           thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
406           0xffffffff;
407       raw_value |=
408           (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) &
409            0xffffffff)
410           << 32;
411 
412       switch (*byte_size) {
413       default:
414         break;
415 
416       case 16:
417         // For clang::BuiltinType::UInt128 & Int128 ToDo: Need to decide how to
418         // handle it
419         break;
420 
421       case 8:
422         if (is_signed)
423           value.GetScalar() = (int64_t)(raw_value);
424         else
425           value.GetScalar() = (uint64_t)(raw_value);
426         success = true;
427         break;
428 
429       case 4:
430         if (is_signed)
431           value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
432         else
433           value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
434         success = true;
435         break;
436 
437       case 2:
438         if (is_signed)
439           value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
440         else
441           value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
442         success = true;
443         break;
444 
445       case 1:
446         if (is_signed)
447           value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
448         else
449           value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
450         success = true;
451         break;
452       }
453 
454       if (success)
455         return_valobj_sp = ValueObjectConstResult::Create(
456             thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
457     } else if (type_flags & eTypeIsEnumeration) // handles enum
458     {
459       uint32_t enm =
460           thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
461           0xffffffff;
462       value.SetValueType(Value::ValueType::Scalar);
463       value.GetScalar() = enm;
464       return_valobj_sp = ValueObjectConstResult::Create(
465           thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
466     } else if (type_flags & eTypeIsFloat) // 'Floating Point'
467     {
468       if (*byte_size <= 12) // handles float, double, long double, __float80
469       {
470         const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
471         RegisterValue st0_value;
472 
473         if (reg_ctx->ReadRegister(st0_info, st0_value)) {
474           DataExtractor data;
475           if (st0_value.GetData(data)) {
476             lldb::offset_t offset = 0;
477             long double value_long_double = data.GetLongDouble(&offset);
478 
479             // float is 4 bytes.
480             if (*byte_size == 4) {
481               float value_float = (float)value_long_double;
482               value.GetScalar() = value_float;
483               success = true;
484             } else if (*byte_size == 8) {
485               // double is 8 bytes
486               // On Android Platform: long double is also 8 bytes It will be
487               // handled here only.
488               double value_double = (double)value_long_double;
489               value.GetScalar() = value_double;
490               success = true;
491             } else if (*byte_size == 12) {
492               // long double and __float80 are 12 bytes on i386.
493               value.GetScalar() = value_long_double;
494               success = true;
495             }
496           }
497         }
498 
499         if (success)
500           return_valobj_sp = ValueObjectConstResult::Create(
501               thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
502       } else if (*byte_size == 16) // handles __float128
503       {
504         lldb::addr_t storage_addr = (uint32_t)(
505             thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
506             0xffffffff);
507         return_valobj_sp = ValueObjectMemory::Create(
508             &thread, "", Address(storage_addr, nullptr), return_compiler_type);
509       }
510     } else // Neither 'Integral' nor 'Floating Point'
511     {
512       // If flow reaches here then check type_flags This type_flags is
513       // unhandled
514     }
515   } else if (type_flags & eTypeIsComplex) // 'Complex Floating Point'
516   {
517     // ToDo: Yet to be implemented
518   } else if (type_flags & eTypeIsVector) // 'Packed'
519   {
520     std::optional<uint64_t> byte_size =
521         llvm::expectedToOptional(return_compiler_type.GetByteSize(&thread));
522     if (byte_size && *byte_size > 0) {
523       const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
524       if (vec_reg == nullptr)
525         vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
526 
527       if (vec_reg) {
528         if (*byte_size <= vec_reg->byte_size) {
529           ProcessSP process_sp(thread.GetProcess());
530           if (process_sp) {
531             std::unique_ptr<DataBufferHeap> heap_data_up(
532                 new DataBufferHeap(*byte_size, 0));
533             const ByteOrder byte_order = process_sp->GetByteOrder();
534             RegisterValue reg_value;
535             if (reg_ctx->ReadRegister(vec_reg, reg_value)) {
536               Status error;
537               if (reg_value.GetAsMemoryData(*vec_reg, heap_data_up->GetBytes(),
538                                             heap_data_up->GetByteSize(),
539                                             byte_order, error)) {
540                 DataExtractor data(DataBufferSP(heap_data_up.release()),
541                                    byte_order,
542                                    process_sp->GetTarget()
543                                        .GetArchitecture()
544                                        .GetAddressByteSize());
545                 return_valobj_sp = ValueObjectConstResult::Create(
546                     &thread, return_compiler_type, ConstString(""), data);
547               }
548             }
549           }
550         } else if (*byte_size <= vec_reg->byte_size * 2) {
551           const RegisterInfo *vec_reg2 =
552               reg_ctx->GetRegisterInfoByName("xmm1", 0);
553           if (vec_reg2) {
554             ProcessSP process_sp(thread.GetProcess());
555             if (process_sp) {
556               std::unique_ptr<DataBufferHeap> heap_data_up(
557                   new DataBufferHeap(*byte_size, 0));
558               const ByteOrder byte_order = process_sp->GetByteOrder();
559               RegisterValue reg_value;
560               RegisterValue reg_value2;
561               if (reg_ctx->ReadRegister(vec_reg, reg_value) &&
562                   reg_ctx->ReadRegister(vec_reg2, reg_value2)) {
563 
564                 Status error;
565                 if (reg_value.GetAsMemoryData(
566                         *vec_reg, heap_data_up->GetBytes(), vec_reg->byte_size,
567                         byte_order, error) &&
568                     reg_value2.GetAsMemoryData(
569                         *vec_reg2,
570                         heap_data_up->GetBytes() + vec_reg->byte_size,
571                         heap_data_up->GetByteSize() - vec_reg->byte_size,
572                         byte_order, error)) {
573                   DataExtractor data(DataBufferSP(heap_data_up.release()),
574                                      byte_order,
575                                      process_sp->GetTarget()
576                                          .GetArchitecture()
577                                          .GetAddressByteSize());
578                   return_valobj_sp = ValueObjectConstResult::Create(
579                       &thread, return_compiler_type, ConstString(""), data);
580                 }
581               }
582             }
583           }
584         }
585       }
586     }
587   } else // 'Decimal Floating Point'
588   {
589     // ToDo: Yet to be implemented
590   }
591   return return_valobj_sp;
592 }
593 
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const594 ValueObjectSP ABISysV_i386::GetReturnValueObjectImpl(
595     Thread &thread, CompilerType &return_compiler_type) const {
596   ValueObjectSP return_valobj_sp;
597 
598   if (!return_compiler_type)
599     return return_valobj_sp;
600 
601   ExecutionContext exe_ctx(thread.shared_from_this());
602   return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
603   if (return_valobj_sp)
604     return return_valobj_sp;
605 
606   RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
607   if (!reg_ctx_sp)
608     return return_valobj_sp;
609 
610   if (return_compiler_type.IsAggregateType()) {
611     unsigned eax_id =
612         reg_ctx_sp->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
613     lldb::addr_t storage_addr = (uint32_t)(
614         thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
615         0xffffffff);
616     return_valobj_sp = ValueObjectMemory::Create(
617         &thread, "", Address(storage_addr, nullptr), return_compiler_type);
618   }
619 
620   return return_valobj_sp;
621 }
622 
623 // This defines CFA as esp+4
624 // The saved pc is at CFA-4 (i.e. esp+0)
625 // The saved esp is CFA+0
626 
CreateFunctionEntryUnwindPlan()627 UnwindPlanSP ABISysV_i386::CreateFunctionEntryUnwindPlan() {
628   uint32_t sp_reg_num = dwarf_esp;
629   uint32_t pc_reg_num = dwarf_eip;
630 
631   UnwindPlan::Row row;
632   row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 4);
633   row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
634   row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
635 
636   auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
637   plan_sp->AppendRow(std::move(row));
638   plan_sp->SetSourceName("i386 at-func-entry default");
639   plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
640   return plan_sp;
641 }
642 
643 // This defines CFA as ebp+8
644 // The saved pc is at CFA-4 (i.e. ebp+4)
645 // The saved ebp is at CFA-8 (i.e. ebp+0)
646 // The saved esp is CFA+0
647 
CreateDefaultUnwindPlan()648 UnwindPlanSP ABISysV_i386::CreateDefaultUnwindPlan() {
649   uint32_t fp_reg_num = dwarf_ebp;
650   uint32_t sp_reg_num = dwarf_esp;
651   uint32_t pc_reg_num = dwarf_eip;
652 
653   UnwindPlan::Row row;
654   const int32_t ptr_size = 4;
655 
656   row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
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   auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
664   plan_sp->AppendRow(std::move(row));
665   plan_sp->SetSourceName("i386 default unwind plan");
666   plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
667   plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
668   plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
669   return plan_sp;
670 }
671 
672 // According to "Register Usage" in reference document (specified on top of
673 // this source file) ebx, ebp, esi, edi and esp registers are preserved i.e.
674 // non-volatile i.e. callee-saved on i386
RegisterIsCalleeSaved(const RegisterInfo * reg_info)675 bool ABISysV_i386::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
676   if (!reg_info)
677     return false;
678 
679   // Saved registers are ebx, ebp, esi, edi, esp, eip
680   const char *name = reg_info->name;
681   if (name[0] == 'e') {
682     switch (name[1]) {
683     case 'b':
684       if (name[2] == 'x' || name[2] == 'p')
685         return name[3] == '\0';
686       break;
687     case 'd':
688       if (name[2] == 'i')
689         return name[3] == '\0';
690       break;
691     case 'i':
692       if (name[2] == 'p')
693         return name[3] == '\0';
694       break;
695     case 's':
696       if (name[2] == 'i' || name[2] == 'p')
697         return name[3] == '\0';
698       break;
699     }
700   }
701 
702   if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
703     return true;
704   if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
705     return true;
706   if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
707     return true;
708 
709   return false;
710 }
711 
Initialize()712 void ABISysV_i386::Initialize() {
713   PluginManager::RegisterPlugin(
714       GetPluginNameStatic(), "System V ABI for i386 targets", CreateInstance);
715 }
716 
Terminate()717 void ABISysV_i386::Terminate() {
718   PluginManager::UnregisterPlugin(CreateInstance);
719 }
720