Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ABIWindows_x86_64.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
9
#include "ABIWindows_x86_64.h"
10
11
#include "llvm/ADT/STLExtras.h"
12
#include "llvm/ADT/StringSwitch.h"
13
#include "llvm/ADT/Triple.h"
14
15
#include "lldb/Core/Module.h"
16
#include "lldb/Core/PluginManager.h"
17
#include "lldb/Core/Value.h"
18
#include "lldb/Core/ValueObjectConstResult.h"
19
#include "lldb/Core/ValueObjectMemory.h"
20
#include "lldb/Core/ValueObjectRegister.h"
21
#include "lldb/Symbol/UnwindPlan.h"
22
#include "lldb/Target/Process.h"
23
#include "lldb/Target/RegisterContext.h"
24
#include "lldb/Target/StackFrame.h"
25
#include "lldb/Target/Target.h"
26
#include "lldb/Target/Thread.h"
27
#include "lldb/Utility/ConstString.h"
28
#include "lldb/Utility/DataExtractor.h"
29
#include "lldb/Utility/Log.h"
30
#include "lldb/Utility/RegisterValue.h"
31
#include "lldb/Utility/Status.h"
32
33
using namespace lldb;
34
using namespace lldb_private;
35
36
LLDB_PLUGIN_DEFINE(ABIWindows_x86_64)
37
38
enum dwarf_regnums {
39
  dwarf_rax = 0,
40
  dwarf_rdx,
41
  dwarf_rcx,
42
  dwarf_rbx,
43
  dwarf_rsi,
44
  dwarf_rdi,
45
  dwarf_rbp,
46
  dwarf_rsp,
47
  dwarf_r8,
48
  dwarf_r9,
49
  dwarf_r10,
50
  dwarf_r11,
51
  dwarf_r12,
52
  dwarf_r13,
53
  dwarf_r14,
54
  dwarf_r15,
55
  dwarf_rip,
56
  dwarf_xmm0,
57
  dwarf_xmm1,
58
  dwarf_xmm2,
59
  dwarf_xmm3,
60
  dwarf_xmm4,
61
  dwarf_xmm5,
62
  dwarf_xmm6,
63
  dwarf_xmm7,
64
  dwarf_xmm8,
65
  dwarf_xmm9,
66
  dwarf_xmm10,
67
  dwarf_xmm11,
68
  dwarf_xmm12,
69
  dwarf_xmm13,
70
  dwarf_xmm14,
71
  dwarf_xmm15,
72
  dwarf_stmm0,
73
  dwarf_stmm1,
74
  dwarf_stmm2,
75
  dwarf_stmm3,
76
  dwarf_stmm4,
77
  dwarf_stmm5,
78
  dwarf_stmm6,
79
  dwarf_stmm7,
80
  dwarf_ymm0,
81
  dwarf_ymm1,
82
  dwarf_ymm2,
83
  dwarf_ymm3,
84
  dwarf_ymm4,
85
  dwarf_ymm5,
86
  dwarf_ymm6,
87
  dwarf_ymm7,
88
  dwarf_ymm8,
89
  dwarf_ymm9,
90
  dwarf_ymm10,
91
  dwarf_ymm11,
92
  dwarf_ymm12,
93
  dwarf_ymm13,
94
  dwarf_ymm14,
95
  dwarf_ymm15,
96
  dwarf_bnd0 = 126,
97
  dwarf_bnd1,
98
  dwarf_bnd2,
99
  dwarf_bnd3
100
};
101
102
0
bool ABIWindows_x86_64::GetPointerReturnRegister(const char *&name) {
103
0
  name = "rax";
104
0
  return true;
105
0
}
106
107
0
size_t ABIWindows_x86_64::GetRedZoneSize() const { return 0; }
108
109
//------------------------------------------------------------------
110
// Static Functions
111
//------------------------------------------------------------------
112
113
ABISP
114
49
ABIWindows_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
115
49
  if (arch.GetTriple().getArch() == llvm::Triple::x86_64 &&
116
49
      
arch.GetTriple().isOSWindows()4
) {
117
4
    return ABISP(
118
4
        new ABIWindows_x86_64(std::move(process_sp), MakeMCRegisterInfo(arch)));
119
4
  }
