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