Coverage Report

Created: 2023-09-30 09:22

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