1 //===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/lldb-python.h" 11 12 #include "DynamicRegisterInfo.h" 13 14 // C Includes 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Interpreter/Args.h" 19 #include "lldb/Core/RegularExpression.h" 20 #include "lldb/Core/StreamFile.h" 21 #include "lldb/DataFormatters/FormatManager.h" 22 23 #ifndef LLDB_DISABLE_PYTHON 24 #include "lldb/Interpreter/PythonDataObjects.h" 25 #endif 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 DynamicRegisterInfo::DynamicRegisterInfo () : 31 m_regs (), 32 m_sets (), 33 m_set_reg_nums (), 34 m_set_names (), 35 m_value_regs_map (), 36 m_invalidate_regs_map (), 37 m_reg_data_byte_size (0), 38 m_finalized (false) 39 { 40 } 41 42 DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : 43 m_regs (), 44 m_sets (), 45 m_set_reg_nums (), 46 m_set_names (), 47 m_value_regs_map (), 48 m_invalidate_regs_map (), 49 m_reg_data_byte_size (0), 50 m_finalized (false) 51 { 52 SetRegisterInfo (dict, byte_order); 53 } 54 55 DynamicRegisterInfo::~DynamicRegisterInfo () 56 { 57 } 58 59 60 size_t 61 DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, 62 ByteOrder byte_order) 63 { 64 assert(!m_finalized); 65 #ifndef LLDB_DISABLE_PYTHON 66 PythonList sets (dict.GetItemForKey("sets")); 67 if (sets) 68 { 69 const uint32_t num_sets = sets.GetSize(); 70 for (uint32_t i=0; i<num_sets; ++i) 71 { 72 PythonString py_set_name(sets.GetItemAtIndex(i)); 73 ConstString set_name; 74 if (py_set_name) 75 set_name.SetCString(py_set_name.GetString()); 76 if (set_name) 77 { 78 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 79 m_sets.push_back (new_set); 80 } 81 else 82 { 83 Clear(); 84 printf("error: register sets must have valid names\n"); 85 return 0; 86 } 87 } 88 m_set_reg_nums.resize(m_sets.size()); 89 } 90 PythonList regs (dict.GetItemForKey("registers")); 91 if (regs) 92 { 93 const uint32_t num_regs = regs.GetSize(); 94 PythonString name_pystr("name"); 95 PythonString altname_pystr("alt-name"); 96 PythonString bitsize_pystr("bitsize"); 97 PythonString offset_pystr("offset"); 98 PythonString encoding_pystr("encoding"); 99 PythonString format_pystr("format"); 100 PythonString set_pystr("set"); 101 PythonString gcc_pystr("gcc"); 102 PythonString dwarf_pystr("dwarf"); 103 PythonString generic_pystr("generic"); 104 PythonString slice_pystr("slice"); 105 PythonString composite_pystr("composite"); 106 PythonString invalidate_regs_pystr("invalidate-regs"); 107 108 // typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap; 109 // InvalidateNameMap invalidate_map; 110 for (uint32_t i=0; i<num_regs; ++i) 111 { 112 PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); 113 if (reg_info_dict) 114 { 115 // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, 116 RegisterInfo reg_info; 117 std::vector<uint32_t> value_regs; 118 std::vector<uint32_t> invalidate_regs; 119 memset(®_info, 0, sizeof(reg_info)); 120 121 reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); 122 if (reg_info.name == NULL) 123 { 124 Clear(); 125 printf("error: registers must have valid names\n"); 126 reg_info_dict.Dump(); 127 return 0; 128 } 129 130 reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); 131 132 reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); 133 134 if (reg_info.byte_offset == UINT32_MAX) 135 { 136 // No offset for this register, see if the register has a value expression 137 // which indicates this register is part of another register. Value expressions 138 // are things like "rax[31:0]" which state that the current register's value 139 // is in a concrete register "rax" in bits 31:0. If there is a value expression 140 // we can calculate the offset 141 bool success = false; 142 const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); 143 if (slice_cstr) 144 { 145 // Slices use the following format: 146 // REGNAME[MSBIT:LSBIT] 147 // REGNAME - name of the register to grab a slice of 148 // MSBIT - the most significant bit at which the current register value starts at 149 // LSBIT - the least significant bit at which the current register value ends at 150 static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); 151 RegularExpression::Match regex_match(3); 152 if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) 153 { 154 llvm::StringRef reg_name_str; 155 std::string msbit_str; 156 std::string lsbit_str; 157 if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && 158 regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && 159 regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) 160 { 161 const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX); 162 const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX); 163 if (msbit != UINT32_MAX && lsbit != UINT32_MAX) 164 { 165 if (msbit > lsbit) 166 { 167 const uint32_t msbyte = msbit / 8; 168 const uint32_t lsbyte = lsbit / 8; 169 170 ConstString containing_reg_name(reg_name_str); 171 172 RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); 173 if (containing_reg_info) 174 { 175 const uint32_t max_bit = containing_reg_info->byte_size * 8; 176 if (msbit < max_bit && lsbit < max_bit) 177 { 178 m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); 179 m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); 180 m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); 181 182 if (byte_order == eByteOrderLittle) 183 { 184 success = true; 185 reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; 186 } 187 else if (byte_order == eByteOrderBig) 188 { 189 success = true; 190 reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; 191 } 192 else 193 { 194 assert(!"Invalid byte order"); 195 } 196 } 197 else 198 { 199 if (msbit > max_bit) 200 printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); 201 else 202 printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); 203 } 204 } 205 else 206 { 207 printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); 208 } 209 } 210 else 211 { 212 printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); 213 } 214 } 215 else 216 { 217 printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); 218 } 219 } 220 else 221 { 222 // TODO: print error invalid slice string that doesn't follow the format 223 printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); 224 225 } 226 } 227 else 228 { 229 // TODO: print error invalid slice string that doesn't follow the format 230 printf("error: failed to match against register bitfield regex\n"); 231 } 232 } 233 else 234 { 235 PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); 236 if (composite_reg_list) 237 { 238 const size_t num_composite_regs = composite_reg_list.GetSize(); 239 if (num_composite_regs > 0) 240 { 241 uint32_t composite_offset = UINT32_MAX; 242 for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx) 243 { 244 PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx)); 245 if (composite_reg_name_pystr) 246 { 247 ConstString composite_reg_name(composite_reg_name_pystr.GetString()); 248 if (composite_reg_name) 249 { 250 RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name); 251 if (composite_reg_info) 252 { 253 if (composite_offset > composite_reg_info->byte_offset) 254 composite_offset = composite_reg_info->byte_offset; 255 m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); 256 m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); 257 m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); 258 } 259 else 260 { 261 // TODO: print error invalid slice string that doesn't follow the format 262 printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); 263 } 264 } 265 else 266 { 267 printf("error: 'composite' key contained an empty string\n"); 268 } 269 } 270 else 271 { 272 printf("error: 'composite' list value wasn't a python string\n"); 273 } 274 } 275 if (composite_offset != UINT32_MAX) 276 { 277 reg_info.byte_offset = composite_offset; 278 success = m_value_regs_map.find(i) != m_value_regs_map.end(); 279 } 280 else 281 { 282 printf("error: 'composite' registers must specify at least one real register\n"); 283 } 284 } 285 else 286 { 287 printf("error: 'composite' list was empty\n"); 288 } 289 } 290 } 291 292 293 if (!success) 294 { 295 Clear(); 296 reg_info_dict.Dump(); 297 return 0; 298 } 299 } 300 const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); 301 if (bitsize == 0) 302 { 303 Clear(); 304 printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); 305 reg_info_dict.Dump(); 306 return 0; 307 } 308 309 reg_info.byte_size = bitsize / 8; 310 311 const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); 312 if (format_cstr) 313 { 314 if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) 315 { 316 Clear(); 317 printf("error: invalid 'format' value in register dictionary\n"); 318 reg_info_dict.Dump(); 319 return 0; 320 } 321 } 322 else 323 { 324 reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); 325 } 326 327 const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); 328 if (encoding_cstr) 329 reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); 330 else 331 reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); 332 333 const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); 334 if (static_cast<size_t>(set) >= m_sets.size()) 335 { 336 Clear(); 337 printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); 338 reg_info_dict.Dump(); 339 return 0; 340 } 341 342 // Fill in the register numbers 343 reg_info.kinds[lldb::eRegisterKindLLDB] = i; 344 reg_info.kinds[lldb::eRegisterKindGDB] = i; 345 reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); 346 reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM); 347 const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); 348 if (generic_cstr) 349 reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); 350 else 351 reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); 352 353 // Check if this register invalidates any other register values when it is modified 354 PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); 355 if (invalidate_reg_list) 356 { 357 const size_t num_regs = invalidate_reg_list.GetSize(); 358 if (num_regs > 0) 359 { 360 for (uint32_t idx=0; idx<num_regs; ++idx) 361 { 362 PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx)); 363 PythonString invalidate_reg_name_pystr(invalidate_reg_object); 364 if (invalidate_reg_name_pystr) 365 { 366 ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString()); 367 if (invalidate_reg_name) 368 { 369 RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name); 370 if (invalidate_reg_info) 371 { 372 m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); 373 } 374 else 375 { 376 // TODO: print error invalid slice string that doesn't follow the format 377 printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); 378 } 379 } 380 else 381 { 382 printf("error: 'invalidate-regs' list value was an empty string\n"); 383 } 384 } 385 else 386 { 387 PythonInteger invalidate_reg_num(invalidate_reg_object); 388 389 if (invalidate_reg_num) 390 { 391 const int64_t r = invalidate_reg_num.GetInteger(); 392 if (r != static_cast<int64_t>(UINT64_MAX)) 393 m_invalidate_regs_map[i].push_back(r); 394 else 395 printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); 396 } 397 else 398 { 399 printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); 400 } 401 } 402 } 403 } 404 else 405 { 406 printf("error: 'invalidate-regs' contained an empty list\n"); 407 } 408 } 409 410 // Calculate the register offset 411 const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 412 if (m_reg_data_byte_size < end_reg_offset) 413 m_reg_data_byte_size = end_reg_offset; 414 415 m_regs.push_back (reg_info); 416 m_set_reg_nums[set].push_back(i); 417 418 } 419 else 420 { 421 Clear(); 422 printf("error: items in the 'registers' array must be dictionaries\n"); 423 regs.Dump(); 424 return 0; 425 } 426 } 427 Finalize (); 428 } 429 #endif 430 return m_regs.size(); 431 } 432 433 434 void 435 DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, 436 ConstString ®_name, 437 ConstString ®_alt_name, 438 ConstString &set_name) 439 { 440 assert(!m_finalized); 441 const uint32_t reg_num = m_regs.size(); 442 reg_info.name = reg_name.AsCString(); 443 assert (reg_info.name); 444 reg_info.alt_name = reg_alt_name.AsCString(NULL); 445 uint32_t i; 446 if (reg_info.value_regs) 447 { 448 for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) 449 m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); 450 } 451 if (reg_info.invalidate_regs) 452 { 453 for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) 454 m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); 455 } 456 m_regs.push_back (reg_info); 457 uint32_t set = GetRegisterSetIndexByName (set_name, true); 458 assert (set < m_sets.size()); 459 assert (set < m_set_reg_nums.size()); 460 assert (set < m_set_names.size()); 461 m_set_reg_nums[set].push_back(reg_num); 462 size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; 463 if (m_reg_data_byte_size < end_reg_offset) 464 m_reg_data_byte_size = end_reg_offset; 465 } 466 467 void 468 DynamicRegisterInfo::Finalize () 469 { 470 if (m_finalized) 471 return; 472 473 m_finalized = true; 474 const size_t num_sets = m_sets.size(); 475 for (size_t set = 0; set < num_sets; ++set) 476 { 477 assert (m_sets.size() == m_set_reg_nums.size()); 478 m_sets[set].num_registers = m_set_reg_nums[set].size(); 479 m_sets[set].registers = &m_set_reg_nums[set][0]; 480 } 481 482 // sort and unique all value registers and make sure each is terminated with 483 // LLDB_INVALID_REGNUM 484 485 for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end(); 486 pos != end; 487 ++pos) 488 { 489 if (pos->second.size() > 1) 490 { 491 std::sort (pos->second.begin(), pos->second.end()); 492 reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); 493 if (unique_end != pos->second.end()) 494 pos->second.erase(unique_end, pos->second.end()); 495 } 496 assert (!pos->second.empty()); 497 if (pos->second.back() != LLDB_INVALID_REGNUM) 498 pos->second.push_back(LLDB_INVALID_REGNUM); 499 } 500 501 // Now update all value_regs with each register info as needed 502 const size_t num_regs = m_regs.size(); 503 for (size_t i=0; i<num_regs; ++i) 504 { 505 if (m_value_regs_map.find(i) != m_value_regs_map.end()) 506 m_regs[i].value_regs = m_value_regs_map[i].data(); 507 else 508 m_regs[i].value_regs = NULL; 509 } 510 511 // Expand all invalidation dependencies 512 for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); 513 pos != end; 514 ++pos) 515 { 516 const uint32_t reg_num = pos->first; 517 518 if (m_regs[reg_num].value_regs) 519 { 520 reg_num_collection extra_invalid_regs; 521 for (const uint32_t invalidate_reg_num : pos->second) 522 { 523 reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num); 524 if (invalidate_pos != m_invalidate_regs_map.end()) 525 { 526 for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second) 527 { 528 if (concrete_invalidate_reg_num != reg_num) 529 extra_invalid_regs.push_back(concrete_invalidate_reg_num); 530 } 531 } 532 } 533 pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end()); 534 } 535 } 536 537 // sort and unique all invalidate registers and make sure each is terminated with 538 // LLDB_INVALID_REGNUM 539 for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); 540 pos != end; 541 ++pos) 542 { 543 if (pos->second.size() > 1) 544 { 545 std::sort (pos->second.begin(), pos->second.end()); 546 reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); 547 if (unique_end != pos->second.end()) 548 pos->second.erase(unique_end, pos->second.end()); 549 } 550 assert (!pos->second.empty()); 551 if (pos->second.back() != LLDB_INVALID_REGNUM) 552 pos->second.push_back(LLDB_INVALID_REGNUM); 553 } 554 555 // Now update all invalidate_regs with each register info as needed 556 for (size_t i=0; i<num_regs; ++i) 557 { 558 if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) 559 m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); 560 else 561 m_regs[i].invalidate_regs = NULL; 562 } 563 } 564 565 size_t 566 DynamicRegisterInfo::GetNumRegisters() const 567 { 568 return m_regs.size(); 569 } 570 571 size_t 572 DynamicRegisterInfo::GetNumRegisterSets() const 573 { 574 return m_sets.size(); 575 } 576 577 size_t 578 DynamicRegisterInfo::GetRegisterDataByteSize() const 579 { 580 return m_reg_data_byte_size; 581 } 582 583 const RegisterInfo * 584 DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const 585 { 586 if (i < m_regs.size()) 587 return &m_regs[i]; 588 return NULL; 589 } 590 591 const RegisterSet * 592 DynamicRegisterInfo::GetRegisterSet (uint32_t i) const 593 { 594 if (i < m_sets.size()) 595 return &m_sets[i]; 596 return NULL; 597 } 598 599 uint32_t 600 DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create) 601 { 602 name_collection::iterator pos, end = m_set_names.end(); 603 for (pos = m_set_names.begin(); pos != end; ++pos) 604 { 605 if (*pos == set_name) 606 return std::distance (m_set_names.begin(), pos); 607 } 608 609 m_set_names.push_back(set_name); 610 m_set_reg_nums.resize(m_set_reg_nums.size()+1); 611 RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; 612 m_sets.push_back (new_set); 613 return m_sets.size() - 1; 614 } 615 616 uint32_t 617 DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const 618 { 619 reg_collection::const_iterator pos, end = m_regs.end(); 620 for (pos = m_regs.begin(); pos != end; ++pos) 621 { 622 if (pos->kinds[kind] == num) 623 return std::distance (m_regs.begin(), pos); 624 } 625 626 return LLDB_INVALID_REGNUM; 627 } 628 629 void 630 DynamicRegisterInfo::Clear() 631 { 632 m_regs.clear(); 633 m_sets.clear(); 634 m_set_reg_nums.clear(); 635 m_set_names.clear(); 636 m_value_regs_map.clear(); 637 m_invalidate_regs_map.clear(); 638 m_reg_data_byte_size = 0; 639 m_finalized = false; 640 } 641 642 void 643 DynamicRegisterInfo::Dump () const 644 { 645 StreamFile s(stdout, false); 646 const size_t num_regs = m_regs.size(); 647 s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " registers:\n", 648 static_cast<const void*>(this), static_cast<uint64_t>(num_regs)); 649 for (size_t i=0; i<num_regs; ++i) 650 { 651 s.Printf("[%3" PRIu64 "] name = %-10s", (uint64_t)i, m_regs[i].name); 652 s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s", 653 m_regs[i].byte_size, 654 m_regs[i].byte_offset, 655 m_regs[i].encoding, 656 FormatManager::GetFormatAsCString (m_regs[i].format)); 657 if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM) 658 s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]); 659 if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) 660 s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]); 661 if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM) 662 s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]); 663 if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) 664 s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]); 665 if (m_regs[i].alt_name) 666 s.Printf(", alt-name = %s", m_regs[i].alt_name); 667 if (m_regs[i].value_regs) 668 { 669 s.Printf(", value_regs = [ "); 670 for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) 671 { 672 s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name); 673 } 674 s.Printf("]"); 675 } 676 if (m_regs[i].invalidate_regs) 677 { 678 s.Printf(", invalidate_regs = [ "); 679 for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j) 680 { 681 s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name); 682 } 683 s.Printf("]"); 684 } 685 s.EOL(); 686 } 687 688 const size_t num_sets = m_sets.size(); 689 s.Printf("%p: DynamicRegisterInfo contains %" PRIu64 " register sets:\n", 690 static_cast<const void*>(this), static_cast<uint64_t>(num_sets)); 691 for (size_t i=0; i<num_sets; ++i) 692 { 693 s.Printf("set[%" PRIu64 "] name = %s, regs = [", (uint64_t)i, m_sets[i].name); 694 for (size_t idx=0; idx<m_sets[i].num_registers; ++idx) 695 { 696 s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name); 697 } 698 s.Printf("]\n"); 699 } 700 } 701 702 703 704 lldb_private::RegisterInfo * 705 DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString ®_name) 706 { 707 for (auto ®_info : m_regs) 708 { 709 // We can use pointer comparison since we used a ConstString to set 710 // the "name" member in AddRegister() 711 if (reg_info.name == reg_name.GetCString()) 712 { 713 return ®_info; 714 } 715 } 716 return NULL; 717 } 718