120
45
  return ABISP();
121
49
}
122
123
bool ABIWindows_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
124
                                           addr_t func_addr, addr_t return_addr,
125
0
                                           llvm::ArrayRef<addr_t> args) const {
126
0
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
127
128
0
  if (log) {
129
0
    StreamString s;
130
0
    s.Printf("ABIWindows_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
131
0
             ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
132
0
             ", return_addr = 0x%" PRIx64,
133
0
             thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
134
0
             (uint64_t)return_addr);
135
136
0
    for (size_t i = 0; i < args.size(); ++i)
137
0
      s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
138
0
               args[i]);
139
0
    s.PutCString(")");
140
0
    log->PutString(s.GetString());
141
0
  }
142
143
0
  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
144
0
  if (!reg_ctx)
145
0
    return false;
146
147
0
  const RegisterInfo *reg_info = nullptr;
148
149
0
  if (args.size() > 4) // Windows x64 only put first 4 arguments into registers
150
0
    return false;
151
152
0
  for (size_t i = 0; i < args.size(); ++i) {
153
0
    reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
154
0
                                        LLDB_REGNUM_GENERIC_ARG1 + i);
155
0
    LLDB_LOGF(log, "About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
156
0
              static_cast<uint64_t>(i + 1), args[i], reg_info->name);
157
0
    if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
158
0
      return false;
159
0
  }
160
161
  // First, align the SP
162
163
0
  LLDB_LOGF(log, "16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
164
0
            (uint64_t)sp, (uint64_t)(sp & ~0xfull));
165
166
0
  sp &= ~(0xfull); // 16-byte alignment
167
168
0
  sp -= 8; // return address
169
170
0
  Status error;
171
0
  const RegisterInfo *pc_reg_info =
172
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
173
0
  const RegisterInfo *sp_reg_info =
174
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
175
0
  ProcessSP process_sp(thread.GetProcess());
176
177
0
  RegisterValue reg_value;
178
0
  LLDB_LOGF(log,
179
0
            "Pushing the return address onto the stack: 0x%" PRIx64
180
0
            ": 0x%" PRIx64,
181
0
            (uint64_t)sp, (uint64_t)return_addr);
182
183
  // Save return address onto the stack
184
0
  if (!process_sp->WritePointerToMemory(sp, return_addr, error))
185
0
    return false;
186
187
  // %rsp is set to the actual stack value.
188
189
0
  LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
190
191
0
  if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
192
0
    return false;
193
194
  // %rip is set to the address of the called function.
195
196
0
  LLDB_LOGF(log, "Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
197
198
0
  if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
199
0
    return false;
200
201
0
  return true;
202
0
}
203
204
static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
205
                                bool is_signed, Thread &thread,
206
                                uint32_t *argument_register_ids,
207
                                unsigned int &current_argument_register,
208
0
                                addr_t &current_stack_argument) {
209
0
  if (bit_width > 64)
210
0
    return false; // Scalar can't hold large integer arguments
211
212
0
  if (current_argument_register < 4) { // Windows pass first 4 arguments to register
213
0
    scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
214
0
        argument_register_ids[current_argument_register], 0);
215
0
    current_argument_register++;
216
0
    if (is_signed)
217
0
      scalar.SignExtend(bit_width);
218
0
    return true;
219
0
  }
220
0
  uint32_t byte_size = (bit_width + (CHAR_BIT - 1)) / CHAR_BIT;
221
0
  Status error;
222
0
  if (thread.GetProcess()->ReadScalarIntegerFromMemory(
223
0
          current_stack_argument, byte_size, is_signed, scalar, error)) {
224
0
    current_stack_argument += byte_size;
225
0
    return true;
226
0
  }
227
0
  return false;
