llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp

771 lines
31 KiB
C++
Raw Normal View History

//===-- 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
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.h"
using namespace lldb;
using namespace lldb_private;
DynamicRegisterInfo::DynamicRegisterInfo () :
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)
{
}
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)
{
SetRegisterInfo (dict, arch);
}
DynamicRegisterInfo::~DynamicRegisterInfo ()
{
}
size_t
DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
{
assert(!m_finalized);
StructuredData::Array *sets = nullptr;
if (dict.GetValueForKeyAsArray("sets", sets))
{
const uint32_t num_sets = sets->GetSize();
for (uint32_t i=0; i<num_sets; ++i)
{
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;
if (sets->GetItemAtIndexAsString(i, set_name_str))
set_name.SetCString(set_name_str.c_str());
if (set_name)
{
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
m_sets.push_back (new_set);
}
else
{
Clear();
printf("error: register sets must have valid names\n");
return 0;
}
}
m_set_reg_nums.resize(m_sets.size());
}
StructuredData::Array *regs = nullptr;
if (!dict.GetValueForKeyAsArray("registers", regs))
return 0;
const uint32_t num_regs = regs->GetSize();
// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap;
// InvalidateNameMap invalidate_map;
for (uint32_t i = 0; i < num_regs; ++i)
{
StructuredData::Dictionary *reg_info_dict = nullptr;
if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict))
{
Clear();
printf("error: items in the 'registers' array must be dictionaries\n");
regs->DumpToStdout();
return 0;
}
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,
// 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
RegisterInfo reg_info;
std::vector<uint32_t> value_regs;
std::vector<uint32_t> invalidate_regs;
memset(&reg_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);
const ByteOrder byte_order = arch.GetByteOrder();
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(), &regex_match))
{
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))
{
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)
{
if (msbit > lsbit)
{
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)
{
const uint32_t max_bit = containing_reg_info->byte_size * 8;
if (msbit < max_bit && lsbit < max_bit)
{
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]);
if (byte_order == eByteOrderLittle)
{
success = true;
reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte;
}
else if (byte_order == eByteOrderBig)
{
success = true;
reg_info.byte_offset = containing_reg_info->byte_offset + msbyte;
}
else
{
assert(!"Invalid byte order");
}
}
else
{
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);
}
}
else
{
printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString());
}
}
else
{
printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit);
}
}
else
{
printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit);
}
}
else
{
// 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)
{
ConstString composite_reg_name;
if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr))
{
RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name);
if (composite_reg_info)
{
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]);
}
else
{
// 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());
}
}
else
{
printf("error: 'composite' list value wasn't a python string\n");
}
}
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");
}
}
else
{
printf("error: 'composite' list was empty\n");
}
}
}
<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
if (!success)
{
Clear();
reg_info_dict->DumpToStdout();
return 0;
}
}
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;
}
reg_info.byte_size = bitsize / 8;
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;
uint32_t eh_frame_regno = LLDB_INVALID_REGNUM;
reg_info_dict->GetValueForKeyAsInteger("gcc", eh_frame_regno, LLDB_INVALID_REGNUM);
if (eh_frame_regno == LLDB_INVALID_REGNUM)
reg_info_dict->GetValueForKeyAsInteger("ehframe", eh_frame_regno, LLDB_INVALID_REGNUM);
reg_info.kinds[lldb::eRegisterKindEHFrame] = eh_frame_regno;
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)
{
ConstString invalidate_reg_name;
uint64_t invalidate_reg_num;
if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name))
{
RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name);
if (invalidate_reg_info)
{
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);
}
}
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");
}
else
{
printf("error: 'invalidate-regs' list value wasn't a python string or integer\n");
}
}
}
else
{
printf("error: 'invalidate-regs' contained an empty list\n");
}
}
// 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);
}
Finalize(arch);
return m_regs.size();
}
void
DynamicRegisterInfo::AddRegister (RegisterInfo &reg_info,
ConstString &reg_name,
ConstString &reg_alt_name,
ConstString &set_name)
{
assert(!m_finalized);
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);
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]);
}
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
DynamicRegisterInfo::Finalize (const ArchSpec &arch)
{
if (m_finalized)
return;
m_finalized = true;
const size_t num_sets = m_sets.size();
for (size_t set = 0; set < num_sets; ++set)
{
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];
}
// 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;
}
// Check if we need to automatically set the generic registers in case
// they weren't set
bool generic_regs_specified = false;
for (const auto &reg: 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 &reg: 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 &reg: 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 &reg: 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 &reg: 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;
}
}
}
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();
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();
s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n",
static_cast<const void*>(this), static_cast<uint64_t>(num_regs));
for (size_t i=0; i<num_regs; ++i)
{
s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name);
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]);
if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]);
A messy bit of cleanup: Move towards more descriptive names for eh_frame and stabs register numberings. This is not complete but it's a step in the right direction. It's almost entirely mechanical. lldb informally uses "gcc register numbering" to mean eh_frame. Why? Probably because there's a notorious bug with gcc on i386 darwin where the register numbers in eh_frame were incorrect. In all other cases, eh_frame register numbering is identical to dwarf. lldb informally uses "gdb register numbering" to mean stabs. There are no official definitions of stabs register numbers for different architectures, so the implementations of gdb and gcc are the de facto reference source. There were some incorrect uses of these register number types in lldb already. I fixed the ones that I saw as I made this change. This commit changes all references to "gcc" and "gdb" register numbers in lldb to "eh_frame" and "stabs" to make it clear what is actually being represented. lldb cannot parse the stabs debug format, and given that no one is using stabs any more, it is unlikely that it ever will. A more comprehensive cleanup would remove the stabs register numbers altogether - it's unnecessary cruft / complication to all of our register structures. In ProcessGDBRemote, when we get register definitions from the gdb-remote stub, we expect to see "gcc:" (qRegisterInfo) or "gcc_regnum" (qXfer:features:read: packet to get xml payload). This patch changes ProcessGDBRemote to also accept "ehframe:" and "ehframe_regnum" from these remotes. I did not change GDBRemoteCommunicationServerLLGS or debugserver to send these new packets. I don't know what kind of interoperability constraints we might be working under. At some point in the future we should transition to using the more descriptive names. Throughout lldb we're still using enum names like "gcc_r0" and "gdb_r0", for eh_frame and stabs register numberings. These should be cleaned up eventually too. The sources link cleanly on macosx native with xcode build. I don't think we'll see problems on other platforms but please let me know if I broke anyone. llvm-svn: 245141
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]);
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();
}
const size_t num_sets = m_sets.size();
s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n",
static_cast<const void*>(this), static_cast<uint64_t>(num_sets));
for (size_t i=0; i<num_sets; ++i)
{
s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name);
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 &reg_name)
{
for (auto &reg_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 &reg_info;
}
}
return NULL;
}