Coverage Report

Created: 2022-07-16 07:03

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