228
0
}
229
230
bool ABIWindows_x86_64::GetArgumentValues(Thread &thread,
231
0
                                       ValueList &values) const {
232
0
  unsigned int num_values = values.GetSize();
233
0
  unsigned int value_index;
234
235
  // Extract the register context so we can read arguments from registers
236
237
0
  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
238
239
0
  if (!reg_ctx)
240
0
    return false;
241
242
  // Get the pointer to the first stack argument so we have a place to start
243
  // when reading data
244
245
0
  addr_t sp = reg_ctx->GetSP(0);
246
247
0
  if (!sp)
248
0
    return false;
249
250
0
  addr_t current_stack_argument = sp + 8; // jump over return address
251
252
0
  uint32_t argument_register_ids[4];
253
254
0
  argument_register_ids[0] =
255
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
256
0
          ->kinds[eRegisterKindLLDB];
257
0
  argument_register_ids[1] =
258
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
259
0
          ->kinds[eRegisterKindLLDB];
260
0
  argument_register_ids[2] =
261
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
262
0
          ->kinds[eRegisterKindLLDB];
263
0
  argument_register_ids[3] =
264
0
      reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
265
0
          ->kinds[eRegisterKindLLDB];
266
267
0
  unsigned int current_argument_register = 0;
268
269
0
  for (value_index = 0; value_index < num_values; ++value_index) {
270
0
    Value *value = values.GetValueAtIndex(value_index);
271
272
0
    if (!value)
273
0
      return false;
274
275
0
    CompilerType compiler_type = value->GetCompilerType();
276
0
    llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
277
0
    if (!bit_size)
278
0
      return false;
279
0
    bool is_signed;
280
281
0
    if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
282
0
      ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
283
0
                          argument_register_ids, current_argument_register,
284
0
                          current_stack_argument);
285
0
    } else if (compiler_type.IsPointerType()) {
286
0
      ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
287
0
                          argument_register_ids, current_argument_register,
288
0
                          current_stack_argument);
289
0
    }
290
0
  }
291
292
0
  return true;
293
0
}
294
295
Status ABIWindows_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
296
0
                                            lldb::ValueObjectSP &new_value_sp) {
297
0
  Status error;
298
0
  if (!new_value_sp) {
299
0
    error.SetErrorString("Empty value object for return value.");
300
0
    return error;
301
0
  }
302
303
0
  CompilerType compiler_type = new_value_sp->GetCompilerType();
304
0
  if (!compiler_type) {
305
0
    error.SetErrorString("Null clang type for return value.");
306
0
    return error;
307
0
  }
308
309
0
  Thread *thread = frame_sp->GetThread().get();
310
311
0
  bool is_signed;
312
0
  uint32_t count;
313
0
  bool is_complex;
314
315
0
  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
316
317
0
  bool set_it_simple = false;
318
0
  if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
319
0
      compiler_type.IsPointerType()) {
320
0
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
321
322
0
    DataExtractor data;
323
0
    Status data_error;
324
0
    size_t num_bytes = new_value_sp->GetData(data, data_error);
325
0
    if (data_error.Fail()) {
326
0
      error.SetErrorStringWithFormat(
327
0
          "Couldn't convert return value to raw data: %s",
328
0
          data_error.AsCString());
329
0
      return error;
330
0
    }
331
0
    lldb::offset_t offset = 0;
332
0
    if (num_bytes <= 8) {
333
0
      uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
334
335
0
      if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
336
0
        set_it_simple = true;
337
0
    } else {
338
0
      error.SetErrorString("We don't support returning longer than 64 bit "
339
0
                           "integer values at present.");
340
0
    }
341
0
  } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
342
0
    if (is_complex)
343
0
      error.SetErrorString(
344
0
          "We don't support returning complex values at present");
