[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- ABISysV_mips.cpp --------------------------------------------------===//
|
2015-06-18 15:02:10 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-06-18 15:02:10 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "ABISysV_mips.h"
|
|
|
|
|
2016-02-27 06:26:21 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/Triple.h"
|
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
#include "lldb/Core/Module.h"
|
|
|
|
#include "lldb/Core/PluginManager.h"
|
|
|
|
#include "lldb/Core/Value.h"
|
|
|
|
#include "lldb/Core/ValueObjectConstResult.h"
|
|
|
|
#include "lldb/Core/ValueObjectMemory.h"
|
|
|
|
#include "lldb/Core/ValueObjectRegister.h"
|
|
|
|
#include "lldb/Symbol/UnwindPlan.h"
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Target/RegisterContext.h"
|
|
|
|
#include "lldb/Target/StackFrame.h"
|
|
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "lldb/Target/Thread.h"
|
2017-02-03 05:39:50 +08:00
|
|
|
#include "lldb/Utility/ConstString.h"
|
2017-03-04 09:30:05 +08:00
|
|
|
#include "lldb/Utility/DataExtractor.h"
|
2017-03-04 04:56:28 +08:00
|
|
|
#include "lldb/Utility/Log.h"
|
2018-08-07 19:07:21 +08:00
|
|
|
#include "lldb/Utility/RegisterValue.h"
|
2017-05-12 12:51:55 +08:00
|
|
|
#include "lldb/Utility/Status.h"
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2020-02-08 06:58:18 +08:00
|
|
|
LLDB_PLUGIN(ABISysV_mips);
|
|
|
|
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
enum dwarf_regnums {
|
|
|
|
dwarf_r0 = 0,
|
|
|
|
dwarf_r1,
|
|
|
|
dwarf_r2,
|
|
|
|
dwarf_r3,
|
|
|
|
dwarf_r4,
|
|
|
|
dwarf_r5,
|
|
|
|
dwarf_r6,
|
|
|
|
dwarf_r7,
|
|
|
|
dwarf_r8,
|
|
|
|
dwarf_r9,
|
|
|
|
dwarf_r10,
|
|
|
|
dwarf_r11,
|
|
|
|
dwarf_r12,
|
|
|
|
dwarf_r13,
|
|
|
|
dwarf_r14,
|
|
|
|
dwarf_r15,
|
|
|
|
dwarf_r16,
|
|
|
|
dwarf_r17,
|
|
|
|
dwarf_r18,
|
|
|
|
dwarf_r19,
|
|
|
|
dwarf_r20,
|
|
|
|
dwarf_r21,
|
|
|
|
dwarf_r22,
|
|
|
|
dwarf_r23,
|
|
|
|
dwarf_r24,
|
|
|
|
dwarf_r25,
|
|
|
|
dwarf_r26,
|
|
|
|
dwarf_r27,
|
|
|
|
dwarf_r28,
|
|
|
|
dwarf_r29,
|
|
|
|
dwarf_r30,
|
|
|
|
dwarf_r31,
|
|
|
|
dwarf_sr,
|
|
|
|
dwarf_lo,
|
|
|
|
dwarf_hi,
|
|
|
|
dwarf_bad,
|
|
|
|
dwarf_cause,
|
|
|
|
dwarf_pc
|
2015-06-18 15:02:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static const RegisterInfo g_register_infos[] = {
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
|
|
|
|
// DWARF GENERIC PROCESS PLUGINS
|
|
|
|
// LLDB NATIVE VALUE REGS INVALIDATE REGS
|
|
|
|
// ======== ====== == === ============= =========== ============
|
|
|
|
// ============== ============ =================
|
|
|
|
// =================== ========== =================
|
2016-08-09 06:15:35 +08:00
|
|
|
{"r0",
|
|
|
|
"zero",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r1",
|
|
|
|
"AT",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r2",
|
|
|
|
"v0",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r3",
|
|
|
|
"v1",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r4",
|
|
|
|
"arg1",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r5",
|
|
|
|
"arg2",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r6",
|
|
|
|
"arg3",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r7",
|
|
|
|
"arg4",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r8",
|
|
|
|
"arg5",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r9",
|
|
|
|
"arg6",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r10",
|
|
|
|
"arg7",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r11",
|
|
|
|
"arg8",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r12",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r13",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r14",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r15",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r16",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r16, dwarf_r16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r17",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r17, dwarf_r17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r18",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r18, dwarf_r18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r19",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r19, dwarf_r19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r20",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r20, dwarf_r20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r21",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r21, dwarf_r21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r22",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r22, dwarf_r22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r23",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r23, dwarf_r23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r24",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r24, dwarf_r24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r25",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r25, dwarf_r25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r26",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r26, dwarf_r26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r27",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r27, dwarf_r27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r28",
|
|
|
|
"gp",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r28, dwarf_r28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r29",
|
|
|
|
"sp",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r29, dwarf_r29, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r30",
|
|
|
|
"fp",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r30, dwarf_r30, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"r31",
|
|
|
|
"ra",
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_r31, dwarf_r31, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"sr",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_sr, dwarf_sr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"lo",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_lo, dwarf_lo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"hi",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_hi, dwarf_hi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"bad",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_bad, dwarf_bad, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"cause",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_cause, dwarf_cause, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
|
|
|
{"pc",
|
|
|
|
nullptr,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
eEncodingUint,
|
|
|
|
eFormatHex,
|
|
|
|
{dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
|
|
|
|
LLDB_INVALID_REGNUM},
|
2016-09-07 04:57:50 +08:00
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
0},
|
2015-06-18 15:02:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t k_num_register_infos =
|
|
|
|
llvm::array_lengthof(g_register_infos);
|
|
|
|
|
|
|
|
const lldb_private::RegisterInfo *
|
|
|
|
ABISysV_mips::GetRegisterInfoArray(uint32_t &count) {
|
|
|
|
count = k_num_register_infos;
|
|
|
|
return g_register_infos;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t ABISysV_mips::GetRedZoneSize() const { return 0; }
|
|
|
|
|
|
|
|
// Static Functions
|
2016-02-27 06:26:21 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
ABISP
|
2017-06-29 10:57:03 +08:00
|
|
|
ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
|
2015-06-18 15:02:10 +08:00
|
|
|
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
|
|
|
|
if ((arch_type == llvm::Triple::mips) ||
|
|
|
|
(arch_type == llvm::Triple::mipsel)) {
|
Have ABI plugins vend llvm MCRegisterInfo data
Summary:
I was recently surprised to learn that there is a total of 2 (two) users
of the register info definitions contained in the ABI plugins. Yet, the
defitions themselves span nearly 10kLOC.
The two users are:
- dwarf expression pretty printer
- the mechanism for augmenting the register info definitions obtained
over gdb-remote protocol (AugmentRegisterInfoViaABI)
Both of these uses need the DWARF an EH register numbers, which is
information that is already available in LLVM. This patch makes it
possible to do so.
It adds a GetMCRegisterInfo method to the ABI class, which every class
is expected to implement. Normally, it should be sufficient to obtain
the definitions from the appropriate llvm::Target object (for which I
provide a utility function), but the subclasses are free to construct it
in any way they deem fit.
We should be able to always get the MCRegisterInfo object from llvm,
with one important exception: if the relevant llvm target was disabled
at compile time. To handle this, I add a mechanism to disable the
compilation of ABI plugins based on the value of LLVM_TARGETS_TO_BUILD
cmake setting. This ensures all our existing are able to create their
MCRegisterInfo objects.
The new MCRegisterInfo api is not used yet, but the intention is to make
use of it in follow-up patches.
Reviewers: jasonmolenda, aprantl, JDevlieghere, tatyana-krasnukha
Subscribers: wuzish, nemanjai, mgorny, kbarton, atanasyan, lldb-commits
Differential Revision: https://reviews.llvm.org/D67965
llvm-svn: 372862
2019-09-25 21:03:04 +08:00
|
|
|
return ABISP(
|
|
|
|
new ABISysV_mips(std::move(process_sp), MakeMCRegisterInfo(arch)));
|
2015-06-18 15:02:10 +08:00
|
|
|
}
|
|
|
|
return ABISP();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ABISysV_mips::PrepareTrivialCall(Thread &thread, addr_t sp,
|
|
|
|
addr_t func_addr, addr_t return_addr,
|
|
|
|
llvm::ArrayRef<addr_t> args) const {
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
if (log) {
|
2015-06-18 15:02:10 +08:00
|
|
|
StreamString s;
|
|
|
|
s.Printf("ABISysV_mips::PrepareTrivialCall (tid = 0x%" PRIx64
|
|
|
|
", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
|
|
|
|
", return_addr = 0x%" PRIx64,
|
2015-12-08 14:05:57 +08:00
|
|
|
thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
|
2016-02-08 12:35:51 +08:00
|
|
|
(uint64_t)return_addr);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
for (size_t i = 0; i < args.size(); ++i)
|
|
|
|
s.Printf(", arg%zd = 0x%" PRIx64, i + 1, args[i]);
|
|
|
|
s.PutCString(")");
|
2016-11-17 05:15:24 +08:00
|
|
|
log->PutString(s.GetString());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
|
|
|
|
if (!reg_ctx)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const RegisterInfo *reg_info = nullptr;
|
|
|
|
|
|
|
|
RegisterValue reg_value;
|
|
|
|
|
2016-02-27 06:26:21 +08:00
|
|
|
// Argument registers
|
|
|
|
const char *reg_names[] = {"r4", "r5", "r6", "r7"};
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
|
|
|
|
|
|
|
|
// Write arguments to registers
|
|
|
|
for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
|
|
|
|
if (ai == ae)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
|
|
|
|
LLDB_REGNUM_GENERIC_ARG1 + i);
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") into %s", i + 1,
|
|
|
|
args[i], reg_info->name);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
++ai;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
// If we have more than 4 arguments --Spill onto the stack
|
|
|
|
if (ai != ae) {
|
|
|
|
// No of arguments to go on stack
|
|
|
|
size_t num_stack_regs = args.size();
|
|
|
|
|
|
|
|
// Allocate needed space for args on the stack
|
|
|
|
sp -= (num_stack_regs * 4);
|
|
|
|
|
|
|
|
// Keep the stack 8 byte aligned
|
|
|
|
sp &= ~(8ull - 1ull);
|
|
|
|
|
|
|
|
// just using arg1 to get the right size
|
|
|
|
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
|
|
|
|
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
|
|
|
|
|
|
|
|
addr_t arg_pos = sp + 16;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
size_t i = 4;
|
|
|
|
for (; ai != ae; ++ai) {
|
|
|
|
reg_value.SetUInt32(*ai);
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "About to write arg%zd (0x%" PRIx64 ") at 0x%" PRIx64 "",
|
|
|
|
i + 1, args[i], arg_pos);
|
2016-02-08 12:35:51 +08:00
|
|
|
|
|
|
|
if (reg_ctx
|
|
|
|
->WriteRegisterValueToMemory(reg_info, arg_pos,
|
|
|
|
reg_info->byte_size, reg_value)
|
|
|
|
.Fail())
|
|
|
|
return false;
|
2015-06-18 15:02:10 +08:00
|
|
|
arg_pos += reg_info->byte_size;
|
2016-09-07 04:57:50 +08:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-12 12:51:55 +08:00
|
|
|
Status error;
|
2015-06-18 15:02:10 +08:00
|
|
|
const RegisterInfo *pc_reg_info =
|
|
|
|
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
|
|
|
|
const RegisterInfo *sp_reg_info =
|
|
|
|
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
|
2016-05-24 22:52:50 +08:00
|
|
|
const RegisterInfo *ra_reg_info =
|
2015-06-18 15:02:10 +08:00
|
|
|
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
|
2015-12-08 14:05:57 +08:00
|
|
|
const RegisterInfo *r25_info = reg_ctx->GetRegisterInfoByName("r25", 0);
|
2016-02-08 12:35:51 +08:00
|
|
|
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("zero", 0);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "Writing R0: 0x%" PRIx64, (uint64_t)0);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-02-08 12:35:51 +08:00
|
|
|
/* Write r0 with 0, in case we are stopped in syscall,
|
|
|
|
* such setting prevents automatic decrement of the PC.
|
|
|
|
* This clears the bug 23659 for MIPS.
|
2016-09-07 04:57:50 +08:00
|
|
|
*/
|
2015-12-08 14:05:57 +08:00
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(r0_info, (uint64_t)0))
|
2015-06-18 15:02:10 +08:00
|
|
|
return false;
|
2016-02-08 12:35:51 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "Writing SP: 0x%" PRIx64, (uint64_t)sp);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
// Set "sp" to the requested value
|
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
|
|
|
|
return false;
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "Writing RA: 0x%" PRIx64, (uint64_t)return_addr);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
// Set "ra" to the return address
|
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_info, return_addr))
|
|
|
|
return false;
|
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "Writing PC: 0x%" PRIx64, (uint64_t)func_addr);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
// Set pc to the address of the called function.
|
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-07-25 01:56:10 +08:00
|
|
|
LLDB_LOGF(log, "Writing r25: 0x%" PRIx64, (uint64_t)func_addr);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// All callers of position independent functions must place the address of
|
|
|
|
// the called function in t9 (r25)
|
2015-06-18 15:02:10 +08:00
|
|
|
if (!reg_ctx->WriteRegisterFromUnsigned(r25_info, func_addr))
|
|
|
|
return false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-12-08 14:05:57 +08:00
|
|
|
return true;
|
2015-06-18 15:02:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ABISysV_mips::GetArgumentValues(Thread &thread, ValueList &values) const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-05-12 12:51:55 +08:00
|
|
|
Status ABISysV_mips::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
|
|
|
|
lldb::ValueObjectSP &new_value_sp) {
|
|
|
|
Status error;
|
2015-09-24 11:54:50 +08:00
|
|
|
if (!new_value_sp) {
|
2015-06-18 15:02:10 +08:00
|
|
|
error.SetErrorString("Empty value object for return value.");
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2015-09-24 11:54:50 +08:00
|
|
|
CompilerType compiler_type = new_value_sp->GetCompilerType();
|
|
|
|
if (!compiler_type) {
|
2015-06-18 15:02:10 +08:00
|
|
|
error.SetErrorString("Null clang type for return value.");
|
|
|
|
return error;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
Thread *thread = frame_sp->GetThread().get();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
bool is_signed;
|
|
|
|
uint32_t count;
|
|
|
|
bool is_complex;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
RegisterContext *reg_ctx = thread->GetRegisterContext().get();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
bool set_it_simple = false;
|
2016-06-25 07:48:00 +08:00
|
|
|
if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
|
|
|
|
compiler_type.IsPointerType()) {
|
2015-06-18 15:02:10 +08:00
|
|
|
DataExtractor data;
|
2017-05-12 12:51:55 +08:00
|
|
|
Status data_error;
|
2015-06-18 15:02:10 +08:00
|
|
|
size_t num_bytes = new_value_sp->GetData(data, data_error);
|
|
|
|
if (data_error.Fail()) {
|
|
|
|
error.SetErrorStringWithFormat(
|
|
|
|
"Couldn't convert return value to raw data: %s",
|
|
|
|
data_error.AsCString());
|
|
|
|
return error;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
lldb::offset_t offset = 0;
|
|
|
|
if (num_bytes <= 8) {
|
|
|
|
const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
|
|
|
|
if (num_bytes <= 4) {
|
|
|
|
uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
|
|
|
|
|
|
|
|
if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value))
|
|
|
|
set_it_simple = true;
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2015-06-18 15:02:10 +08:00
|
|
|
uint32_t raw_value = data.GetMaxU32(&offset, 4);
|
|
|
|
|
2016-06-25 07:48:00 +08:00
|
|
|
if (reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
|
|
|
|
const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
|
2015-06-18 15:02:10 +08:00
|
|
|
uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
|
|
|
|
|
|
|
|
if (reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value))
|
|
|
|
set_it_simple = true;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
} else {
|
|
|
|
error.SetErrorString("We don't support returning longer than 64 bit "
|
|
|
|
"integer values at present.");
|
|
|
|
}
|
2015-09-24 11:54:50 +08:00
|
|
|
} else if (compiler_type.IsFloatingPointType(count, is_complex)) {
|
2015-06-18 15:02:10 +08:00
|
|
|
if (is_complex)
|
|
|
|
error.SetErrorString(
|
|
|
|
"We don't support returning complex values at present");
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2015-06-18 15:02:10 +08:00
|
|
|
error.SetErrorString(
|
|
|
|
"We don't support returning float values at present");
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
if (!set_it_simple)
|
|
|
|
error.SetErrorString(
|
|
|
|
"We only support setting simple integer return types at present.");
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2015-09-24 11:54:50 +08:00
|
|
|
ValueObjectSP ABISysV_mips::GetReturnValueObjectSimple(
|
|
|
|
Thread &thread, CompilerType &return_compiler_type) const {
|
2015-06-18 15:02:10 +08:00
|
|
|
ValueObjectSP return_valobj_sp;
|
|
|
|
return return_valobj_sp;
|
|
|
|
}
|
|
|
|
|
2015-09-24 11:54:50 +08:00
|
|
|
ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
|
|
|
|
Thread &thread, CompilerType &return_compiler_type) const {
|
2015-06-18 15:02:10 +08:00
|
|
|
ValueObjectSP return_valobj_sp;
|
|
|
|
Value value;
|
|
|
|
|
2015-09-24 11:54:50 +08:00
|
|
|
if (!return_compiler_type)
|
2015-06-18 15:02:10 +08:00
|
|
|
return return_valobj_sp;
|
|
|
|
|
|
|
|
ExecutionContext exe_ctx(thread.shared_from_this());
|
2016-02-27 06:26:21 +08:00
|
|
|
if (exe_ctx.GetTargetPtr() == nullptr || exe_ctx.GetProcessPtr() == nullptr)
|
2015-06-18 15:02:10 +08:00
|
|
|
return return_valobj_sp;
|
|
|
|
|
2016-05-24 22:52:50 +08:00
|
|
|
Target *target = exe_ctx.GetTargetPtr();
|
|
|
|
const ArchSpec target_arch = target->GetArchitecture();
|
|
|
|
ByteOrder target_byte_order = target_arch.GetByteOrder();
|
2015-09-24 11:54:50 +08:00
|
|
|
value.SetCompilerType(return_compiler_type);
|
2016-05-24 22:52:50 +08:00
|
|
|
uint32_t fp_flag =
|
|
|
|
target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
|
|
|
|
if (!reg_ctx)
|
|
|
|
return return_valobj_sp;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-08-14 11:40:31 +08:00
|
|
|
bool is_signed = false;
|
|
|
|
bool is_complex = false;
|
|
|
|
uint32_t count = 0;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
// In MIPS register "r2" (v0) holds the integer function return values
|
|
|
|
const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
|
2019-01-16 04:33:58 +08:00
|
|
|
llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
|
2019-01-16 02:07:52 +08:00
|
|
|
if (!bit_width)
|
|
|
|
return return_valobj_sp;
|
2016-06-25 07:48:00 +08:00
|
|
|
if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
|
2019-01-16 02:07:52 +08:00
|
|
|
switch (*bit_width) {
|
2015-06-18 15:02:10 +08:00
|
|
|
default:
|
|
|
|
return return_valobj_sp;
|
|
|
|
case 64: {
|
|
|
|
const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);
|
|
|
|
uint64_t raw_value;
|
|
|
|
raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX;
|
|
|
|
raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0) &
|
|
|
|
UINT32_MAX))
|
|
|
|
<< 32;
|
|
|
|
if (is_signed)
|
|
|
|
value.GetScalar() = (int64_t)raw_value;
|
|
|
|
else
|
|
|
|
value.GetScalar() = (uint64_t)raw_value;
|
|
|
|
} break;
|
|
|
|
case 32:
|
|
|
|
if (is_signed)
|
|
|
|
value.GetScalar() = (int32_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
|
|
|
|
else
|
|
|
|
value.GetScalar() = (uint32_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT32_MAX);
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if (is_signed)
|
|
|
|
value.GetScalar() = (int16_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2015-06-18 15:02:10 +08:00
|
|
|
value.GetScalar() = (uint16_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT16_MAX);
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
case 8:
|
2015-06-18 15:02:10 +08:00
|
|
|
if (is_signed)
|
|
|
|
value.GetScalar() = (int8_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2015-06-18 15:02:10 +08:00
|
|
|
value.GetScalar() = (uint8_t)(
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0) & UINT8_MAX);
|
|
|
|
break;
|
|
|
|
}
|
2015-09-24 11:54:50 +08:00
|
|
|
} else if (return_compiler_type.IsPointerType()) {
|
2015-06-18 15:02:10 +08:00
|
|
|
uint32_t ptr =
|
|
|
|
thread.GetRegisterContext()->ReadRegisterAsUnsigned(r2_reg_info, 0) &
|
|
|
|
UINT32_MAX;
|
|
|
|
value.GetScalar() = ptr;
|
2015-09-24 11:54:50 +08:00
|
|
|
} else if (return_compiler_type.IsAggregateType()) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Structure/Vector is always passed in memory and pointer to that memory
|
|
|
|
// is passed in r2.
|
2015-08-14 11:40:31 +08:00
|
|
|
uint64_t mem_address = reg_ctx->ReadRegisterAsUnsigned(
|
|
|
|
reg_ctx->GetRegisterInfoByName("r2", 0), 0);
|
|
|
|
// We have got the address. Create a memory object out of it
|
2016-02-27 06:26:21 +08:00
|
|
|
return_valobj_sp = ValueObjectMemory::Create(
|
|
|
|
&thread, "", Address(mem_address, nullptr), return_compiler_type);
|
|
|
|
return return_valobj_sp;
|
|
|
|
} else if (return_compiler_type.IsFloatingPointType(count, is_complex)) {
|
2016-05-24 22:52:50 +08:00
|
|
|
if (IsSoftFloat(fp_flag)) {
|
2016-02-27 06:26:21 +08:00
|
|
|
uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
|
2016-05-24 22:52:50 +08:00
|
|
|
if (count != 1 && is_complex)
|
2015-08-14 11:40:31 +08:00
|
|
|
return return_valobj_sp;
|
2019-01-16 02:07:52 +08:00
|
|
|
switch (*bit_width) {
|
2016-09-07 04:57:50 +08:00
|
|
|
default:
|
2015-06-18 15:02:10 +08:00
|
|
|
return return_valobj_sp;
|
2016-09-07 04:57:50 +08:00
|
|
|
case 32:
|
2016-05-24 22:52:50 +08:00
|
|
|
static_assert(sizeof(float) == sizeof(uint32_t), "");
|
|
|
|
value.GetScalar() = *((float *)(&raw_value));
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
case 64:
|
2016-05-24 22:52:50 +08:00
|
|
|
static_assert(sizeof(double) == sizeof(uint64_t), "");
|
|
|
|
const RegisterInfo *r3_reg_info =
|
|
|
|
reg_ctx->GetRegisterInfoByName("r3", 0);
|
|
|
|
if (target_byte_order == eByteOrderLittle)
|
|
|
|
raw_value =
|
|
|
|
((reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0)) << 32) |
|
|
|
|
raw_value;
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2016-05-24 22:52:50 +08:00
|
|
|
raw_value = (raw_value << 32) |
|
|
|
|
reg_ctx->ReadRegisterAsUnsigned(r3_reg_info, 0);
|
|
|
|
value.GetScalar() = *((double *)(&raw_value));
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
}
|
2015-08-14 11:40:31 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-09-24 11:54:50 +08:00
|
|
|
else {
|
2016-05-24 22:52:50 +08:00
|
|
|
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
|
|
|
|
RegisterValue f0_value;
|
|
|
|
DataExtractor f0_data;
|
|
|
|
reg_ctx->ReadRegister(f0_info, f0_value);
|
|
|
|
f0_value.GetData(f0_data);
|
|
|
|
lldb::offset_t offset = 0;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-05-24 22:52:50 +08:00
|
|
|
if (count == 1 && !is_complex) {
|
2019-01-16 02:07:52 +08:00
|
|
|
switch (*bit_width) {
|
2015-08-14 11:40:31 +08:00
|
|
|
default:
|
|
|
|
return return_valobj_sp;
|
2016-05-24 22:52:50 +08:00
|
|
|
case 64: {
|
|
|
|
static_assert(sizeof(double) == sizeof(uint64_t), "");
|
|
|
|
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
|
|
|
|
RegisterValue f1_value;
|
|
|
|
DataExtractor f1_data;
|
|
|
|
reg_ctx->ReadRegister(f1_info, f1_value);
|
|
|
|
DataExtractor *copy_from_extractor = nullptr;
|
|
|
|
DataBufferSP data_sp(new DataBufferHeap(8, 0));
|
|
|
|
DataExtractor return_ext(
|
|
|
|
data_sp, target_byte_order,
|
|
|
|
target->GetArchitecture().GetAddressByteSize());
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2016-05-24 22:52:50 +08:00
|
|
|
if (target_byte_order == eByteOrderLittle) {
|
|
|
|
copy_from_extractor = &f0_data;
|
|
|
|
copy_from_extractor->CopyByteOrderedData(
|
|
|
|
offset, 4, data_sp->GetBytes(), 4, target_byte_order);
|
|
|
|
f1_value.GetData(f1_data);
|
|
|
|
copy_from_extractor = &f1_data;
|
|
|
|
copy_from_extractor->CopyByteOrderedData(
|
|
|
|
offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
|
|
|
|
} else {
|
|
|
|
copy_from_extractor = &f0_data;
|
|
|
|
copy_from_extractor->CopyByteOrderedData(
|
|
|
|
offset, 4, data_sp->GetBytes() + 4, 4, target_byte_order);
|
|
|
|
f1_value.GetData(f1_data);
|
|
|
|
copy_from_extractor = &f1_data;
|
|
|
|
copy_from_extractor->CopyByteOrderedData(
|
|
|
|
offset, 4, data_sp->GetBytes(), 4, target_byte_order);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2016-05-24 22:52:50 +08:00
|
|
|
value.GetScalar() = (double)return_ext.GetDouble(&offset);
|
2016-05-20 21:07:16 +08:00
|
|
|
break;
|
2015-08-14 11:40:31 +08:00
|
|
|
}
|
2016-05-24 22:52:50 +08:00
|
|
|
case 32: {
|
|
|
|
static_assert(sizeof(float) == sizeof(uint32_t), "");
|
|
|
|
value.GetScalar() = (float)f0_data.GetFloat(&offset);
|
|
|
|
break;
|
2015-08-14 11:40:31 +08:00
|
|
|
}
|
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
} else {
|
|
|
|
// not handled yet
|
|
|
|
return return_valobj_sp;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// not handled yet
|
|
|
|
return return_valobj_sp;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
// If we get here, we have a valid Value, so make our ValueObject out of it:
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
return_valobj_sp = ValueObjectConstResult::Create(
|
|
|
|
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
|
|
|
|
return return_valobj_sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ABISysV_mips::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
|
|
|
|
unwind_plan.Clear();
|
|
|
|
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
|
|
|
|
|
|
|
|
UnwindPlan::RowSP row(new UnwindPlan::Row);
|
|
|
|
|
|
|
|
// Our Call Frame Address is the stack pointer value
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
|
|
|
// The previous PC is in the RA
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
|
2015-06-18 15:02:10 +08:00
|
|
|
unwind_plan.AppendRow(row);
|
|
|
|
|
|
|
|
// All other registers are the same.
|
|
|
|
|
|
|
|
unwind_plan.SetSourceName("mips at-func-entry default");
|
|
|
|
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
unwind_plan.SetReturnAddressRegister(dwarf_r31);
|
2015-06-18 15:02:10 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ABISysV_mips::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
|
|
|
|
unwind_plan.Clear();
|
|
|
|
unwind_plan.SetRegisterKind(eRegisterKindDWARF);
|
|
|
|
|
|
|
|
UnwindPlan::RowSP row(new UnwindPlan::Row);
|
|
|
|
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_r29, 0);
|
2015-06-18 15:02:10 +08:00
|
|
|
|
Clean up register naming conventions inside lldb.
"gcc" register numbers are now correctly referred to as "ehframe"
register numbers. In almost all cases, ehframe and dwarf register
numbers are identical (the one exception is i386 darwin where ehframe
regnums were incorrect).
The old "gdb" register numbers, which I incorrectly thought were
stabs register numbers, are now referred to as "Process Plugin"
register numbers. This is the register numbering scheme that the
remote process controller stub (lldb-server, gdbserver, core file
support, kdp server, remote jtag devices, etc) uses to refer to the
registers. The process plugin register numbers may not be contiguous
- there are remote jtag devices that have gaps in their register
numbering schemes.
I removed all of the enums for "gdb" register numbers that we had
in lldb - these were meaningless - and I put LLDB_INVALID_REGNUM
in all of the register tables for the Process Plugin regnum slot.
This change is almost entirely mechnical; the one actual change in
here is to ProcessGDBRemote.cpp's ParseRegisters() which parses the
qXfer:features:read:target.xml response. As it parses register
definitions from the xml, it will assign sequential numbers as the
eRegisterKindLLDB numbers (the lldb register numberings must be
sequential, without any gaps) and if the xml file specifies register
numbers, those will be used as the eRegisterKindProcessPlugin
register numbers (and those may have gaps). A J-Link jtag device's
target.xml does contain a gap in register numbers, and it only
specifies the register numbers for the registers after that gap.
The device supports many different ARM boards and probably selects
different part of its register file as appropriate.
http://reviews.llvm.org/D12791
<rdar://problem/22623262>
llvm-svn: 247741
2015-09-16 07:20:34 +08:00
|
|
|
row->SetRegisterLocationToRegister(dwarf_pc, dwarf_r31, true);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
unwind_plan.AppendRow(row);
|
|
|
|
unwind_plan.SetSourceName("mips default unwind plan");
|
|
|
|
unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
|
|
|
|
unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
|
Support Linux signal return trampolines in frame initialization
Summary:
Add __kernel_rt_sigreturn to the list of trap handlers for Linux (it's
used as such on aarch64 at least), and __restore_rt as well (used on
x86_64).
Skip decrement-and-recompute for trap handlers in
InitializeNonZerothFrame, as signal dispatch may point the child frame's
return address to the start of the return trampoline.
Parse the 'S' flag for signal handlers from eh_frame augmentation, and
propagate it to the unwind plan.
Reviewers: labath, jankratochvil, compnerd, jfb, jasonmolenda
Reviewed By: jasonmolenda
Subscribers: clayborg, MaskRay, wuzish, nemanjai, kbarton, jrtc27, atanasyan, jsji, javed.absar, kristof.beyls, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D63667
llvm-svn: 366580
2019-07-19 22:05:55 +08:00
|
|
|
unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
|
2015-06-18 15:02:10 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ABISysV_mips::RegisterIsVolatile(const RegisterInfo *reg_info) {
|
|
|
|
return !RegisterIsCalleeSaved(reg_info);
|
|
|
|
}
|
|
|
|
|
2016-05-24 22:52:50 +08:00
|
|
|
bool ABISysV_mips::IsSoftFloat(uint32_t fp_flags) const {
|
|
|
|
return (fp_flags == lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT);
|
|
|
|
}
|
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
bool ABISysV_mips::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
|
|
|
|
if (reg_info) {
|
|
|
|
// Preserved registers are :
|
|
|
|
// r16-r23, r28, r29, r30, r31
|
2015-12-08 14:05:57 +08:00
|
|
|
const char *name = reg_info->name;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-12-08 14:05:57 +08:00
|
|
|
if (name[0] == 'r') {
|
|
|
|
switch (name[1]) {
|
|
|
|
case '1':
|
|
|
|
if (name[2] == '6' || name[2] == '7' || name[2] == '8' ||
|
|
|
|
name[2] == '9') // r16-r19
|
|
|
|
return name[3] == '\0';
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
if (name[2] == '0' || name[2] == '1' || name[2] == '2' ||
|
|
|
|
name[2] == '3' // r20-r23
|
|
|
|
|| name[2] == '8' || name[2] == '9') // r28 and r29
|
|
|
|
return name[3] == '\0';
|
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
if (name[2] == '0' || name[2] == '1') // r30 and r31
|
|
|
|
return name[3] == '\0';
|
|
|
|
break;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-12-08 14:05:57 +08:00
|
|
|
if (name[0] == 'g' && name[1] == 'p' && name[2] == '\0') // gp (r28)
|
|
|
|
return true;
|
|
|
|
if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp (r29)
|
|
|
|
return true;
|
|
|
|
if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp (r30)
|
|
|
|
return true;
|
|
|
|
if (name[0] == 'r' && name[1] == 'a' && name[2] == '\0') // ra (r31)
|
|
|
|
return true;
|
2015-06-18 15:02:10 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-06-18 15:02:10 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ABISysV_mips::Initialize() {
|
|
|
|
PluginManager::RegisterPlugin(
|
|
|
|
GetPluginNameStatic(), "System V ABI for mips targets", CreateInstance);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ABISysV_mips::Terminate() {
|
|
|
|
PluginManager::UnregisterPlugin(CreateInstance);
|
|
|
|
}
|
|
|
|
|
|
|
|
lldb_private::ConstString ABISysV_mips::GetPluginNameStatic() {
|
|
|
|
static ConstString g_name("sysv-mips");
|
|
|
|
return g_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PluginInterface protocol
|
2016-02-27 06:26:21 +08:00
|
|
|
|
2015-06-18 15:02:10 +08:00
|
|
|
lldb_private::ConstString ABISysV_mips::GetPluginName() {
|
|
|
|
return GetPluginNameStatic();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t ABISysV_mips::GetPluginVersion() { return 1; }
|