1 //===-- CompactUnwindInfo.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 11 // C Includes 12 // C++ Includes 13 #include <algorithm> 14 15 #include "lldb/Core/ArchSpec.h" 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/Section.h" 19 #include "lldb/Core/Section.h" 20 #include "lldb/Core/StreamString.h" 21 #include "lldb/Symbol/CompactUnwindInfo.h" 22 #include "lldb/Symbol/ObjectFile.h" 23 #include "lldb/Symbol/UnwindPlan.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Target/Target.h" 26 27 #include "llvm/Support/MathExtras.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 33 namespace lldb_private { 34 35 // Constants from <mach-o/compact_unwind_encoding.h> 36 37 enum { 38 UNWIND_IS_NOT_FUNCTION_START = 0x80000000, 39 UNWIND_HAS_LSDA = 0x40000000, 40 UNWIND_PERSONALITY_MASK = 0x30000000, 41 }; 42 43 enum { 44 UNWIND_X86_MODE_MASK = 0x0F000000, 45 UNWIND_X86_MODE_EBP_FRAME = 0x01000000, 46 UNWIND_X86_MODE_STACK_IMMD = 0x02000000, 47 UNWIND_X86_MODE_STACK_IND = 0x03000000, 48 UNWIND_X86_MODE_DWARF = 0x04000000, 49 50 UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, 51 UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, 52 53 UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, 54 UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, 55 UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, 56 UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, 57 58 UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, 59 }; 60 61 enum { 62 UNWIND_X86_REG_NONE = 0, 63 UNWIND_X86_REG_EBX = 1, 64 UNWIND_X86_REG_ECX = 2, 65 UNWIND_X86_REG_EDX = 3, 66 UNWIND_X86_REG_EDI = 4, 67 UNWIND_X86_REG_ESI = 5, 68 UNWIND_X86_REG_EBP = 6, 69 }; 70 enum { 71 UNWIND_X86_64_MODE_MASK = 0x0F000000, 72 UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, 73 UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, 74 UNWIND_X86_64_MODE_STACK_IND = 0x03000000, 75 UNWIND_X86_64_MODE_DWARF = 0x04000000, 76 77 UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, 78 UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, 79 80 UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, 81 UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, 82 UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, 83 UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, 84 85 UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, 86 }; 87 88 enum { 89 UNWIND_X86_64_REG_NONE = 0, 90 UNWIND_X86_64_REG_RBX = 1, 91 UNWIND_X86_64_REG_R12 = 2, 92 UNWIND_X86_64_REG_R13 = 3, 93 UNWIND_X86_64_REG_R14 = 4, 94 UNWIND_X86_64_REG_R15 = 5, 95 UNWIND_X86_64_REG_RBP = 6, 96 }; 97 }; 98 99 100 #ifndef UNWIND_SECOND_LEVEL_REGULAR 101 #define UNWIND_SECOND_LEVEL_REGULAR 2 102 #endif 103 104 #ifndef UNWIND_SECOND_LEVEL_COMPRESSED 105 #define UNWIND_SECOND_LEVEL_COMPRESSED 3 106 #endif 107 108 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET 109 #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) 110 #endif 111 112 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX 113 #define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) 114 #endif 115 116 #define EXTRACT_BITS(value, mask) \ 117 ( (value >> llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) & \ 118 (((1 << llvm::CountPopulation_32(static_cast<uint32_t>(mask))))-1) ) 119 120 121 122 //---------------------- 123 // constructor 124 //---------------------- 125 126 127 CompactUnwindInfo::CompactUnwindInfo(ObjectFile& objfile, SectionSP& section_sp) : 128 m_objfile (objfile), 129 m_section_sp (section_sp), 130 m_section_contents_if_encrypted (), 131 m_mutex (), 132 m_indexes (), 133 m_indexes_computed (eLazyBoolCalculate), 134 m_unwindinfo_data (), 135 m_unwindinfo_data_computed (false), 136 m_unwind_header () 137 { 138 139 } 140 141 //---------------------- 142 // destructor 143 //---------------------- 144 145 CompactUnwindInfo::~CompactUnwindInfo() 146 { 147 } 148 149 bool 150 CompactUnwindInfo::GetUnwindPlan (Target &target, Address addr, UnwindPlan& unwind_plan) 151 { 152 if (!IsValid (target.GetProcessSP())) 153 { 154 return false; 155 } 156 FunctionInfo function_info; 157 if (GetCompactUnwindInfoForFunction (target, addr, function_info)) 158 { 159 // shortcut return for functions that have no compact unwind 160 if (function_info.encoding == 0) 161 return false; 162 163 ArchSpec arch; 164 if (m_objfile.GetArchitecture (arch)) 165 { 166 167 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); 168 if (log && log->GetVerbose()) 169 { 170 StreamString strm; 171 addr.Dump (&strm, NULL, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize()); 172 log->Printf ("Got compact unwind encoding 0x%x for function %s", function_info.encoding, strm.GetData()); 173 } 174 175 if (function_info.valid_range_offset_start != 0 && function_info.valid_range_offset_end != 0) 176 { 177 SectionList *sl = m_objfile.GetSectionList (); 178 if (sl) 179 { 180 addr_t func_range_start_file_addr = 181 function_info.valid_range_offset_start + m_objfile.GetHeaderAddress().GetFileAddress(); 182 AddressRange func_range (func_range_start_file_addr, 183 function_info.valid_range_offset_end - function_info.valid_range_offset_start, 184 sl); 185 unwind_plan.SetPlanValidAddressRange (func_range); 186 } 187 } 188 189 if (arch.GetTriple().getArch() == llvm::Triple::x86_64) 190 { 191 return CreateUnwindPlan_x86_64 (target, function_info, unwind_plan, addr); 192 } 193 if (arch.GetTriple().getArch() == llvm::Triple::x86) 194 { 195 return CreateUnwindPlan_i386 (target, function_info, unwind_plan, addr); 196 } 197 } 198 } 199 return false; 200 } 201 202 bool 203 CompactUnwindInfo::IsValid (const ProcessSP &process_sp) 204 { 205 if (m_section_sp.get() == nullptr) 206 return false; 207 208 if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed) 209 return true; 210 211 ScanIndex (process_sp); 212 213 return m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed; 214 } 215 216 void 217 CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp) 218 { 219 Mutex::Locker locker(m_mutex); 220 if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed) 221 return; 222 223 // We can't read the index for some reason. 224 if (m_indexes_computed == eLazyBoolNo) 225 { 226 return; 227 } 228 229 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); 230 if (log) 231 m_objfile.GetModule()->LogMessage(log, "Reading compact unwind first-level indexes"); 232 233 if (m_unwindinfo_data_computed == false) 234 { 235 if (m_section_sp->IsEncrypted()) 236 { 237 // Can't get section contents of a protected/encrypted section until we have a live 238 // process and can read them out of memory. 239 if (process_sp.get() == nullptr) 240 return; 241 m_section_contents_if_encrypted.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0)); 242 Error error; 243 if (process_sp->ReadMemory ( 244 m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()), 245 m_section_contents_if_encrypted->GetBytes(), 246 m_section_sp->GetByteSize(), error) == m_section_sp->GetByteSize() && error.Success()) 247 { 248 m_unwindinfo_data.SetAddressByteSize (process_sp->GetTarget().GetArchitecture().GetAddressByteSize()); 249 m_unwindinfo_data.SetByteOrder (process_sp->GetTarget().GetArchitecture().GetByteOrder()); 250 m_unwindinfo_data.SetData (m_section_contents_if_encrypted, 0); 251 } 252 } 253 else 254 { 255 m_objfile.ReadSectionData (m_section_sp.get(), m_unwindinfo_data); 256 } 257 if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize()) 258 return; 259 m_unwindinfo_data_computed = true; 260 } 261 262 if (m_unwindinfo_data.GetByteSize() > 0) 263 { 264 offset_t offset = 0; 265 266 // struct unwind_info_section_header 267 // { 268 // uint32_t version; // UNWIND_SECTION_VERSION 269 // uint32_t commonEncodingsArraySectionOffset; 270 // uint32_t commonEncodingsArrayCount; 271 // uint32_t personalityArraySectionOffset; 272 // uint32_t personalityArrayCount; 273 // uint32_t indexSectionOffset; 274 // uint32_t indexCount; 275 276 m_unwind_header.version = m_unwindinfo_data.GetU32(&offset); 277 m_unwind_header.common_encodings_array_offset = m_unwindinfo_data.GetU32(&offset); 278 m_unwind_header.common_encodings_array_count = m_unwindinfo_data.GetU32(&offset); 279 m_unwind_header.personality_array_offset = m_unwindinfo_data.GetU32(&offset); 280 m_unwind_header.personality_array_count = m_unwindinfo_data.GetU32(&offset); 281 uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset); 282 283 uint32_t indexCount = m_unwindinfo_data.GetU32(&offset); 284 285 if (m_unwind_header.version != 1) 286 { 287 m_indexes_computed = eLazyBoolNo; 288 } 289 290 // Parse the basic information from the indexes 291 // We wait to scan the second level page info until it's needed 292 293 // struct unwind_info_section_header_index_entry 294 // { 295 // uint32_t functionOffset; 296 // uint32_t secondLevelPagesSectionOffset; 297 // uint32_t lsdaIndexArraySectionOffset; 298 // }; 299 300 offset = indexSectionOffset; 301 for (uint32_t idx = 0; idx < indexCount; idx++) 302 { 303 uint32_t function_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset 304 uint32_t second_level_offset = m_unwindinfo_data.GetU32(&offset); // secondLevelPagesSectionOffset 305 uint32_t lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaIndexArraySectionOffset 306 307 if (second_level_offset > m_section_sp->GetByteSize() || lsda_offset > m_section_sp->GetByteSize()) 308 { 309 m_indexes_computed = eLazyBoolNo; 310 } 311 312 UnwindIndex this_index; 313 this_index.function_offset = function_offset; // 314 this_index.second_level = second_level_offset; 315 this_index.lsda_array_start = lsda_offset; 316 317 if (m_indexes.size() > 0) 318 { 319 m_indexes[m_indexes.size() - 1].lsda_array_end = lsda_offset; 320 } 321 322 if (second_level_offset == 0) 323 { 324 this_index.sentinal_entry = true; 325 } 326 327 m_indexes.push_back (this_index); 328 } 329 m_indexes_computed = eLazyBoolYes; 330 } 331 else 332 { 333 m_indexes_computed = eLazyBoolNo; 334 } 335 } 336 337 uint32_t 338 CompactUnwindInfo::GetLSDAForFunctionOffset (uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset) 339 { 340 // struct unwind_info_section_header_lsda_index_entry 341 // { 342 // uint32_t functionOffset; 343 // uint32_t lsdaOffset; 344 // }; 345 346 offset_t first_entry = lsda_offset; 347 uint32_t low = 0; 348 uint32_t high = lsda_count; 349 while (low < high) 350 { 351 uint32_t mid = (low + high) / 2; 352 offset_t offset = first_entry + (mid * 8); 353 uint32_t mid_func_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset 354 uint32_t mid_lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaOffset 355 if (mid_func_offset == function_offset) 356 { 357 return mid_lsda_offset; 358 } 359 if (mid_func_offset < function_offset) 360 { 361 low = mid + 1; 362 } 363 else 364 { 365 high = mid; 366 } 367 } 368 return 0; 369 } 370 371 lldb::offset_t 372 CompactUnwindInfo::BinarySearchRegularSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) 373 { 374 // typedef uint32_t compact_unwind_encoding_t; 375 // struct unwind_info_regular_second_level_entry 376 // { 377 // uint32_t functionOffset; 378 // compact_unwind_encoding_t encoding; 379 380 offset_t first_entry = entry_page_offset; 381 382 uint32_t low = 0; 383 uint32_t high = entry_count; 384 uint32_t last = high - 1; 385 while (low < high) 386 { 387 uint32_t mid = (low + high) / 2; 388 offset_t offset = first_entry + (mid * 8); 389 uint32_t mid_func_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset 390 uint32_t next_func_offset = 0; 391 if (mid < last) 392 { 393 offset = first_entry + ((mid + 1) * 8); 394 next_func_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset 395 } 396 if (mid_func_offset <= function_offset) 397 { 398 if (mid == last || (next_func_offset > function_offset)) 399 { 400 if (entry_func_start_offset) 401 *entry_func_start_offset = mid_func_offset; 402 if (mid != last && entry_func_end_offset) 403 *entry_func_end_offset = next_func_offset; 404 return first_entry + (mid * 8); 405 } 406 else 407 { 408 low = mid + 1; 409 } 410 } 411 else 412 { 413 high = mid; 414 } 415 } 416 return LLDB_INVALID_OFFSET; 417 } 418 419 uint32_t 420 CompactUnwindInfo::BinarySearchCompressedSecondPage (uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset_to_find, uint32_t function_offset_base, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) 421 { 422 offset_t first_entry = entry_page_offset; 423 424 uint32_t low = 0; 425 uint32_t high = entry_count; 426 uint32_t last = high - 1; 427 while (low < high) 428 { 429 uint32_t mid = (low + high) / 2; 430 offset_t offset = first_entry + (mid * 4); 431 uint32_t entry = m_unwindinfo_data.GetU32(&offset); // entry 432 uint32_t mid_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (entry); 433 mid_func_offset += function_offset_base; 434 uint32_t next_func_offset = 0; 435 if (mid < last) 436 { 437 offset = first_entry + ((mid + 1) * 4); 438 uint32_t next_entry = m_unwindinfo_data.GetU32(&offset); // entry 439 next_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET (next_entry); 440 next_func_offset += function_offset_base; 441 } 442 if (mid_func_offset <= function_offset_to_find) 443 { 444 if (mid == last || (next_func_offset > function_offset_to_find)) 445 { 446 if (entry_func_start_offset) 447 *entry_func_start_offset = mid_func_offset; 448 if (mid != last && entry_func_end_offset) 449 *entry_func_end_offset = next_func_offset; 450 return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX (entry); 451 } 452 else 453 { 454 low = mid + 1; 455 } 456 } 457 else 458 { 459 high = mid; 460 } 461 } 462 463 return UINT32_MAX; 464 } 465 466 bool 467 CompactUnwindInfo::GetCompactUnwindInfoForFunction (Target &target, Address address, FunctionInfo &unwind_info) 468 { 469 unwind_info.encoding = 0; 470 unwind_info.lsda_address.Clear(); 471 unwind_info.personality_ptr_address.Clear(); 472 473 if (!IsValid (target.GetProcessSP())) 474 return false; 475 476 addr_t text_section_file_address = LLDB_INVALID_ADDRESS; 477 SectionList *sl = m_objfile.GetSectionList (); 478 if (sl) 479 { 480 SectionSP text_sect = sl->FindSectionByType (eSectionTypeCode, true); 481 if (text_sect.get()) 482 { 483 text_section_file_address = text_sect->GetFileAddress(); 484 } 485 } 486 if (text_section_file_address == LLDB_INVALID_ADDRESS) 487 return false; 488 489 addr_t function_offset = address.GetFileAddress() - m_objfile.GetHeaderAddress().GetFileAddress(); 490 491 UnwindIndex key; 492 key.function_offset = function_offset; 493 494 std::vector<UnwindIndex>::const_iterator it; 495 it = std::lower_bound (m_indexes.begin(), m_indexes.end(), key); 496 if (it == m_indexes.end()) 497 { 498 return false; 499 } 500 501 if (it->function_offset != key.function_offset) 502 { 503 if (it != m_indexes.begin()) 504 --it; 505 } 506 507 if (it->sentinal_entry == true) 508 { 509 return false; 510 } 511 512 auto next_it = it + 1; 513 if (next_it != m_indexes.begin()) 514 { 515 // initialize the function offset end range to be the start of the 516 // next index offset. If we find an entry which is at the end of 517 // the index table, this will establish the range end. 518 unwind_info.valid_range_offset_end = next_it->function_offset; 519 } 520 521 offset_t second_page_offset = it->second_level; 522 offset_t lsda_array_start = it->lsda_array_start; 523 offset_t lsda_array_count = (it->lsda_array_end - it->lsda_array_start) / 8; 524 525 offset_t offset = second_page_offset; 526 uint32_t kind = m_unwindinfo_data.GetU32(&offset); // UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED 527 528 if (kind == UNWIND_SECOND_LEVEL_REGULAR) 529 { 530 // struct unwind_info_regular_second_level_page_header 531 // { 532 // uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR 533 // uint16_t entryPageOffset; 534 // uint16_t entryCount; 535 536 // typedef uint32_t compact_unwind_encoding_t; 537 // struct unwind_info_regular_second_level_entry 538 // { 539 // uint32_t functionOffset; 540 // compact_unwind_encoding_t encoding; 541 542 uint16_t entry_page_offset = m_unwindinfo_data.GetU16(&offset); // entryPageOffset 543 uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount 544 545 offset_t entry_offset = BinarySearchRegularSecondPage (second_page_offset + entry_page_offset, entry_count, function_offset, &unwind_info.valid_range_offset_start, &unwind_info.valid_range_offset_end); 546 if (entry_offset == LLDB_INVALID_OFFSET) 547 { 548 return false; 549 } 550 entry_offset += 4; // skip over functionOffset 551 unwind_info.encoding = m_unwindinfo_data.GetU32(&entry_offset); // encoding 552 if (unwind_info.encoding & UNWIND_HAS_LSDA) 553 { 554 SectionList *sl = m_objfile.GetSectionList (); 555 if (sl) 556 { 557 uint32_t lsda_offset = GetLSDAForFunctionOffset (lsda_array_start, lsda_array_count, function_offset); 558 addr_t objfile_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress(); 559 unwind_info.lsda_address.ResolveAddressUsingFileSections (objfile_header_file_address + lsda_offset, sl); 560 } 561 } 562 if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) 563 { 564 uint32_t personality_index = EXTRACT_BITS (unwind_info.encoding, UNWIND_PERSONALITY_MASK); 565 566 if (personality_index > 0) 567 { 568 personality_index--; 569 if (personality_index < m_unwind_header.personality_array_count) 570 { 571 offset_t offset = m_unwind_header.personality_array_offset; 572 offset += 4 * personality_index; 573 SectionList *sl = m_objfile.GetSectionList (); 574 if (sl) 575 { 576 uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset); 577 addr_t objfile_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress(); 578 unwind_info.personality_ptr_address.ResolveAddressUsingFileSections (objfile_header_file_address + personality_offset, sl); 579 } 580 } 581 } 582 } 583 return true; 584 } 585 else if (kind == UNWIND_SECOND_LEVEL_COMPRESSED) 586 { 587 // struct unwind_info_compressed_second_level_page_header 588 // { 589 // uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED 590 // uint16_t entryPageOffset; // offset from this 2nd lvl page idx to array of entries 591 // // (an entry has a function offset and index into the encodings) 592 // // NB function offset from the entry in the compressed page 593 // // must be added to the index's functionOffset value. 594 // uint16_t entryCount; 595 // uint16_t encodingsPageOffset; // offset from this 2nd lvl page idx to array of encodings 596 // uint16_t encodingsCount; 597 598 uint16_t entry_page_offset = m_unwindinfo_data.GetU16(&offset); // entryPageOffset 599 uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount 600 uint16_t encodings_page_offset = m_unwindinfo_data.GetU16(&offset); // encodingsPageOffset 601 uint16_t encodings_count = m_unwindinfo_data.GetU16(&offset); // encodingsCount 602 603 uint32_t encoding_index = BinarySearchCompressedSecondPage (second_page_offset + entry_page_offset, entry_count, function_offset, it->function_offset, &unwind_info.valid_range_offset_start, &unwind_info.valid_range_offset_end); 604 if (encoding_index == UINT32_MAX || encoding_index >= encodings_count + m_unwind_header.common_encodings_array_count) 605 { 606 return false; 607 } 608 uint32_t encoding = 0; 609 if (encoding_index < m_unwind_header.common_encodings_array_count) 610 { 611 offset = m_unwind_header.common_encodings_array_offset + (encoding_index * sizeof (uint32_t)); 612 encoding = m_unwindinfo_data.GetU32(&offset); // encoding entry from the commonEncodingsArray 613 } 614 else 615 { 616 uint32_t page_specific_entry_index = encoding_index - m_unwind_header.common_encodings_array_count; 617 offset = second_page_offset + encodings_page_offset + (page_specific_entry_index * sizeof (uint32_t)); 618 encoding = m_unwindinfo_data.GetU32(&offset); // encoding entry from the page-specific encoding array 619 } 620 if (encoding == 0) 621 return false; 622 623 unwind_info.encoding = encoding; 624 if (unwind_info.encoding & UNWIND_HAS_LSDA) 625 { 626 SectionList *sl = m_objfile.GetSectionList (); 627 if (sl) 628 { 629 uint32_t lsda_offset = GetLSDAForFunctionOffset (lsda_array_start, lsda_array_count, function_offset); 630 addr_t objfile_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress(); 631 unwind_info.lsda_address.ResolveAddressUsingFileSections (objfile_header_file_address + lsda_offset, sl); 632 } 633 } 634 if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) 635 { 636 uint32_t personality_index = EXTRACT_BITS (unwind_info.encoding, UNWIND_PERSONALITY_MASK); 637 638 if (personality_index > 0) 639 { 640 personality_index--; 641 if (personality_index < m_unwind_header.personality_array_count) 642 { 643 offset_t offset = m_unwind_header.personality_array_offset; 644 offset += 4 * personality_index; 645 SectionList *sl = m_objfile.GetSectionList (); 646 if (sl) 647 { 648 uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset); 649 addr_t objfile_header_file_address = m_objfile.GetHeaderAddress().GetFileAddress(); 650 unwind_info.personality_ptr_address.ResolveAddressUsingFileSections (objfile_header_file_address + personality_offset, sl); 651 } 652 } 653 } 654 } 655 return true; 656 } 657 return false; 658 } 659 660 enum x86_64_eh_regnum { 661 rax = 0, 662 rdx = 1, 663 rcx = 2, 664 rbx = 3, 665 rsi = 4, 666 rdi = 5, 667 rbp = 6, 668 rsp = 7, 669 r8 = 8, 670 r9 = 9, 671 r10 = 10, 672 r11 = 11, 673 r12 = 12, 674 r13 = 13, 675 r14 = 14, 676 r15 = 15, 677 rip = 16 // this is officially the Return Address register number, but close enough 678 }; 679 680 // Convert the compact_unwind_info.h register numbering scheme 681 // to eRegisterKindGCC (eh_frame) register numbering scheme. 682 uint32_t 683 translate_to_eh_frame_regnum_x86_64 (uint32_t unwind_regno) 684 { 685 switch (unwind_regno) 686 { 687 case UNWIND_X86_64_REG_RBX: 688 return x86_64_eh_regnum::rbx; 689 case UNWIND_X86_64_REG_R12: 690 return x86_64_eh_regnum::r12; 691 case UNWIND_X86_64_REG_R13: 692 return x86_64_eh_regnum::r13; 693 case UNWIND_X86_64_REG_R14: 694 return x86_64_eh_regnum::r14; 695 case UNWIND_X86_64_REG_R15: 696 return x86_64_eh_regnum::r15; 697 case UNWIND_X86_64_REG_RBP: 698 return x86_64_eh_regnum::rbp; 699 default: 700 return LLDB_INVALID_REGNUM; 701 } 702 } 703 704 bool 705 CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start) 706 { 707 unwind_plan.SetSourceName ("compact unwind info"); 708 unwind_plan.SetSourcedFromCompiler (eLazyBoolYes); 709 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 710 unwind_plan.SetRegisterKind (eRegisterKindGCC); 711 712 unwind_plan.SetLSDAAddress (function_info.lsda_address); 713 unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address); 714 715 UnwindPlan::RowSP row (new UnwindPlan::Row); 716 717 const int wordsize = 8; 718 int mode = function_info.encoding & UNWIND_X86_64_MODE_MASK; 719 switch (mode) 720 { 721 case UNWIND_X86_64_MODE_RBP_FRAME: 722 { 723 row->SetCFARegister (translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP)); 724 row->SetCFAOffset (2 * wordsize); 725 row->SetOffset (0); 726 row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true); 727 row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); 728 row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); 729 730 uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET); 731 732 uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS); 733 734 saved_registers_offset += 2; 735 736 for (int i = 0; i < 5; i++) 737 { 738 uint32_t regnum = saved_registers_locations & 0x7; 739 switch (regnum) 740 { 741 case UNWIND_X86_64_REG_NONE: 742 break; 743 case UNWIND_X86_64_REG_RBX: 744 case UNWIND_X86_64_REG_R12: 745 case UNWIND_X86_64_REG_R13: 746 case UNWIND_X86_64_REG_R14: 747 case UNWIND_X86_64_REG_R15: 748 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (regnum), wordsize * -saved_registers_offset, true); 749 break; 750 } 751 saved_registers_offset--; 752 saved_registers_locations >>= 3; 753 } 754 unwind_plan.AppendRow (row); 755 return true; 756 } 757 break; 758 759 case UNWIND_X86_64_MODE_STACK_IND: 760 { 761 // The clang in Xcode 6 is emitting incorrect compact unwind encodings for this 762 // style of unwind. It was fixed in llvm r217020. 763 return false; 764 } 765 break; 766 767 case UNWIND_X86_64_MODE_STACK_IMMD: 768 { 769 uint32_t stack_size = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); 770 uint32_t register_count = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT); 771 uint32_t permutation = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION); 772 773 if (mode == UNWIND_X86_64_MODE_STACK_IND && function_info.valid_range_offset_start != 0) 774 { 775 uint32_t stack_adjust = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST); 776 777 // offset into the function instructions; 0 == beginning of first instruction 778 uint32_t offset_to_subl_insn = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); 779 780 SectionList *sl = m_objfile.GetSectionList (); 781 if (sl) 782 { 783 ProcessSP process_sp = target.GetProcessSP(); 784 if (process_sp) 785 { 786 Address subl_payload_addr (function_info.valid_range_offset_start, sl); 787 subl_payload_addr.Slide (offset_to_subl_insn); 788 Error error; 789 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory (subl_payload_addr.GetLoadAddress (&target), 790 4, 0, error); 791 if (large_stack_size != 0 && error.Success ()) 792 { 793 // Got the large stack frame size correctly - use it 794 stack_size = large_stack_size + (stack_adjust * wordsize); 795 } 796 else 797 { 798 return false; 799 } 800 } 801 else 802 { 803 return false; 804 } 805 } 806 else 807 { 808 return false; 809 } 810 } 811 812 if (mode == UNWIND_X86_64_MODE_STACK_IND) 813 { 814 row->SetCFAOffset (stack_size); 815 } 816 else 817 { 818 row->SetCFAOffset (stack_size * wordsize); 819 } 820 821 row->SetCFARegister (x86_64_eh_regnum::rsp); 822 row->SetOffset (0); 823 row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); 824 row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); 825 826 if (register_count > 0) 827 { 828 829 // We need to include (up to) 6 registers in 10 bits. 830 // That would be 18 bits if we just used 3 bits per reg to indicate 831 // the order they're saved on the stack. 832 // 833 // This is done with Lehmer code permutation, e.g. see 834 // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms 835 int permunreg[6]; 836 837 // This decodes the variable-base number in the 10 bits 838 // and gives us the Lehmer code sequence which can then 839 // be decoded. 840 841 switch (register_count) 842 { 843 case 6: 844 permunreg[0] = permutation/120; // 120 == 5! 845 permutation -= (permunreg[0]*120); 846 permunreg[1] = permutation/24; // 24 == 4! 847 permutation -= (permunreg[1]*24); 848 permunreg[2] = permutation/6; // 6 == 3! 849 permutation -= (permunreg[2]*6); 850 permunreg[3] = permutation/2; // 2 == 2! 851 permutation -= (permunreg[3]*2); 852 permunreg[4] = permutation; // 1 == 1! 853 permunreg[5] = 0; 854 break; 855 case 5: 856 permunreg[0] = permutation/120; 857 permutation -= (permunreg[0]*120); 858 permunreg[1] = permutation/24; 859 permutation -= (permunreg[1]*24); 860 permunreg[2] = permutation/6; 861 permutation -= (permunreg[2]*6); 862 permunreg[3] = permutation/2; 863 permutation -= (permunreg[3]*2); 864 permunreg[4] = permutation; 865 break; 866 case 4: 867 permunreg[0] = permutation/60; 868 permutation -= (permunreg[0]*60); 869 permunreg[1] = permutation/12; 870 permutation -= (permunreg[1]*12); 871 permunreg[2] = permutation/3; 872 permutation -= (permunreg[2]*3); 873 permunreg[3] = permutation; 874 break; 875 case 3: 876 permunreg[0] = permutation/20; 877 permutation -= (permunreg[0]*20); 878 permunreg[1] = permutation/4; 879 permutation -= (permunreg[1]*4); 880 permunreg[2] = permutation; 881 break; 882 case 2: 883 permunreg[0] = permutation/5; 884 permutation -= (permunreg[0]*5); 885 permunreg[1] = permutation; 886 break; 887 case 1: 888 permunreg[0] = permutation; 889 break; 890 } 891 892 // Decode the Lehmer code for this permutation of 893 // the registers v. http://en.wikipedia.org/wiki/Lehmer_code 894 895 int registers[6]; 896 bool used[7] = { false, false, false, false, false, false, false }; 897 for (uint32_t i = 0; i < register_count; i++) 898 { 899 int renum = 0; 900 for (int j = 1; j < 7; j++) 901 { 902 if (used[j] == false) 903 { 904 if (renum == permunreg[i]) 905 { 906 registers[i] = j; 907 used[j] = true; 908 break; 909 } 910 renum++; 911 } 912 } 913 } 914 915 uint32_t saved_registers_offset = 1; 916 saved_registers_offset++; 917 918 for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--) 919 { 920 switch (registers[i]) 921 { 922 case UNWIND_X86_64_REG_NONE: 923 break; 924 case UNWIND_X86_64_REG_RBX: 925 case UNWIND_X86_64_REG_R12: 926 case UNWIND_X86_64_REG_R13: 927 case UNWIND_X86_64_REG_R14: 928 case UNWIND_X86_64_REG_R15: 929 case UNWIND_X86_64_REG_RBP: 930 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (registers[i]), wordsize * -saved_registers_offset, true); 931 saved_registers_offset++; 932 break; 933 } 934 } 935 } 936 unwind_plan.AppendRow (row); 937 return true; 938 } 939 break; 940 941 case UNWIND_X86_64_MODE_DWARF: 942 { 943 return false; 944 } 945 break; 946 947 case 0: 948 { 949 return false; 950 } 951 break; 952 } 953 return false; 954 } 955 956 enum i386_eh_regnum { 957 eax = 0, 958 ecx = 1, 959 edx = 2, 960 ebx = 3, 961 ebp = 4, 962 esp = 5, 963 esi = 6, 964 edi = 7, 965 eip = 8 // this is officially the Return Address register number, but close enough 966 }; 967 968 // Convert the compact_unwind_info.h register numbering scheme 969 // to eRegisterKindGCC (eh_frame) register numbering scheme. 970 uint32_t 971 translate_to_eh_frame_regnum_i386 (uint32_t unwind_regno) 972 { 973 switch (unwind_regno) 974 { 975 case UNWIND_X86_REG_EBX: 976 return i386_eh_regnum::ebx; 977 case UNWIND_X86_REG_ECX: 978 return i386_eh_regnum::ecx; 979 case UNWIND_X86_REG_EDX: 980 return i386_eh_regnum::edx; 981 case UNWIND_X86_REG_EDI: 982 return i386_eh_regnum::edi; 983 case UNWIND_X86_REG_ESI: 984 return i386_eh_regnum::esi; 985 case UNWIND_X86_REG_EBP: 986 return i386_eh_regnum::ebp; 987 default: 988 return LLDB_INVALID_REGNUM; 989 } 990 } 991 992 993 bool 994 CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start) 995 { 996 unwind_plan.SetSourceName ("compact unwind info"); 997 unwind_plan.SetSourcedFromCompiler (eLazyBoolYes); 998 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 999 unwind_plan.SetRegisterKind (eRegisterKindGCC); 1000 1001 unwind_plan.SetLSDAAddress (function_info.lsda_address); 1002 unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address); 1003 1004 UnwindPlan::RowSP row (new UnwindPlan::Row); 1005 1006 const int wordsize = 4; 1007 int mode = function_info.encoding & UNWIND_X86_MODE_MASK; 1008 switch (mode) 1009 { 1010 case UNWIND_X86_MODE_EBP_FRAME: 1011 { 1012 row->SetCFARegister (translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP)); 1013 row->SetCFAOffset (2 * wordsize); 1014 row->SetOffset (0); 1015 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true); 1016 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); 1017 row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true); 1018 1019 uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET); 1020 1021 uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS); 1022 1023 saved_registers_offset += 2; 1024 1025 for (int i = 0; i < 5; i++) 1026 { 1027 uint32_t regnum = saved_registers_locations & 0x7; 1028 switch (regnum) 1029 { 1030 case UNWIND_X86_REG_NONE: 1031 break; 1032 case UNWIND_X86_REG_EBX: 1033 case UNWIND_X86_REG_ECX: 1034 case UNWIND_X86_REG_EDX: 1035 case UNWIND_X86_REG_EDI: 1036 case UNWIND_X86_REG_ESI: 1037 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (regnum), wordsize * -saved_registers_offset, true); 1038 break; 1039 } 1040 saved_registers_offset--; 1041 saved_registers_locations >>= 3; 1042 } 1043 unwind_plan.AppendRow (row); 1044 return true; 1045 } 1046 break; 1047 1048 case UNWIND_X86_MODE_STACK_IND: 1049 case UNWIND_X86_MODE_STACK_IMMD: 1050 { 1051 uint32_t stack_size = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); 1052 uint32_t register_count = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT); 1053 uint32_t permutation = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION); 1054 1055 if (mode == UNWIND_X86_MODE_STACK_IND && function_info.valid_range_offset_start != 0) 1056 { 1057 uint32_t stack_adjust = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST); 1058 1059 // offset into the function instructions; 0 == beginning of first instruction 1060 uint32_t offset_to_subl_insn = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); 1061 1062 SectionList *sl = m_objfile.GetSectionList (); 1063 if (sl) 1064 { 1065 ProcessSP process_sp = target.GetProcessSP(); 1066 if (process_sp) 1067 { 1068 Address subl_payload_addr (function_info.valid_range_offset_start, sl); 1069 subl_payload_addr.Slide (offset_to_subl_insn); 1070 Error error; 1071 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory (subl_payload_addr.GetLoadAddress (&target), 1072 4, 0, error); 1073 if (large_stack_size != 0 && error.Success ()) 1074 { 1075 // Got the large stack frame size correctly - use it 1076 stack_size = large_stack_size + (stack_adjust * wordsize); 1077 } 1078 else 1079 { 1080 return false; 1081 } 1082 } 1083 else 1084 { 1085 return false; 1086 } 1087 } 1088 else 1089 { 1090 return false; 1091 } 1092 } 1093 1094 row->SetCFARegister (i386_eh_regnum::esp); 1095 1096 if (mode == UNWIND_X86_MODE_STACK_IND) 1097 { 1098 row->SetCFAOffset (stack_size); 1099 } 1100 else 1101 { 1102 row->SetCFAOffset (stack_size * wordsize); 1103 } 1104 1105 row->SetOffset (0); 1106 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); 1107 row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true); 1108 1109 if (register_count > 0) 1110 { 1111 1112 // We need to include (up to) 6 registers in 10 bits. 1113 // That would be 18 bits if we just used 3 bits per reg to indicate 1114 // the order they're saved on the stack. 1115 // 1116 // This is done with Lehmer code permutation, e.g. see 1117 // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms 1118 int permunreg[6]; 1119 1120 // This decodes the variable-base number in the 10 bits 1121 // and gives us the Lehmer code sequence which can then 1122 // be decoded. 1123 1124 switch (register_count) 1125 { 1126 case 6: 1127 permunreg[0] = permutation/120; // 120 == 5! 1128 permutation -= (permunreg[0]*120); 1129 permunreg[1] = permutation/24; // 24 == 4! 1130 permutation -= (permunreg[1]*24); 1131 permunreg[2] = permutation/6; // 6 == 3! 1132 permutation -= (permunreg[2]*6); 1133 permunreg[3] = permutation/2; // 2 == 2! 1134 permutation -= (permunreg[3]*2); 1135 permunreg[4] = permutation; // 1 == 1! 1136 permunreg[5] = 0; 1137 break; 1138 case 5: 1139 permunreg[0] = permutation/120; 1140 permutation -= (permunreg[0]*120); 1141 permunreg[1] = permutation/24; 1142 permutation -= (permunreg[1]*24); 1143 permunreg[2] = permutation/6; 1144 permutation -= (permunreg[2]*6); 1145 permunreg[3] = permutation/2; 1146 permutation -= (permunreg[3]*2); 1147 permunreg[4] = permutation; 1148 break; 1149 case 4: 1150 permunreg[0] = permutation/60; 1151 permutation -= (permunreg[0]*60); 1152 permunreg[1] = permutation/12; 1153 permutation -= (permunreg[1]*12); 1154 permunreg[2] = permutation/3; 1155 permutation -= (permunreg[2]*3); 1156 permunreg[3] = permutation; 1157 break; 1158 case 3: 1159 permunreg[0] = permutation/20; 1160 permutation -= (permunreg[0]*20); 1161 permunreg[1] = permutation/4; 1162 permutation -= (permunreg[1]*4); 1163 permunreg[2] = permutation; 1164 break; 1165 case 2: 1166 permunreg[0] = permutation/5; 1167 permutation -= (permunreg[0]*5); 1168 permunreg[1] = permutation; 1169 break; 1170 case 1: 1171 permunreg[0] = permutation; 1172 break; 1173 } 1174 1175 // Decode the Lehmer code for this permutation of 1176 // the registers v. http://en.wikipedia.org/wiki/Lehmer_code 1177 1178 int registers[6]; 1179 bool used[7] = { false, false, false, false, false, false, false }; 1180 for (uint32_t i = 0; i < register_count; i++) 1181 { 1182 int renum = 0; 1183 for (int j = 1; j < 7; j++) 1184 { 1185 if (used[j] == false) 1186 { 1187 if (renum == permunreg[i]) 1188 { 1189 registers[i] = j; 1190 used[j] = true; 1191 break; 1192 } 1193 renum++; 1194 } 1195 } 1196 } 1197 1198 uint32_t saved_registers_offset = 1; 1199 saved_registers_offset++; 1200 1201 for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--) 1202 { 1203 switch (registers[i]) 1204 { 1205 case UNWIND_X86_REG_NONE: 1206 break; 1207 case UNWIND_X86_REG_EBX: 1208 case UNWIND_X86_REG_ECX: 1209 case UNWIND_X86_REG_EDX: 1210 case UNWIND_X86_REG_EDI: 1211 case UNWIND_X86_REG_ESI: 1212 case UNWIND_X86_REG_EBP: 1213 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (registers[i]), wordsize * -saved_registers_offset, true); 1214 saved_registers_offset++; 1215 break; 1216 } 1217 } 1218 } 1219 1220 unwind_plan.AppendRow (row); 1221 return true; 1222 } 1223 break; 1224 1225 case UNWIND_X86_MODE_DWARF: 1226 { 1227 return false; 1228 } 1229 break; 1230 } 1231 return false; 1232 } 1233