345
0
    else {
346
0
      llvm::Optional<uint64_t> bit_width =
347
0
          compiler_type.GetBitSize(frame_sp.get());
348
0
      if (!bit_width) {
349
0
        error.SetErrorString("can't get type size");
350
0
        return error;
351
0
      }
352
0
      if (*bit_width <= 64) {
353
0
        const RegisterInfo *xmm0_info =
354
0
            reg_ctx->GetRegisterInfoByName("xmm0", 0);
355
0
        RegisterValue xmm0_value;
356
0
        DataExtractor data;
357
0
        Status data_error;
358
0
        size_t num_bytes = new_value_sp->GetData(data, data_error);
359
0
        if (data_error.Fail()) {
360
0
          error.SetErrorStringWithFormat(
361
0
              "Couldn't convert return value to raw data: %s",
362
0
              data_error.AsCString());
363
0
          return error;
364
0
        }
365
366
0
        unsigned char buffer[16];
367
0
        ByteOrder byte_order = data.GetByteOrder();
368
369
0
        data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
370
0
        xmm0_value.SetBytes(buffer, 16, byte_order);
371
0
        reg_ctx->WriteRegister(xmm0_info, xmm0_value);
372
0
        set_it_simple = true;
373
0
      } else {
374
        // Windows doesn't support 80 bit FP
375
0
        error.SetErrorString(
376
0
            "Windows-x86_64 doesn't allow FP larger than 64 bits.");
377
0
      }
378
0
    }
379
0
  }
380
381
0
  if (!set_it_simple) {
382
    // Okay we've got a structure or something that doesn't fit in a simple
383
    // register.
384
    // TODO(wanyi): On Windows, if the return type is a struct:
385
    // 1) smaller that 64 bits and return by value -> RAX
386
    // 2) bigger than 64 bits, the caller will allocate memory for that struct
387
    // and pass the struct pointer in RCX then return the pointer in RAX
388
0
    error.SetErrorString("We only support setting simple integer and float "
389
0
                         "return types at present.");
390
0
  }
391
392
0
  return error;
393
0
}
394
395
ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectSimple(
396
0
    Thread &thread, CompilerType &return_compiler_type) const {
397
0
  ValueObjectSP return_valobj_sp;
398
0
  Value value;
399
400
0
  if (!return_compiler_type)
401
0
    return return_valobj_sp;
402
403
0
  value.SetCompilerType(return_compiler_type);
404
405
0
  RegisterContext *reg_ctx = thread.GetRegisterContext().get();
406
0
  if (!reg_ctx)
407
0
    return return_valobj_sp;
408
409
0
  const uint32_t type_flags = return_compiler_type.GetTypeInfo();
410
0
  if (type_flags & eTypeIsScalar) {
411
0
    value.SetValueType(Value::ValueType::Scalar);
412
413
0
    bool success = false;
414
0
    if (type_flags & eTypeIsInteger) {
415
      // Extract the register context so we can read arguments from registers
416
0
      llvm::Optional<uint64_t> byte_size =
417
0
          return_compiler_type.GetByteSize(&thread);
418
0
      if (!byte_size)
419
0
        return return_valobj_sp;
420
0
      uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
421
0
          reg_ctx->GetRegisterInfoByName("rax", 0), 0);
422
0
      const bool is_signed = (type_flags & eTypeIsSigned) != 0;
423
0
      switch (*byte_size) {
424
0
      default:
425
0
        break;
426
427
0
      case sizeof(uint64_t):
428
0
        if (is_signed)
429
0
          value.GetScalar() = (int64_t)(raw_value);
430
0
        else
431
0
          value.GetScalar() = (uint64_t)(raw_value);
432
0
        success = true;
433
0
        break;
434
435
0
      case sizeof(uint32_t):
436
0
        if (is_signed)
437
0
          value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
438
0
        else
439
0
          value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
440
0
        success = true;
441
0
        break;
442
443
0
      case sizeof(uint16_t):
444
0
        if (is_signed)
445
0
          value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
446
0
        else
447
0
          value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
448
0
        success = true;
449
0
        break;
450
451
0
      case sizeof(uint8_t):
452
0
        if (is_signed)
453
0
          value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
454
0
        else
455
0
          value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
456
0
        success = true;
457
0
        break;
458
0
      }
459
0
    } else if (type_flags & eTypeIsFloat) {
460
0
      if (type_flags & eTypeIsComplex) {
461
        // Don't handle complex yet.
462
0
      } else {
463
0
        llvm::Optional<uint64_t> byte_size =
464
0
            return_compiler_type.GetByteSize(&thread);
465
0
        if (byte_size && *byte_size <= sizeof(long double)) {
466
0
          const RegisterInfo *xmm0_info =
467
0
              reg_ctx->GetRegisterInfoByName("xmm0", 0);
468
0
          RegisterValue xmm0_value;
469
0
          if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
470
0
            DataExtractor data;
471
0
            if (xmm0_value.GetData(data)) {
472
0
              lldb::offset_t offset = 0;
473
0
              if (*byte_size == sizeof(float)) {
474
0
                value.GetScalar() = (float)data.GetFloat(&offset);
475
0
                success = true;
476
0
              } else if (*byte_size == sizeof(double)) {
477
                // double and long double are the same on windows
478
0
                value.GetScalar() = (double)data.GetDouble(&offset);
479
0
                success = true;
480
0
              }
481
0
            }
482
0
          }
483
0
        }
484
0
      }
485
0
    }
