2011-08-22 02:49:39 +00:00
|
|
|
//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "DynamicRegisterInfo.h"
|
|
|
|
|
|
|
|
// C Includes
|
|
|
|
// C++ Includes
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
2015-05-26 18:00:51 +00:00
|
|
|
#include "lldb/Core/ArchSpec.h"
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
#include "lldb/Core/RegularExpression.h"
|
|
|
|
#include "lldb/Core/StreamFile.h"
|
2015-03-17 20:04:04 +00:00
|
|
|
#include "lldb/Core/StructuredData.h"
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
#include "lldb/DataFormatters/FormatManager.h"
|
2015-05-26 18:00:51 +00:00
|
|
|
#include "lldb/Host/StringConvert.h"
|
2012-09-11 06:35:15 +00:00
|
|
|
|
2011-08-22 02:49:39 +00:00
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
DynamicRegisterInfo::DynamicRegisterInfo () :
|
|
|
|
m_regs (),
|
|
|
|
m_sets (),
|
|
|
|
m_set_reg_nums (),
|
|
|
|
m_set_names (),
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
m_value_regs_map (),
|
|
|
|
m_invalidate_regs_map (),
|
|
|
|
m_reg_data_byte_size (0),
|
|
|
|
m_finalized (false)
|
2011-08-22 02:49:39 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-05-26 18:00:51 +00:00
|
|
|
DynamicRegisterInfo::DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
|
|
|
|
const lldb_private::ArchSpec &arch) :
|
|
|
|
m_regs (),
|
|
|
|
m_sets (),
|
|
|
|
m_set_reg_nums (),
|
|
|
|
m_set_names (),
|
|
|
|
m_value_regs_map (),
|
|
|
|
m_invalidate_regs_map (),
|
|
|
|
m_reg_data_byte_size (0),
|
|
|
|
m_finalized (false)
|
2012-08-24 01:42:50 +00:00
|
|
|
{
|
2015-05-26 18:00:51 +00:00
|
|
|
SetRegisterInfo (dict, arch);
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
|
|
|
|
2011-08-22 02:49:39 +00:00
|
|
|
DynamicRegisterInfo::~DynamicRegisterInfo ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-08-24 01:42:50 +00:00
|
|
|
size_t
|
2015-05-26 18:00:51 +00:00
|
|
|
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
|
2012-08-24 01:42:50 +00:00
|
|
|
{
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
assert(!m_finalized);
|
2015-03-17 20:04:04 +00:00
|
|
|
StructuredData::Array *sets = nullptr;
|
|
|
|
if (dict.GetValueForKeyAsArray("sets", sets))
|
2012-08-24 01:42:50 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
const uint32_t num_sets = sets->GetSize();
|
2012-08-24 01:42:50 +00:00
|
|
|
for (uint32_t i=0; i<num_sets; ++i)
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
std::string set_name_str;
|
<rdar://problem/13010007>
Added the ability for OS plug-ins to lazily populate the thread this. The python OS plug-in classes can now implement the following method:
class OperatingSystemPlugin:
def create_thread(self, tid, context):
# Return a dictionary for a new thread to create it on demand
This will add a new thread to the thread list if it doesn't already exist. The example code in lldb/examples/python/operating_system.py has been updated to show how this call us used.
Cleaned up the code in PythonDataObjects.cpp/h:
- renamed all classes that started with PythonData* to be Python*.
- renamed PythonArray to PythonList. Cleaned up the code to use inheritance where
- Centralized the code that does ref counting in the PythonObject class to a single function.
- Made the "bool PythonObject::Reset(PyObject *)" function be virtual so each subclass can correctly check to ensure a PyObject is of the right type before adopting the object.
- Cleaned up all APIs and added new constructors for the Python* classes to they can all construct form:
- PyObject *
- const PythonObject &
- const lldb::ScriptInterpreterObjectSP &
Cleaned up code in ScriptInterpreterPython:
- Made calling python functions safer by templatizing the production of value formats. Python specifies the value formats based on built in C types (long, long long, etc), and code often uses typedefs for uint32_t, uint64_t, etc when passing arguments down to python. We will now always produce correct value formats as the templatized code will "do the right thing" all the time.
- Fixed issues with the ScriptInterpreterPython::Locker where entering the session and leaving the session had a bunch of issues that could cause the "lldb" module globals lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame to not be initialized.
llvm-svn: 172873
2013-01-18 23:41:08 +00:00
|
|
|
ConstString set_name;
|
2015-03-17 20:04:04 +00:00
|
|
|
if (sets->GetItemAtIndexAsString(i, set_name_str))
|
|
|
|
set_name.SetCString(set_name_str.c_str());
|
2012-08-24 01:42:50 +00:00
|
|
|
if (set_name)
|
|
|
|
{
|
|
|
|
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
|
|
|
|
m_sets.push_back (new_set);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Clear();
|
2014-12-11 23:52:05 +00:00
|
|
|
printf("error: register sets must have valid names\n");
|
2012-08-24 01:42:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_set_reg_nums.resize(m_sets.size());
|
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
StructuredData::Array *regs = nullptr;
|
|
|
|
if (!dict.GetValueForKeyAsArray("registers", regs))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const uint32_t num_regs = regs->GetSize();
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
|
|
|
|
// InvalidateNameMap invalidate_map;
|
2015-03-17 20:04:04 +00:00
|
|
|
for (uint32_t i = 0; i < num_regs; ++i)
|
|
|
|
{
|
|
|
|
StructuredData::Dictionary *reg_info_dict = nullptr;
|
|
|
|
if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict))
|
2012-08-24 01:42:50 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
Clear();
|
|
|
|
printf("error: items in the 'registers' array must be dictionaries\n");
|
|
|
|
regs->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
2012-08-24 01:42:50 +00: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-15 23:20:34 +00:00
|
|
|
// { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'ehframe' : 2,
|
2015-03-17 20:04:04 +00:00
|
|
|
// 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
|
|
|
|
RegisterInfo reg_info;
|
|
|
|
std::vector<uint32_t> value_regs;
|
|
|
|
std::vector<uint32_t> invalidate_regs;
|
|
|
|
memset(®_info, 0, sizeof(reg_info));
|
|
|
|
|
|
|
|
ConstString name_val;
|
|
|
|
ConstString alt_name_val;
|
|
|
|
if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr))
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
printf("error: registers must have valid names and offsets\n");
|
|
|
|
reg_info_dict->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
reg_info.name = name_val.GetCString();
|
|
|
|
reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr);
|
|
|
|
reg_info.alt_name = alt_name_val.GetCString();
|
|
|
|
|
|
|
|
reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX);
|
|
|
|
|
2015-05-26 18:00:51 +00:00
|
|
|
const ByteOrder byte_order = arch.GetByteOrder();
|
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
if (reg_info.byte_offset == UINT32_MAX)
|
|
|
|
{
|
|
|
|
// No offset for this register, see if the register has a value expression
|
|
|
|
// which indicates this register is part of another register. Value expressions
|
|
|
|
// are things like "rax[31:0]" which state that the current register's value
|
|
|
|
// is in a concrete register "rax" in bits 31:0. If there is a value expression
|
|
|
|
// we can calculate the offset
|
|
|
|
bool success = false;
|
|
|
|
std::string slice_str;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr))
|
|
|
|
{
|
|
|
|
// Slices use the following format:
|
|
|
|
// REGNAME[MSBIT:LSBIT]
|
|
|
|
// REGNAME - name of the register to grab a slice of
|
|
|
|
// MSBIT - the most significant bit at which the current register value starts at
|
|
|
|
// LSBIT - the least significant bit at which the current register value ends at
|
|
|
|
static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]");
|
|
|
|
RegularExpression::Match regex_match(3);
|
|
|
|
if (g_bitfield_regex.Execute(slice_str.c_str(), ®ex_match))
|
2012-08-24 01:42:50 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
llvm::StringRef reg_name_str;
|
|
|
|
std::string msbit_str;
|
|
|
|
std::string lsbit_str;
|
|
|
|
if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) &&
|
|
|
|
regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) &&
|
|
|
|
regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str))
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX);
|
|
|
|
const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX);
|
|
|
|
if (msbit != UINT32_MAX && lsbit != UINT32_MAX)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
if (msbit > lsbit)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
const uint32_t msbyte = msbit / 8;
|
|
|
|
const uint32_t lsbyte = lsbit / 8;
|
|
|
|
|
|
|
|
ConstString containing_reg_name(reg_name_str);
|
|
|
|
|
|
|
|
RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name);
|
|
|
|
if (containing_reg_info)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
const uint32_t max_bit = containing_reg_info->byte_size * 8;
|
|
|
|
if (msbit < max_bit && lsbit < max_bit)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
|
|
|
|
m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
|
|
|
|
m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
if (byte_order == eByteOrderLittle)
|
|
|
|
{
|
|
|
|
success = true;
|
|
|
|
reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
|
|
|
|
}
|
|
|
|
else if (byte_order == eByteOrderBig)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
success = true;
|
|
|
|
reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
assert(!"Invalid byte order");
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
if (msbit > max_bit)
|
|
|
|
printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit,
|
|
|
|
max_bit);
|
|
|
|
else
|
|
|
|
printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit,
|
|
|
|
max_bit);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
// TODO: print error invalid slice string that doesn't follow the format
|
|
|
|
printf("error: failed to extract regex matches for parsing the register bitfield regex\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// TODO: print error invalid slice string that doesn't follow the format
|
|
|
|
printf("error: failed to match against register bitfield regex\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
StructuredData::Array *composite_reg_list = nullptr;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list))
|
|
|
|
{
|
|
|
|
const size_t num_composite_regs = composite_reg_list->GetSize();
|
|
|
|
if (num_composite_regs > 0)
|
|
|
|
{
|
|
|
|
uint32_t composite_offset = UINT32_MAX;
|
|
|
|
for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
ConstString composite_reg_name;
|
|
|
|
if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr))
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name);
|
|
|
|
if (composite_reg_info)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
composite_offset = std::min(composite_offset, composite_reg_info->byte_offset);
|
|
|
|
m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
|
|
|
|
m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i);
|
|
|
|
m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
// TODO: print error invalid slice string that doesn't follow the format
|
|
|
|
printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString());
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: 'composite' list value wasn't a python string\n");
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
if (composite_offset != UINT32_MAX)
|
|
|
|
{
|
|
|
|
reg_info.byte_offset = composite_offset;
|
|
|
|
success = m_value_regs_map.find(i) != m_value_regs_map.end();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf("error: 'composite' registers must specify at least one real register\n");
|
|
|
|
}
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
else
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: 'composite' list was empty\n");
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
}
|
<rdar://problem/14972424>
When debugging with the GDB remote in LLDB, LLDB uses special packets to discover the
registers on the remote server. When those packets aren't supported, LLDB doesn't
know what the registers look like. This checkin implements a setting that can be used
to specify a python file that contains the registers definitions. The setting is:
(lldb) settings set plugin.process.gdb-remote.target-definition-file /path/to/module.py
Inside module there should be a function:
def get_dynamic_setting(target, setting_name):
This dynamic setting function is handed the "target" which is a SBTarget, and the
"setting_name", which is the name of the dynamic setting to retrieve. For the GDB
remote target definition the setting name is 'gdb-server-target-definition'. The
return value is a dictionary that follows the same format as the OperatingSystem
plugins follow. I have checked in an example file that implements the x86_64 GDB
register set for people to see:
examples/python/x86_64_target_definition.py
This allows LLDB to debug to any archticture that is support and allows users to
define the registers contexts when the discovery packets (qRegisterInfo, qHostInfo)
are not supported by the remote GDB server.
A few benefits of doing this in Python:
1 - The dynamic register context was already supported in the OperatingSystem plug-in
2 - Register contexts can use all of the LLDB enumerations and definitions for things
like lldb::Format, lldb::Encoding, generic register numbers, invalid registers
numbers, etc.
3 - The code that generates the register context can use the program to calculate the
register context contents (like offsets, register numbers, and more)
4 - True dynamic detection could be used where variables and types could be read from
the target program itself in order to determine which registers are available since
the target is passed into the python function.
This is designed to be used instead of XML since it is more dynamic and code flow and
functions can be used to make the dictionary.
llvm-svn: 192646
2013-10-15 00:14:28 +00:00
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
reg_info_dict->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2012-08-24 01:42:50 +00:00
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
int64_t bitsize = 0;
|
|
|
|
if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize))
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n");
|
|
|
|
reg_info_dict->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
2012-08-24 01:42:50 +00:00
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
reg_info.byte_size = bitsize / 8;
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
|
2015-03-17 20:04:04 +00:00
|
|
|
std::string format_str;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr))
|
|
|
|
{
|
|
|
|
if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail())
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
printf("error: invalid 'format' value in register dictionary\n");
|
|
|
|
reg_info_dict->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string encoding_str;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str))
|
|
|
|
reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint);
|
|
|
|
else
|
|
|
|
reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint);
|
|
|
|
|
|
|
|
size_t set = 0;
|
|
|
|
if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || set >= m_sets.size())
|
|
|
|
{
|
|
|
|
Clear();
|
|
|
|
printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set);
|
|
|
|
reg_info_dict->DumpToStdout();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill in the register numbers
|
|
|
|
reg_info.kinds[lldb::eRegisterKindLLDB] = i;
|
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-15 23:20:34 +00:00
|
|
|
reg_info.kinds[lldb::eRegisterKindProcessPlugin] = i;
|
2015-08-15 02:59:42 +00:00
|
|
|
uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
|
|
|
|
reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, LLDB_INVALID_REGNUM);
|
2015-08-18 00:21:24 +00:00
|
|
|
if (eh_frame_regno == LLDB_INVALID_REGNUM)
|
2015-08-15 02:59:42 +00:00
|
|
|
reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, LLDB_INVALID_REGNUM);
|
|
|
|
reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
|
2015-03-17 20:04:04 +00:00
|
|
|
reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
|
|
|
|
std::string generic_str;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsString("generic", generic_str))
|
|
|
|
reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str());
|
|
|
|
else
|
|
|
|
reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM);
|
|
|
|
|
|
|
|
// Check if this register invalidates any other register values when it is modified
|
|
|
|
StructuredData::Array *invalidate_reg_list = nullptr;
|
|
|
|
if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list))
|
|
|
|
{
|
|
|
|
const size_t num_regs = invalidate_reg_list->GetSize();
|
|
|
|
if (num_regs > 0)
|
|
|
|
{
|
|
|
|
for (uint32_t idx = 0; idx < num_regs; ++idx)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
ConstString invalidate_reg_name;
|
|
|
|
uint64_t invalidate_reg_num;
|
|
|
|
if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
|
|
|
|
if (invalidate_reg_info)
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// TODO: print error invalid slice string that doesn't follow the format
|
|
|
|
printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n",
|
|
|
|
invalidate_reg_name.GetCString(), reg_info.name);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num))
|
|
|
|
{
|
|
|
|
if (invalidate_reg_num != UINT64_MAX)
|
|
|
|
m_invalidate_regs_map[i].push_back(invalidate_reg_num);
|
|
|
|
else
|
|
|
|
printf("error: 'invalidate-regs' list value wasn't a valid integer\n");
|
|
|
|
}
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-03-17 20:04:04 +00:00
|
|
|
printf("error: 'invalidate-regs' contained an empty list\n");
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
|
|
|
}
|
2015-03-17 20:04:04 +00:00
|
|
|
|
|
|
|
// Calculate the register offset
|
|
|
|
const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
|
|
|
|
if (m_reg_data_byte_size < end_reg_offset)
|
|
|
|
m_reg_data_byte_size = end_reg_offset;
|
|
|
|
|
|
|
|
m_regs.push_back(reg_info);
|
|
|
|
m_set_reg_nums[set].push_back(i);
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
2015-05-26 18:00:51 +00:00
|
|
|
Finalize(arch);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
return m_regs.size();
|
2012-08-24 01:42:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-08-22 02:49:39 +00:00
|
|
|
void
|
2012-08-24 01:42:50 +00:00
|
|
|
DynamicRegisterInfo::AddRegister (RegisterInfo ®_info,
|
2011-08-22 02:49:39 +00:00
|
|
|
ConstString ®_name,
|
|
|
|
ConstString ®_alt_name,
|
|
|
|
ConstString &set_name)
|
|
|
|
{
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
assert(!m_finalized);
|
2011-08-22 02:49:39 +00:00
|
|
|
const uint32_t reg_num = m_regs.size();
|
|
|
|
reg_info.name = reg_name.AsCString();
|
|
|
|
assert (reg_info.name);
|
|
|
|
reg_info.alt_name = reg_alt_name.AsCString(NULL);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
uint32_t i;
|
|
|
|
if (reg_info.value_regs)
|
|
|
|
{
|
|
|
|
for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
|
|
|
|
m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
|
|
|
|
}
|
|
|
|
if (reg_info.invalidate_regs)
|
|
|
|
{
|
|
|
|
for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
|
|
|
|
m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
|
|
|
|
}
|
2011-08-22 02:49:39 +00:00
|
|
|
m_regs.push_back (reg_info);
|
|
|
|
uint32_t set = GetRegisterSetIndexByName (set_name, true);
|
|
|
|
assert (set < m_sets.size());
|
|
|
|
assert (set < m_set_reg_nums.size());
|
|
|
|
assert (set < m_set_names.size());
|
|
|
|
m_set_reg_nums[set].push_back(reg_num);
|
|
|
|
size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size;
|
|
|
|
if (m_reg_data_byte_size < end_reg_offset)
|
|
|
|
m_reg_data_byte_size = end_reg_offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-05-26 18:00:51 +00:00
|
|
|
DynamicRegisterInfo::Finalize (const ArchSpec &arch)
|
2011-08-22 02:49:39 +00:00
|
|
|
{
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
if (m_finalized)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_finalized = true;
|
|
|
|
const size_t num_sets = m_sets.size();
|
|
|
|
for (size_t set = 0; set < num_sets; ++set)
|
2011-08-22 02:49:39 +00:00
|
|
|
{
|
|
|
|
assert (m_sets.size() == m_set_reg_nums.size());
|
|
|
|
m_sets[set].num_registers = m_set_reg_nums[set].size();
|
|
|
|
m_sets[set].registers = &m_set_reg_nums[set][0];
|
|
|
|
}
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
|
|
|
|
// sort and unique all value registers and make sure each is terminated with
|
|
|
|
// LLDB_INVALID_REGNUM
|
|
|
|
|
|
|
|
for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end();
|
|
|
|
pos != end;
|
|
|
|
++pos)
|
|
|
|
{
|
|
|
|
if (pos->second.size() > 1)
|
|
|
|
{
|
|
|
|
std::sort (pos->second.begin(), pos->second.end());
|
|
|
|
reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
|
|
|
|
if (unique_end != pos->second.end())
|
|
|
|
pos->second.erase(unique_end, pos->second.end());
|
|
|
|
}
|
|
|
|
assert (!pos->second.empty());
|
|
|
|
if (pos->second.back() != LLDB_INVALID_REGNUM)
|
|
|
|
pos->second.push_back(LLDB_INVALID_REGNUM);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now update all value_regs with each register info as needed
|
|
|
|
const size_t num_regs = m_regs.size();
|
|
|
|
for (size_t i=0; i<num_regs; ++i)
|
|
|
|
{
|
|
|
|
if (m_value_regs_map.find(i) != m_value_regs_map.end())
|
|
|
|
m_regs[i].value_regs = m_value_regs_map[i].data();
|
|
|
|
else
|
|
|
|
m_regs[i].value_regs = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expand all invalidation dependencies
|
|
|
|
for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
|
|
|
|
pos != end;
|
|
|
|
++pos)
|
|
|
|
{
|
|
|
|
const uint32_t reg_num = pos->first;
|
|
|
|
|
|
|
|
if (m_regs[reg_num].value_regs)
|
|
|
|
{
|
|
|
|
reg_num_collection extra_invalid_regs;
|
|
|
|
for (const uint32_t invalidate_reg_num : pos->second)
|
|
|
|
{
|
|
|
|
reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num);
|
|
|
|
if (invalidate_pos != m_invalidate_regs_map.end())
|
|
|
|
{
|
|
|
|
for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second)
|
|
|
|
{
|
|
|
|
if (concrete_invalidate_reg_num != reg_num)
|
|
|
|
extra_invalid_regs.push_back(concrete_invalidate_reg_num);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sort and unique all invalidate registers and make sure each is terminated with
|
|
|
|
// LLDB_INVALID_REGNUM
|
|
|
|
for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end();
|
|
|
|
pos != end;
|
|
|
|
++pos)
|
|
|
|
{
|
|
|
|
if (pos->second.size() > 1)
|
|
|
|
{
|
|
|
|
std::sort (pos->second.begin(), pos->second.end());
|
|
|
|
reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end());
|
|
|
|
if (unique_end != pos->second.end())
|
|
|
|
pos->second.erase(unique_end, pos->second.end());
|
|
|
|
}
|
|
|
|
assert (!pos->second.empty());
|
|
|
|
if (pos->second.back() != LLDB_INVALID_REGNUM)
|
|
|
|
pos->second.push_back(LLDB_INVALID_REGNUM);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now update all invalidate_regs with each register info as needed
|
|
|
|
for (size_t i=0; i<num_regs; ++i)
|
|
|
|
{
|
|
|
|
if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end())
|
|
|
|
m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data();
|
|
|
|
else
|
|
|
|
m_regs[i].invalidate_regs = NULL;
|
|
|
|
}
|
2015-05-26 18:00:51 +00:00
|
|
|
|
|
|
|
// Check if we need to automatically set the generic registers in case
|
|
|
|
// they weren't set
|
|
|
|
bool generic_regs_specified = false;
|
|
|
|
for (const auto ®: m_regs)
|
|
|
|
{
|
|
|
|
if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
|
|
|
|
{
|
|
|
|
generic_regs_specified = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!generic_regs_specified)
|
|
|
|
{
|
|
|
|
switch (arch.GetMachine())
|
|
|
|
{
|
|
|
|
case llvm::Triple::aarch64:
|
|
|
|
case llvm::Triple::aarch64_be:
|
|
|
|
for (auto ®: m_regs)
|
|
|
|
{
|
|
|
|
if (strcmp(reg.name, "pc") == 0)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
|
|
|
|
else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
|
|
|
|
else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
|
|
|
|
else if (strcmp(reg.name, "cpsr") == 0)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
case llvm::Triple::armeb:
|
|
|
|
case llvm::Triple::thumb:
|
|
|
|
case llvm::Triple::thumbeb:
|
|
|
|
for (auto ®: m_regs)
|
|
|
|
{
|
|
|
|
if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
|
|
|
|
else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
|
|
|
|
else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
|
|
|
|
else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if (strcmp(reg.name, "fp") == 0)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if (strcmp(reg.name, "cpsr") == 0)
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
for (auto ®: m_regs)
|
|
|
|
{
|
|
|
|
if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
|
|
|
|
else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
|
|
|
|
else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
for (auto ®: m_regs)
|
|
|
|
{
|
|
|
|
if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
|
|
|
|
else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
|
|
|
|
else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
|
|
|
|
else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
|
|
|
|
reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-08-22 02:49:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
DynamicRegisterInfo::GetNumRegisters() const
|
|
|
|
{
|
|
|
|
return m_regs.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
DynamicRegisterInfo::GetNumRegisterSets() const
|
|
|
|
{
|
|
|
|
return m_sets.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
DynamicRegisterInfo::GetRegisterDataByteSize() const
|
|
|
|
{
|
|
|
|
return m_reg_data_byte_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RegisterInfo *
|
|
|
|
DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const
|
|
|
|
{
|
|
|
|
if (i < m_regs.size())
|
|
|
|
return &m_regs[i];
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RegisterSet *
|
|
|
|
DynamicRegisterInfo::GetRegisterSet (uint32_t i) const
|
|
|
|
{
|
|
|
|
if (i < m_sets.size())
|
|
|
|
return &m_sets[i];
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create)
|
|
|
|
{
|
|
|
|
name_collection::iterator pos, end = m_set_names.end();
|
|
|
|
for (pos = m_set_names.begin(); pos != end; ++pos)
|
|
|
|
{
|
|
|
|
if (*pos == set_name)
|
|
|
|
return std::distance (m_set_names.begin(), pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_set_names.push_back(set_name);
|
|
|
|
m_set_reg_nums.resize(m_set_reg_nums.size()+1);
|
|
|
|
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
|
|
|
|
m_sets.push_back (new_set);
|
|
|
|
return m_sets.size() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
|
|
|
|
{
|
|
|
|
reg_collection::const_iterator pos, end = m_regs.end();
|
|
|
|
for (pos = m_regs.begin(); pos != end; ++pos)
|
|
|
|
{
|
|
|
|
if (pos->kinds[kind] == num)
|
|
|
|
return std::distance (m_regs.begin(), pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
return LLDB_INVALID_REGNUM;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynamicRegisterInfo::Clear()
|
|
|
|
{
|
|
|
|
m_regs.clear();
|
|
|
|
m_sets.clear();
|
|
|
|
m_set_reg_nums.clear();
|
|
|
|
m_set_names.clear();
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
m_value_regs_map.clear();
|
|
|
|
m_invalidate_regs_map.clear();
|
|
|
|
m_reg_data_byte_size = 0;
|
|
|
|
m_finalized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DynamicRegisterInfo::Dump () const
|
|
|
|
{
|
|
|
|
StreamFile s(stdout, false);
|
|
|
|
const size_t num_regs = m_regs.size();
|
2014-04-04 04:06:10 +00:00
|
|
|
s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
|
|
|
|
static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
for (size_t i=0; i<num_regs; ++i)
|
|
|
|
{
|
2014-03-03 19:15:20 +00:00
|
|
|
s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s",
|
|
|
|
m_regs[i].byte_size,
|
|
|
|
m_regs[i].byte_offset,
|
|
|
|
m_regs[i].encoding,
|
|
|
|
FormatManager::GetFormatAsCString (m_regs[i].format));
|
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-15 23:20:34 +00:00
|
|
|
if (m_regs[i].kinds[eRegisterKindProcessPlugin] != LLDB_INVALID_REGNUM)
|
|
|
|
s.Printf(", process plugin = %3u", m_regs[i].kinds[eRegisterKindProcessPlugin]);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
|
|
|
|
s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
|
2015-08-15 01:21:01 +00:00
|
|
|
if (m_regs[i].kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
|
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-15 23:20:34 +00:00
|
|
|
s.Printf(", ehframe = %3u", m_regs[i].kinds[eRegisterKindEHFrame]);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
|
|
|
|
s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]);
|
|
|
|
if (m_regs[i].alt_name)
|
|
|
|
s.Printf(", alt-name = %s", m_regs[i].alt_name);
|
|
|
|
if (m_regs[i].value_regs)
|
|
|
|
{
|
|
|
|
s.Printf(", value_regs = [ ");
|
|
|
|
for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j)
|
|
|
|
{
|
|
|
|
s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name);
|
|
|
|
}
|
|
|
|
s.Printf("]");
|
|
|
|
}
|
|
|
|
if (m_regs[i].invalidate_regs)
|
|
|
|
{
|
|
|
|
s.Printf(", invalidate_regs = [ ");
|
|
|
|
for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j)
|
|
|
|
{
|
|
|
|
s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name);
|
|
|
|
}
|
|
|
|
s.Printf("]");
|
|
|
|
}
|
|
|
|
s.EOL();
|
|
|
|
}
|
2014-04-04 04:06:10 +00:00
|
|
|
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
const size_t num_sets = m_sets.size();
|
2014-04-04 04:06:10 +00:00
|
|
|
s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
|
|
|
|
static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
for (size_t i=0; i<num_sets; ++i)
|
|
|
|
{
|
2014-03-03 15:39:47 +00:00
|
|
|
s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
|
<rdar://problem/14972424>
- Made the dynamic register context for the GDB remote plug-in inherit from the generic DynamicRegisterInfo to avoid code duplication
- Finished up the target definition python setting stuff.
- Added a new "slice" key/value pair that can specify that a register is part of another register:
{ 'name':'eax', 'set':0, 'bitsize':32, 'encoding':eEncodingUint, 'format':eFormatHex, 'slice': 'rax[31:0]' },
- Added a new "composite" key/value pair that can specify that a register is made up of two or more registers:
{ 'name':'d0', 'set':0, 'bitsize':64 , 'encoding':eEncodingIEEE754, 'format':eFormatFloat, 'composite': ['s1', 's0'] },
- Added a new "invalidate-regs" key/value pair for when a register is modified, it can invalidate other registers:
{ 'name':'cpsr', 'set':0, 'bitsize':32 , 'encoding':eEncodingUint, 'format':eFormatHex, 'invalidate-regs': ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']},
This now completes the feature that allows a GDB remote target to completely describe itself.
llvm-svn: 192858
2013-10-17 01:10:23 +00:00
|
|
|
for (size_t idx=0; idx<m_sets[i].num_registers; ++idx)
|
|
|
|
{
|
|
|
|
s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name);
|
|
|
|
}
|
|
|
|
s.Printf("]\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lldb_private::RegisterInfo *
|
|
|
|
DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString ®_name)
|
|
|
|
{
|
|
|
|
for (auto ®_info : m_regs)
|
|
|
|
{
|
|
|
|
// We can use pointer comparison since we used a ConstString to set
|
|
|
|
// the "name" member in AddRegister()
|
|
|
|
if (reg_info.name == reg_name.GetCString())
|
|
|
|
{
|
|
|
|
return ®_info;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
2011-08-22 02:49:39 +00:00
|
|
|
}
|