1254721Semaste//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "DynamicRegisterInfo.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste// Project includes 18254721Semaste#include "lldb/Interpreter/Args.h" 19263363Semaste#include "lldb/Core/RegularExpression.h" 20263363Semaste#include "lldb/Core/StreamFile.h" 21263363Semaste#include "lldb/DataFormatters/FormatManager.h" 22254721Semaste 23254721Semaste#ifndef LLDB_DISABLE_PYTHON 24254721Semaste#include "lldb/Interpreter/PythonDataObjects.h" 25254721Semaste#endif 26254721Semaste 27254721Semasteusing namespace lldb; 28254721Semasteusing namespace lldb_private; 29254721Semaste 30254721SemasteDynamicRegisterInfo::DynamicRegisterInfo () : 31254721Semaste m_regs (), 32254721Semaste m_sets (), 33254721Semaste m_set_reg_nums (), 34254721Semaste m_set_names (), 35263363Semaste m_value_regs_map (), 36263363Semaste m_invalidate_regs_map (), 37263363Semaste m_reg_data_byte_size (0), 38263363Semaste m_finalized (false) 39254721Semaste{ 40254721Semaste} 41254721Semaste 42263363SemasteDynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : 43254721Semaste m_regs (), 44254721Semaste m_sets (), 45254721Semaste m_set_reg_nums (), 46254721Semaste m_set_names (), 47263363Semaste m_value_regs_map (), 48263363Semaste m_invalidate_regs_map (), 49263363Semaste m_reg_data_byte_size (0), 50263363Semaste m_finalized (false) 51254721Semaste{ 52263363Semaste SetRegisterInfo (dict, byte_order); 53254721Semaste} 54254721Semaste 55254721SemasteDynamicRegisterInfo::~DynamicRegisterInfo () 56254721Semaste{ 57254721Semaste} 58254721Semaste 59254721Semaste 60254721Semastesize_t 61263363SemasteDynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, 62263363Semaste ByteOrder byte_order) 63254721Semaste{ 64263363Semaste assert(!m_finalized); 65254721Semaste#ifndef LLDB_DISABLE_PYTHON 66254721Semaste PythonList sets (dict.GetItemForKey("sets")); 67254721Semaste if (sets) 68254721Semaste { 69254721Semaste const uint32_t num_sets = sets.GetSize(); 70254721Semaste for (uint32_t i=0; i<num_sets; ++i) 71254721Semaste { 72254721Semaste PythonString py_set_name(sets.GetItemAtIndex(i)); 73254721Semaste ConstString set_name; 74254721Semaste if (py_set_name) 75254721Semaste set_name.SetCString(py_set_name.GetString()); 76254721Semaste if (set_name) 77254721Semaste { 78254721Semaste RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 79254721Semaste m_sets.push_back (new_set); 80254721Semaste } 81254721Semaste else 82254721Semaste { 83254721Semaste Clear(); 84254721Semaste return 0; 85254721Semaste } 86254721Semaste } 87254721Semaste m_set_reg_nums.resize(m_sets.size()); 88254721Semaste } 89254721Semaste PythonList regs (dict.GetItemForKey("registers")); 90254721Semaste if (regs) 91254721Semaste { 92254721Semaste const uint32_t num_regs = regs.GetSize(); 93254721Semaste PythonString name_pystr("name"); 94254721Semaste PythonString altname_pystr("alt-name"); 95254721Semaste PythonString bitsize_pystr("bitsize"); 96254721Semaste PythonString offset_pystr("offset"); 97254721Semaste PythonString encoding_pystr("encoding"); 98254721Semaste PythonString format_pystr("format"); 99254721Semaste PythonString set_pystr("set"); 100254721Semaste PythonString gcc_pystr("gcc"); 101254721Semaste PythonString dwarf_pystr("dwarf"); 102254721Semaste PythonString generic_pystr("generic"); 103263363Semaste PythonString slice_pystr("slice"); 104263363Semaste PythonString composite_pystr("composite"); 105263363Semaste PythonString invalidate_regs_pystr("invalidate-regs"); 106263363Semaste 107263363Semaste// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap; 108263363Semaste// InvalidateNameMap invalidate_map; 109254721Semaste for (uint32_t i=0; i<num_regs; ++i) 110254721Semaste { 111254721Semaste PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); 112254721Semaste if (reg_info_dict) 113254721Semaste { 114254721Semaste // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, 115254721Semaste RegisterInfo reg_info; 116263363Semaste std::vector<uint32_t> value_regs; 117263363Semaste std::vector<uint32_t> invalidate_regs; 118254721Semaste bzero (®_info, sizeof(reg_info)); 119254721Semaste 120254721Semaste reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); 121254721Semaste if (reg_info.name == NULL) 122254721Semaste { 123254721Semaste Clear(); 124254721Semaste return 0; 125254721Semaste } 126254721Semaste 127254721Semaste reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); 128254721Semaste 129254721Semaste reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); 130254721Semaste 131254721Semaste if (reg_info.byte_offset == UINT32_MAX) 132254721Semaste { 133263363Semaste // No offset for this register, see if the register has a value expression 134263363Semaste // which indicates this register is part of another register. Value expressions 135263363Semaste // are things like "rax[31:0]" which state that the current register's value 136263363Semaste // is in a concrete register "rax" in bits 31:0. If there is a value expression 137263363Semaste // we can calculate the offset 138263363Semaste bool success = false; 139263363Semaste const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); 140263363Semaste if (slice_cstr) 141263363Semaste { 142263363Semaste // Slices use the following format: 143263363Semaste // REGNAME[MSBIT:LSBIT] 144263363Semaste // REGNAME - name of the register to grab a slice of 145263363Semaste // MSBIT - the most significant bit at which the current register value starts at 146263363Semaste // LSBIT - the least significant bit at which the current register value ends at 147263363Semaste static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); 148263363Semaste RegularExpression::Match regex_match(3); 149263363Semaste if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) 150263363Semaste { 151263363Semaste llvm::StringRef reg_name_str; 152263363Semaste std::string msbit_str; 153263363Semaste std::string lsbit_str; 154263363Semaste if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && 155263363Semaste regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && 156263363Semaste regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) 157263363Semaste { 158263363Semaste const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX); 159263363Semaste const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX); 160263363Semaste if (msbit != UINT32_MAX && lsbit != UINT32_MAX) 161263363Semaste { 162263363Semaste if (msbit > lsbit) 163263363Semaste { 164263363Semaste const uint32_t msbyte = msbit / 8; 165263363Semaste const uint32_t lsbyte = lsbit / 8; 166263363Semaste 167263363Semaste ConstString containing_reg_name(reg_name_str); 168263363Semaste 169263363Semaste RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); 170263363Semaste if (containing_reg_info) 171263363Semaste { 172263363Semaste const uint32_t max_bit = containing_reg_info->byte_size * 8; 173263363Semaste if (msbit < max_bit && lsbit < max_bit) 174263363Semaste { 175263363Semaste m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); 176263363Semaste m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); 177263363Semaste m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); 178263363Semaste 179263363Semaste if (byte_order == eByteOrderLittle) 180263363Semaste { 181263363Semaste success = true; 182263363Semaste reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; 183263363Semaste } 184263363Semaste else if (byte_order == eByteOrderBig) 185263363Semaste { 186263363Semaste success = true; 187263363Semaste reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; 188263363Semaste } 189263363Semaste else 190263363Semaste { 191263363Semaste assert(!"Invalid byte order"); 192263363Semaste } 193263363Semaste } 194263363Semaste else 195263363Semaste { 196263363Semaste if (msbit > max_bit) 197263363Semaste printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); 198263363Semaste else 199263363Semaste printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); 200263363Semaste } 201263363Semaste } 202263363Semaste else 203263363Semaste { 204263363Semaste printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); 205263363Semaste } 206263363Semaste } 207263363Semaste else 208263363Semaste { 209263363Semaste printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); 210263363Semaste } 211263363Semaste } 212263363Semaste else 213263363Semaste { 214263363Semaste printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); 215263363Semaste } 216263363Semaste } 217263363Semaste else 218263363Semaste { 219263363Semaste // TODO: print error invalid slice string that doesn't follow the format 220263363Semaste printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); 221263363Semaste 222263363Semaste } 223263363Semaste } 224263363Semaste else 225263363Semaste { 226263363Semaste // TODO: print error invalid slice string that doesn't follow the format 227263363Semaste printf("error: failed to match against register bitfield regex\n"); 228263363Semaste } 229263363Semaste } 230263363Semaste else 231263363Semaste { 232263363Semaste PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); 233263363Semaste if (composite_reg_list) 234263363Semaste { 235263363Semaste const size_t num_composite_regs = composite_reg_list.GetSize(); 236263363Semaste if (num_composite_regs > 0) 237263363Semaste { 238263363Semaste uint32_t composite_offset = UINT32_MAX; 239263363Semaste for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx) 240263363Semaste { 241263363Semaste PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx)); 242263363Semaste if (composite_reg_name_pystr) 243263363Semaste { 244263363Semaste ConstString composite_reg_name(composite_reg_name_pystr.GetString()); 245263363Semaste if (composite_reg_name) 246263363Semaste { 247263363Semaste RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name); 248263363Semaste if (composite_reg_info) 249263363Semaste { 250263363Semaste if (composite_offset > composite_reg_info->byte_offset) 251263363Semaste composite_offset = composite_reg_info->byte_offset; 252263363Semaste m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); 253263363Semaste m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); 254263363Semaste m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); 255263363Semaste } 256263363Semaste else 257263363Semaste { 258263363Semaste // TODO: print error invalid slice string that doesn't follow the format 259263363Semaste printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); 260263363Semaste } 261263363Semaste } 262263363Semaste else 263263363Semaste { 264263363Semaste printf("error: 'composite' key contained an empty string\n"); 265263363Semaste } 266263363Semaste } 267263363Semaste else 268263363Semaste { 269263363Semaste printf("error: 'composite' list value wasn't a python string\n"); 270263363Semaste } 271263363Semaste } 272263363Semaste if (composite_offset != UINT32_MAX) 273263363Semaste { 274263363Semaste reg_info.byte_offset = composite_offset; 275263363Semaste success = m_value_regs_map.find(i) != m_value_regs_map.end(); 276263363Semaste } 277263363Semaste else 278263363Semaste { 279263363Semaste printf("error: 'composite' registers must specify at least one real register\n"); 280263363Semaste } 281263363Semaste } 282263363Semaste else 283263363Semaste { 284263363Semaste printf("error: 'composite' list was empty\n"); 285263363Semaste } 286263363Semaste } 287263363Semaste } 288263363Semaste 289263363Semaste 290263363Semaste if (!success) 291263363Semaste { 292263363Semaste Clear(); 293263363Semaste return 0; 294263363Semaste } 295254721Semaste } 296263363Semaste const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); 297263363Semaste if (bitsize == 0) 298254721Semaste { 299254721Semaste Clear(); 300254721Semaste return 0; 301254721Semaste } 302263363Semaste 303263363Semaste reg_info.byte_size = bitsize / 8; 304254721Semaste 305254721Semaste const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); 306254721Semaste if (format_cstr) 307254721Semaste { 308254721Semaste if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) 309254721Semaste { 310254721Semaste Clear(); 311254721Semaste return 0; 312254721Semaste } 313254721Semaste } 314254721Semaste else 315263363Semaste { 316263363Semaste reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); 317263363Semaste } 318263363Semaste 319254721Semaste const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); 320254721Semaste if (encoding_cstr) 321254721Semaste reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); 322254721Semaste else 323263363Semaste reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); 324254721Semaste 325254721Semaste const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); 326254721Semaste if (set >= m_sets.size()) 327254721Semaste { 328254721Semaste Clear(); 329254721Semaste return 0; 330254721Semaste } 331254721Semaste 332263363Semaste // Fill in the register numbers 333254721Semaste reg_info.kinds[lldb::eRegisterKindLLDB] = i; 334254721Semaste reg_info.kinds[lldb::eRegisterKindGDB] = i; 335254721Semaste reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); 336254721Semaste reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM); 337263363Semaste const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); 338263363Semaste if (generic_cstr) 339263363Semaste reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); 340263363Semaste else 341263363Semaste reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); 342263363Semaste 343263363Semaste // Check if this register invalidates any other register values when it is modified 344263363Semaste PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); 345263363Semaste if (invalidate_reg_list) 346263363Semaste { 347263363Semaste const size_t num_regs = invalidate_reg_list.GetSize(); 348263363Semaste if (num_regs > 0) 349263363Semaste { 350263363Semaste for (uint32_t idx=0; idx<num_regs; ++idx) 351263363Semaste { 352263363Semaste PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx)); 353263363Semaste PythonString invalidate_reg_name_pystr(invalidate_reg_object); 354263363Semaste if (invalidate_reg_name_pystr) 355263363Semaste { 356263363Semaste ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString()); 357263363Semaste if (invalidate_reg_name) 358263363Semaste { 359263363Semaste RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name); 360263363Semaste if (invalidate_reg_info) 361263363Semaste { 362263363Semaste m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); 363263363Semaste } 364263363Semaste else 365263363Semaste { 366263363Semaste // TODO: print error invalid slice string that doesn't follow the format 367263363Semaste printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); 368263363Semaste } 369263363Semaste } 370263363Semaste else 371263363Semaste { 372263363Semaste printf("error: 'invalidate-regs' list value was an empty string\n"); 373263363Semaste } 374263363Semaste } 375263363Semaste else 376263363Semaste { 377263363Semaste PythonInteger invalidate_reg_num(invalidate_reg_object); 378263363Semaste 379263363Semaste if (invalidate_reg_num) 380263363Semaste { 381263363Semaste const int64_t r = invalidate_reg_num.GetInteger(); 382263363Semaste if (r != UINT64_MAX) 383263363Semaste m_invalidate_regs_map[i].push_back(r); 384263363Semaste else 385263363Semaste printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); 386263363Semaste } 387263363Semaste else 388263363Semaste { 389263363Semaste printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); 390263363Semaste } 391263363Semaste } 392263363Semaste } 393263363Semaste } 394263363Semaste else 395263363Semaste { 396263363Semaste printf("error: 'invalidate-regs' contained an empty list\n"); 397263363Semaste } 398263363Semaste } 399263363Semaste 400263363Semaste // Calculate the register offset 401254721Semaste const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 402254721Semaste if (m_reg_data_byte_size < end_reg_offset) 403254721Semaste m_reg_data_byte_size = end_reg_offset; 404254721Semaste 405254721Semaste m_regs.push_back (reg_info); 406254721Semaste m_set_reg_nums[set].push_back(i); 407254721Semaste 408254721Semaste } 409254721Semaste else 410254721Semaste { 411254721Semaste Clear(); 412254721Semaste return 0; 413254721Semaste } 414254721Semaste } 415254721Semaste Finalize (); 416254721Semaste } 417254721Semaste#endif 418263363Semaste return m_regs.size(); 419254721Semaste} 420254721Semaste 421254721Semaste 422254721Semastevoid 423254721SemasteDynamicRegisterInfo::AddRegister (RegisterInfo ®_info, 424254721Semaste ConstString ®_name, 425254721Semaste ConstString ®_alt_name, 426254721Semaste ConstString &set_name) 427254721Semaste{ 428263363Semaste assert(!m_finalized); 429254721Semaste const uint32_t reg_num = m_regs.size(); 430254721Semaste reg_info.name = reg_name.AsCString(); 431254721Semaste assert (reg_info.name); 432254721Semaste reg_info.alt_name = reg_alt_name.AsCString(NULL); 433263363Semaste uint32_t i; 434263363Semaste if (reg_info.value_regs) 435263363Semaste { 436263363Semaste for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) 437263363Semaste m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); 438263363Semaste } 439263363Semaste if (reg_info.invalidate_regs) 440263363Semaste { 441263363Semaste for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) 442263363Semaste m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); 443263363Semaste } 444254721Semaste m_regs.push_back (reg_info); 445254721Semaste uint32_t set = GetRegisterSetIndexByName (set_name, true); 446254721Semaste assert (set < m_sets.size()); 447254721Semaste assert (set < m_set_reg_nums.size()); 448254721Semaste assert (set < m_set_names.size()); 449254721Semaste m_set_reg_nums[set].push_back(reg_num); 450254721Semaste size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 451254721Semaste if (m_reg_data_byte_size < end_reg_offset) 452254721Semaste m_reg_data_byte_size = end_reg_offset; 453254721Semaste} 454254721Semaste 455254721Semastevoid 456254721SemasteDynamicRegisterInfo::Finalize () 457254721Semaste{ 458263363Semaste if (m_finalized) 459263363Semaste return; 460263363Semaste 461263363Semaste m_finalized = true; 462263363Semaste const size_t num_sets = m_sets.size(); 463263363Semaste for (size_t set = 0; set < num_sets; ++set) 464254721Semaste { 465254721Semaste assert (m_sets.size() == m_set_reg_nums.size()); 466254721Semaste m_sets[set].num_registers = m_set_reg_nums[set].size(); 467254721Semaste m_sets[set].registers = &m_set_reg_nums[set][0]; 468254721Semaste } 469263363Semaste 470263363Semaste // sort and unique all value registers and make sure each is terminated with 471263363Semaste // LLDB_INVALID_REGNUM 472263363Semaste 473263363Semaste for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end(); 474263363Semaste pos != end; 475263363Semaste ++pos) 476263363Semaste { 477263363Semaste if (pos->second.size() > 1) 478263363Semaste { 479263363Semaste std::sort (pos->second.begin(), pos->second.end()); 480263363Semaste reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); 481263363Semaste if (unique_end != pos->second.end()) 482263363Semaste pos->second.erase(unique_end, pos->second.end()); 483263363Semaste } 484263363Semaste assert (!pos->second.empty()); 485263363Semaste if (pos->second.back() != LLDB_INVALID_REGNUM) 486263363Semaste pos->second.push_back(LLDB_INVALID_REGNUM); 487263363Semaste } 488263363Semaste 489263363Semaste // Now update all value_regs with each register info as needed 490263363Semaste const size_t num_regs = m_regs.size(); 491263363Semaste for (size_t i=0; i<num_regs; ++i) 492263363Semaste { 493263363Semaste if (m_value_regs_map.find(i) != m_value_regs_map.end()) 494263363Semaste m_regs[i].value_regs = m_value_regs_map[i].data(); 495263363Semaste else 496263363Semaste m_regs[i].value_regs = NULL; 497263363Semaste } 498263363Semaste 499263363Semaste // Expand all invalidation dependencies 500263363Semaste for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); 501263363Semaste pos != end; 502263363Semaste ++pos) 503263363Semaste { 504263363Semaste const uint32_t reg_num = pos->first; 505263363Semaste 506263363Semaste if (m_regs[reg_num].value_regs) 507263363Semaste { 508263363Semaste reg_num_collection extra_invalid_regs; 509263363Semaste for (const uint32_t invalidate_reg_num : pos->second) 510263363Semaste { 511263363Semaste reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num); 512263363Semaste if (invalidate_pos != m_invalidate_regs_map.end()) 513263363Semaste { 514263363Semaste for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second) 515263363Semaste { 516263363Semaste if (concrete_invalidate_reg_num != reg_num) 517263363Semaste extra_invalid_regs.push_back(concrete_invalidate_reg_num); 518263363Semaste } 519263363Semaste } 520263363Semaste } 521263363Semaste pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end()); 522263363Semaste } 523263363Semaste } 524263363Semaste 525263363Semaste // sort and unique all invalidate registers and make sure each is terminated with 526263363Semaste // LLDB_INVALID_REGNUM 527263363Semaste for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); 528263363Semaste pos != end; 529263363Semaste ++pos) 530263363Semaste { 531263363Semaste if (pos->second.size() > 1) 532263363Semaste { 533263363Semaste std::sort (pos->second.begin(), pos->second.end()); 534263363Semaste reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); 535263363Semaste if (unique_end != pos->second.end()) 536263363Semaste pos->second.erase(unique_end, pos->second.end()); 537263363Semaste } 538263363Semaste assert (!pos->second.empty()); 539263363Semaste if (pos->second.back() != LLDB_INVALID_REGNUM) 540263363Semaste pos->second.push_back(LLDB_INVALID_REGNUM); 541263363Semaste } 542263363Semaste 543263363Semaste // Now update all invalidate_regs with each register info as needed 544263363Semaste for (size_t i=0; i<num_regs; ++i) 545263363Semaste { 546263363Semaste if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) 547263363Semaste m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); 548263363Semaste else 549263363Semaste m_regs[i].invalidate_regs = NULL; 550263363Semaste } 551254721Semaste} 552254721Semaste 553254721Semastesize_t 554254721SemasteDynamicRegisterInfo::GetNumRegisters() const 555254721Semaste{ 556254721Semaste return m_regs.size(); 557254721Semaste} 558254721Semaste 559254721Semastesize_t 560254721SemasteDynamicRegisterInfo::GetNumRegisterSets() const 561254721Semaste{ 562254721Semaste return m_sets.size(); 563254721Semaste} 564254721Semaste 565254721Semastesize_t 566254721SemasteDynamicRegisterInfo::GetRegisterDataByteSize() const 567254721Semaste{ 568254721Semaste return m_reg_data_byte_size; 569254721Semaste} 570254721Semaste 571254721Semasteconst RegisterInfo * 572254721SemasteDynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const 573254721Semaste{ 574254721Semaste if (i < m_regs.size()) 575254721Semaste return &m_regs[i]; 576254721Semaste return NULL; 577254721Semaste} 578254721Semaste 579254721Semasteconst RegisterSet * 580254721SemasteDynamicRegisterInfo::GetRegisterSet (uint32_t i) const 581254721Semaste{ 582254721Semaste if (i < m_sets.size()) 583254721Semaste return &m_sets[i]; 584254721Semaste return NULL; 585254721Semaste} 586254721Semaste 587254721Semasteuint32_t 588254721SemasteDynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create) 589254721Semaste{ 590254721Semaste name_collection::iterator pos, end = m_set_names.end(); 591254721Semaste for (pos = m_set_names.begin(); pos != end; ++pos) 592254721Semaste { 593254721Semaste if (*pos == set_name) 594254721Semaste return std::distance (m_set_names.begin(), pos); 595254721Semaste } 596254721Semaste 597254721Semaste m_set_names.push_back(set_name); 598254721Semaste m_set_reg_nums.resize(m_set_reg_nums.size()+1); 599254721Semaste RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 600254721Semaste m_sets.push_back (new_set); 601254721Semaste return m_sets.size() - 1; 602254721Semaste} 603254721Semaste 604254721Semasteuint32_t 605254721SemasteDynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const 606254721Semaste{ 607254721Semaste reg_collection::const_iterator pos, end = m_regs.end(); 608254721Semaste for (pos = m_regs.begin(); pos != end; ++pos) 609254721Semaste { 610254721Semaste if (pos->kinds[kind] == num) 611254721Semaste return std::distance (m_regs.begin(), pos); 612254721Semaste } 613254721Semaste 614254721Semaste return LLDB_INVALID_REGNUM; 615254721Semaste} 616254721Semaste 617254721Semastevoid 618254721SemasteDynamicRegisterInfo::Clear() 619254721Semaste{ 620254721Semaste m_regs.clear(); 621254721Semaste m_sets.clear(); 622254721Semaste m_set_reg_nums.clear(); 623254721Semaste m_set_names.clear(); 624263363Semaste m_value_regs_map.clear(); 625263363Semaste m_invalidate_regs_map.clear(); 626263363Semaste m_reg_data_byte_size = 0; 627263363Semaste m_finalized = false; 628254721Semaste} 629263363Semaste 630263363Semastevoid 631263363SemasteDynamicRegisterInfo::Dump () const 632263363Semaste{ 633263363Semaste StreamFile s(stdout, false); 634263363Semaste const size_t num_regs = m_regs.size(); 635263363Semaste s.Printf("%p: DynamicRegisterInfo contains %zu registers:\n", this, num_regs); 636263363Semaste for (size_t i=0; i<num_regs; ++i) 637263363Semaste { 638263363Semaste s.Printf("[%3zu] name = %-10s", i, m_regs[i].name); 639263363Semaste s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s", 640263363Semaste m_regs[i].byte_size, 641263363Semaste m_regs[i].byte_offset, 642263363Semaste m_regs[i].encoding, 643263363Semaste FormatManager::GetFormatAsCString (m_regs[i].format)); 644263363Semaste if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM) 645263363Semaste s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]); 646263363Semaste if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) 647263363Semaste s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]); 648263363Semaste if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM) 649263363Semaste s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]); 650263363Semaste if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) 651263363Semaste s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]); 652263363Semaste if (m_regs[i].alt_name) 653263363Semaste s.Printf(", alt-name = %s", m_regs[i].alt_name); 654263363Semaste if (m_regs[i].value_regs) 655263363Semaste { 656263363Semaste s.Printf(", value_regs = [ "); 657263363Semaste for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) 658263363Semaste { 659263363Semaste s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name); 660263363Semaste } 661263363Semaste s.Printf("]"); 662263363Semaste } 663263363Semaste if (m_regs[i].invalidate_regs) 664263363Semaste { 665263363Semaste s.Printf(", invalidate_regs = [ "); 666263363Semaste for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j) 667263363Semaste { 668263363Semaste s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name); 669263363Semaste } 670263363Semaste s.Printf("]"); 671263363Semaste } 672263363Semaste s.EOL(); 673263363Semaste } 674263363Semaste 675263363Semaste const size_t num_sets = m_sets.size(); 676263363Semaste s.Printf("%p: DynamicRegisterInfo contains %zu register sets:\n", this, num_sets); 677263363Semaste for (size_t i=0; i<num_sets; ++i) 678263363Semaste { 679263363Semaste s.Printf("set[%zu] name = %s, regs = [", i, m_sets[i].name); 680263363Semaste for (size_t idx=0; idx<m_sets[i].num_registers; ++idx) 681263363Semaste { 682263363Semaste s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name); 683263363Semaste } 684263363Semaste s.Printf("]\n"); 685263363Semaste } 686263363Semaste} 687263363Semaste 688263363Semaste 689263363Semaste 690263363Semastelldb_private::RegisterInfo * 691263363SemasteDynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString ®_name) 692263363Semaste{ 693263363Semaste for (auto ®_info : m_regs) 694263363Semaste { 695263363Semaste // We can use pointer comparison since we used a ConstString to set 696263363Semaste // the "name" member in AddRegister() 697263363Semaste if (reg_info.name == reg_name.GetCString()) 698263363Semaste { 699263363Semaste return ®_info; 700263363Semaste } 701263363Semaste } 702263363Semaste return NULL; 703263363Semaste} 704