486
487
0
    if (success)
488
0
      return_valobj_sp = ValueObjectConstResult::Create(
489
0
          thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
490
0
  } else if ((type_flags & eTypeIsPointer) ||
491
0
             (type_flags & eTypeInstanceIsPointer)) {
492
0
    unsigned rax_id =
493
0
        reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
494
0
    value.GetScalar() =
495
0
        (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
496
0
                                                                      0);
497
0
    value.SetValueType(Value::ValueType::Scalar);
498
0
    return_valobj_sp = ValueObjectConstResult::Create(
499
0
        thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
500
0
  } else if (type_flags & eTypeIsVector) {
501
0
    llvm::Optional<uint64_t> byte_size =
502
0
        return_compiler_type.GetByteSize(&thread);
503
0
    if (byte_size && *byte_size > 0) {
504
0
      const RegisterInfo *xmm_reg =
505
0
          reg_ctx->GetRegisterInfoByName("xmm0", 0);
506
0
      if (xmm_reg == nullptr)
507
0
        xmm_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
508
509
0
      if (xmm_reg) {
510
0
        if (*byte_size <= xmm_reg->byte_size) {
511
0
          ProcessSP process_sp(thread.GetProcess());
512
0
          if (process_sp) {
513
0
            std::unique_ptr<DataBufferHeap> heap_data_up(
514
0
                new DataBufferHeap(*byte_size, 0));
515
0
            const ByteOrder byte_order = process_sp->GetByteOrder();
516
0
            RegisterValue reg_value;
517
0
            if (reg_ctx->ReadRegister(xmm_reg, reg_value)) {
518
0
              Status error;
519
0
              if (reg_value.GetAsMemoryData(
520
0
                      xmm_reg, heap_data_up->GetBytes(),
521
0
                      heap_data_up->GetByteSize(), byte_order, error)) {
522
0
                DataExtractor data(DataBufferSP(heap_data_up.release()),
523
0
                                   byte_order,
524
0
                                   process_sp->GetTarget()
525
0
                                       .GetArchitecture()
526
0
                                       .GetAddressByteSize());
527
0
                return_valobj_sp = ValueObjectConstResult::Create(
528
0
                    &thread, return_compiler_type, ConstString(""), data);
529
0
              }
530
0
            }
531
0
          }
532
0
        }
533
0
      }
534
0
    }
535
0
  }
536
537
0
  return return_valobj_sp;
538
0
}
539
540
// The compiler will flatten the nested aggregate type into single
541
// layer and push the value to stack
542
// This helper function will flatten an aggregate type
543
// and return true if it can be returned in register(s) by value
544
// return false if the aggregate is in memory
545
static bool FlattenAggregateType(
546
    Thread &thread, ExecutionContext &exe_ctx,
547
    CompilerType &return_compiler_type,
548
    uint32_t data_byte_offset,
549
    std::vector<uint32_t> &aggregate_field_offsets,
550
0
    std::vector<CompilerType> &aggregate_compiler_types) {
551
552
0
  const uint32_t num_children = return_compiler_type.GetNumFields();
553
0
  for (uint32_t idx = 0; idx < num_children; ++idx) {
554
0
    std::string name;
555
0
    bool is_signed;
556
0
    uint32_t count;
557
0
    bool is_complex;
558
559
0
    uint64_t field_bit_offset = 0;
560
0
    CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
561
0
        idx, name, &field_bit_offset, nullptr, nullptr);
562
0
    llvm::Optional<uint64_t> field_bit_width =
563
0
          field_compiler_type.GetBitSize(&thread);
564
565
    // if we don't know the size of the field (e.g. invalid type), exit
566
0
    if (!field_bit_width || *field_bit_width == 0) {
567
0
      return false;
568
0
    }
569
    // If there are any unaligned fields, this is stored in memory.
570
0
    if (field_bit_offset % *field_bit_width != 0) {
571
0
      return false;
572
0
    }
573
574
    // add overall offset
575
0
    uint32_t field_byte_offset = field_bit_offset / 8 + data_byte_offset;
576
577
0
    const uint32_t field_type_flags = field_compiler_type.GetTypeInfo();
578
0
    if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
579
0
        field_compiler_type.IsPointerType() ||
580
0
        field_compiler_type.IsFloatingPointType(count, is_complex)) {
581
0
      aggregate_field_offsets.push_back(field_byte_offset);
582
0
      aggregate_compiler_types.push_back(field_compiler_type);
583
0
    } else if (field_type_flags & eTypeHasChildren) {
584
0
      if (!FlattenAggregateType(thread, exe_ctx, field_compiler_type,
585
0
                                field_byte_offset, aggregate_field_offsets,
586
0
                                aggregate_compiler_types)) {
587
0
        return false;
588
0
      }
589
0
    }
590
0
  }
591
0
  return true;
592
0
}
593
594
ValueObjectSP ABIWindows_x86_64::GetReturnValueObjectImpl(
595
0
    Thread &thread, CompilerType &return_compiler_type) const {
596
0
  ValueObjectSP return_valobj_sp;
597
598
0
  if (!return_compiler_type) {
599
0
    return return_valobj_sp;
600
0
  }
601
602
  // try extract value as if it's a simple type
603
0
  return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
604
0
  if (return_valobj_sp) {
605
0
    return return_valobj_sp;
606
0
  }
607
608
0
  RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
609
0
  if (!reg_ctx_sp) {
610
0
    return return_valobj_sp;
611
0
  }
612
613
0
  llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
614
0
  if (!bit_width) {
615
0
    return return_valobj_sp;
616
0
  }
617
618
  // if it's not simple or aggregate type, then we don't know how to handle it
619
0
  if (!return_compiler_type.IsAggregateType()) {
620
0
    return return_valobj_sp;
621
0
  }
622
623
0
  ExecutionContext exe_ctx(thread.shared_from_this());
624
0
  Target *target = exe_ctx.GetTargetPtr();
625
0
  uint32_t max_register_value_bit_width = 64;
626
627
  // The scenario here is to have a struct/class which is POD
628
  // if the return struct/class size is larger than 64 bits,
629
  // the caller will allocate memory for it and pass the return addr in RCX
630
  // then return the address in RAX
631
632
  // if the struct is returned by value in register (RAX)
633
  // its size has to be: 1, 2, 4, 8, 16, 32, or 64 bits (aligned)
634
  // for floating point, the return value will be copied over to RAX
635
0
  bool is_memory = *bit_width > max_register_value_bit_width ||
636
0
                   *bit_width & (*bit_width - 1);
637
0
  std::vector<uint32_t> aggregate_field_offsets;
638
0
  std::vector<CompilerType> aggregate_compiler_types;
639
0
  if (!is_memory &&
640
0
      FlattenAggregateType(thread, exe_ctx, return_compiler_type,
641
0
                           0, aggregate_field_offsets,
642
0
                           aggregate_compiler_types)) {
643
0
    ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
644
0
    DataBufferSP data_sp(
645
0
        new DataBufferHeap(max_register_value_bit_width / 8, 0));
646
0
    DataExtractor return_ext(data_sp, byte_order,
647
0
        target->GetArchitecture().GetAddressByteSize());
648
649
    // The only register used to return struct/class by value
650
0
    const RegisterInfo *rax_info =
651
0
        reg_ctx_sp->GetRegisterInfoByName("rax", 0);
652
0
    RegisterValue rax_value;
653
0
    reg_ctx_sp->ReadRegister(rax_info, rax_value);
654
0
    DataExtractor rax_data;
655
0
    rax_value.GetData(rax_data);
656
657
0
    uint32_t used_bytes =
658
0
        0; // Tracks how much of the rax registers we've consumed so far
659
660
    // in case of the returned type is a subclass of non-abstract-base class
661
    // it will have a padding to skip the base content
662
0
    if (aggregate_field_offsets.size())
663
0
      used_bytes = aggregate_field_offsets[0];
664
665
0
    const uint32_t num_children = aggregate_compiler_types.size();
666
0
    for (uint32_t idx = 0; idx < num_children; idx++) {
667
0
      bool is_signed;
668
0
      bool is_complex;
669
0
      uint32_t count;
670
671
0
      CompilerType field_compiler_type = aggregate_compiler_types[idx];
672
0
      uint32_t field_byte_width = (uint32_t) (*field_compiler_type.GetByteSize(&thread));
673
0
      uint32_t field_byte_offset = aggregate_field_offsets[idx];
674
675
      // this is unlikely w/o the overall size being greater than 8 bytes
676
      // For now, return a nullptr return value object.
677
0
      if (used_bytes >= 8 || used_bytes + field_byte_width > 8) {
678
0
        return return_valobj_sp;
679
0
      }
680
681
0
      DataExtractor *copy_from_extractor = nullptr;
682
0
      uint32_t copy_from_offset = 0;
683
0
      if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
684
0
          field_compiler_type.IsPointerType() ||
685
0
          field_compiler_type.IsFloatingPointType(count, is_complex)) {
686
0
        copy_from_extractor = &rax_data;
687
0
        copy_from_offset = used_bytes;
688
0
        used_bytes += field_byte_width;
689
0
      }
690
      // These two tests are just sanity checks.  If I somehow get the type
691
      // calculation wrong above it is better to just return nothing than to
692
      // assert or crash.
693
0
      if (!copy_from_extractor) {
694
0
        return return_valobj_sp;
695
0
      }
696
0
      if (copy_from_offset + field_byte_width >
697
0
          copy_from_extractor->GetByteSize()) {
698
0
        return return_valobj_sp;
699
0
      }
700
0
      copy_from_extractor->CopyByteOrderedData(copy_from_offset,
701
0
          field_byte_width, data_sp->GetBytes() + field_byte_offset,
702
0
          field_byte_width, byte_order);
703
0
    }
704
0
    if (!is_memory) {
705
      // The result is in our data buffer.  Let's make a variable object out
706
      // of it:
707
0
      return_valobj_sp = ValueObjectConstResult::Create(
708
0
          &thread, return_compiler_type, ConstString(""), return_ext);
709
0
    }
710
0
  }
711
712
  // The Windows x86_64 ABI specifies that the return address for MEMORY
713
  // objects be placed in rax on exit from the function.
714
715
  // FIXME: This is just taking a guess, rax may very well no longer hold the
716
  // return storage location.
717
  // If we are going to do this right, when we make a new frame we should
718
  // check to see if it uses a memory return, and if we are at the first
719
  // instruction and if so stash away the return location.  Then we would
720
  // only return the memory return value if we know it is valid.
721
0
  if (is_memory) {
722
0
    unsigned rax_id =
723
0
        reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
724
0
    lldb::addr_t storage_addr =
725
0
        (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
726
0
                                                                      0);
727
0
    return_valobj_sp = ValueObjectMemory::Create(
728
0
        &thread, "", Address(storage_addr, nullptr), return_compiler_type);
729
0
  }
730
0
  return return_valobj_sp;
731
0
}
732
733
// This defines the CFA as rsp+8
734
// the saved pc is at CFA-8 (i.e. rsp+0)
735
// The saved rsp is CFA+0
736
737
0
bool ABIWindows_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
738
0
  unwind_plan.Clear();
739
0
  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
740
741
0
  uint32_t sp_reg_num = dwarf_rsp;
742
0
  uint32_t pc_reg_num = dwarf_rip;
743
744
0
  UnwindPlan::RowSP row(new UnwindPlan::Row);
745
0
  row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
746
0
  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
747
0
  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
748
0
  unwind_plan.AppendRow(row);
749
0
  unwind_plan.SetSourceName("x86_64 at-func-entry default");
750
0
  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
751
0
  return true;
752
0
}
753
754
// Windows-x86_64 doesn't use %rbp
755
// No available Unwind information for Windows-x86_64 (section .pdata)
756
// Let's use SysV-x86_64 one for now
757
5
bool ABIWindows_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
758
5
  unwind_plan.Clear();
759
5
  unwind_plan.SetRegisterKind(eRegisterKindDWARF);
760
761
5
  uint32_t fp_reg_num = dwarf_rbp;
762
5
  uint32_t sp_reg_num = dwarf_rsp;
763
5
  uint32_t pc_reg_num = dwarf_rip;
764
765
5
  UnwindPlan::RowSP row(new UnwindPlan::Row);
766
767
5
  const int32_t ptr_size = 8;
768
5
  row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
769
5
  row->SetOffset(0);
770
5
  row->SetUnspecifiedRegistersAreUndefined(true);
771
772
5
  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
773
5
  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
774
5
  row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
775
776
5
  unwind_plan.AppendRow(row);
777
5
  unwind_plan.SetSourceName("x86_64 default unwind plan");
778
5
  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
779
5
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
780
781
5
  return true;
782
5
}
783
784
0
bool ABIWindows_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
785
0
  return !RegisterIsCalleeSaved(reg_info);
786
0
}
787
788
0
bool ABIWindows_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
789
0
  if (!reg_info)
790
0
    return false;
791
0
  assert(reg_info->name != nullptr && "unnamed register?");
792
0
  std::string Name = std::string(reg_info->name);
793
0
  bool IsCalleeSaved =
794
0
      llvm::StringSwitch<bool>(Name)
795
0
          .Cases("rbx", "ebx", "rbp", "ebp", "rdi", "edi", "rsi", "esi", true)
796
0
          .Cases("rsp", "esp", "r12", "r13", "r14", "r15", "sp", "fp", true)
797
0
          .Cases("xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
798
0
                 "xmm13", "xmm14", "xmm15", true)
799
0
          .Default(false);
800
0
  return IsCalleeSaved;
801
0
}
802
803
0
uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) {
804
0
  return llvm::StringSwitch<uint32_t>(reg)
805
0
      .Case("rip", LLDB_REGNUM_GENERIC_PC)
806
0
      .Case("rsp", LLDB_REGNUM_GENERIC_SP)
807
0
      .Case("rbp", LLDB_REGNUM_GENERIC_FP)
808
0
      .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS)
809
      // gdbserver uses eflags
810
0
      .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS)
811
0
      .Case("rcx", LLDB_REGNUM_GENERIC_ARG1)
812
0
      .Case("rdx", LLDB_REGNUM_GENERIC_ARG2)
813
0
      .Case("r8", LLDB_REGNUM_GENERIC_ARG3)
814
0
      .Case("r9", LLDB_REGNUM_GENERIC_ARG4)
815
0
      .Default(LLDB_INVALID_REGNUM);
816
0
}
817
818
3.44k
void ABIWindows_x86_64::Initialize() {
819
3.44k
  PluginManager::RegisterPlugin(
820
3.44k
      GetPluginNameStatic(), "Windows ABI for x86_64 targets", CreateInstance);
821
3.44k
}
822
823
3.43k
void ABIWindows_x86_64::Terminate() {
824
3.43k
  PluginManager::UnregisterPlugin(CreateInstance);
825
3.43k
}