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 (int 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 row->SetCFARegister (x86_64_eh_regnum::rsp); 813 row->SetCFAOffset (stack_size * wordsize); 814 row->SetOffset (0); 815 row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); 816 row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); 817 818 if (register_count > 0) 819 { 820 821 // We need to include (up to) 6 registers in 10 bits. 822 // That would be 18 bits if we just used 3 bits per reg to indicate 823 // the order they're saved on the stack. 824 // 825 // This is done with Lehmer code permutation, e.g. see 826 // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms 827 int permunreg[6]; 828 829 // This decodes the variable-base number in the 10 bits 830 // and gives us the Lehmer code sequence which can then 831 // be decoded. 832 833 switch (register_count) 834 { 835 case 6: 836 permunreg[0] = permutation/120; // 120 == 5! 837 permutation -= (permunreg[0]*120); 838 permunreg[1] = permutation/24; // 24 == 4! 839 permutation -= (permunreg[1]*24); 840 permunreg[2] = permutation/6; // 6 == 3! 841 permutation -= (permunreg[2]*6); 842 permunreg[3] = permutation/2; // 2 == 2! 843 permutation -= (permunreg[3]*2); 844 permunreg[4] = permutation; // 1 == 1! 845 permunreg[5] = 0; 846 break; 847 case 5: 848 permunreg[0] = permutation/120; 849 permutation -= (permunreg[0]*120); 850 permunreg[1] = permutation/24; 851 permutation -= (permunreg[1]*24); 852 permunreg[2] = permutation/6; 853 permutation -= (permunreg[2]*6); 854 permunreg[3] = permutation/2; 855 permutation -= (permunreg[3]*2); 856 permunreg[4] = permutation; 857 break; 858 case 4: 859 permunreg[0] = permutation/60; 860 permutation -= (permunreg[0]*60); 861 permunreg[1] = permutation/12; 862 permutation -= (permunreg[1]*12); 863 permunreg[2] = permutation/3; 864 permutation -= (permunreg[2]*3); 865 permunreg[3] = permutation; 866 break; 867 case 3: 868 permunreg[0] = permutation/20; 869 permutation -= (permunreg[0]*20); 870 permunreg[1] = permutation/4; 871 permutation -= (permunreg[1]*4); 872 permunreg[2] = permutation; 873 break; 874 case 2: 875 permunreg[0] = permutation/5; 876 permutation -= (permunreg[0]*5); 877 permunreg[1] = permutation; 878 break; 879 case 1: 880 permunreg[0] = permutation; 881 break; 882 } 883 884 // Decode the Lehmer code for this permutation of 885 // the registers v. http://en.wikipedia.org/wiki/Lehmer_code 886 887 int registers[6]; 888 bool used[7] = { false, false, false, false, false, false, false }; 889 for (int i = 0; i < register_count; i++) 890 { 891 int renum = 0; 892 for (int j = 1; j < 7; j++) 893 { 894 if (used[j] == false) 895 { 896 if (renum == permunreg[i]) 897 { 898 registers[i] = j; 899 used[j] = true; 900 break; 901 } 902 renum++; 903 } 904 } 905 } 906 907 uint32_t saved_registers_offset = 1; 908 saved_registers_offset++; 909 910 for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--) 911 { 912 switch (registers[i]) 913 { 914 case UNWIND_X86_64_REG_NONE: 915 break; 916 case UNWIND_X86_64_REG_RBX: 917 case UNWIND_X86_64_REG_R12: 918 case UNWIND_X86_64_REG_R13: 919 case UNWIND_X86_64_REG_R14: 920 case UNWIND_X86_64_REG_R15: 921 case UNWIND_X86_64_REG_RBP: 922 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (registers[i]), wordsize * -saved_registers_offset, true); 923 break; 924 } 925 saved_registers_offset++; 926 } 927 } 928 unwind_plan.AppendRow (row); 929 return true; 930 } 931 break; 932 933 case UNWIND_X86_64_MODE_DWARF: 934 { 935 return false; 936 } 937 break; 938 939 case 0: 940 { 941 return false; 942 } 943 break; 944 } 945 return false; 946 } 947 948 enum i386_eh_regnum { 949 eax = 0, 950 ecx = 1, 951 edx = 2, 952 ebx = 3, 953 ebp = 4, 954 esp = 5, 955 esi = 6, 956 edi = 7, 957 eip = 8 // this is officially the Return Address register number, but close enough 958 }; 959 960 // Convert the compact_unwind_info.h register numbering scheme 961 // to eRegisterKindGCC (eh_frame) register numbering scheme. 962 uint32_t 963 translate_to_eh_frame_regnum_i386 (uint32_t unwind_regno) 964 { 965 switch (unwind_regno) 966 { 967 case UNWIND_X86_REG_EBX: 968 return i386_eh_regnum::ebx; 969 case UNWIND_X86_REG_ECX: 970 return i386_eh_regnum::ecx; 971 case UNWIND_X86_REG_EDX: 972 return i386_eh_regnum::edx; 973 case UNWIND_X86_REG_EDI: 974 return i386_eh_regnum::edi; 975 case UNWIND_X86_REG_ESI: 976 return i386_eh_regnum::esi; 977 case UNWIND_X86_REG_EBP: 978 return i386_eh_regnum::ebp; 979 default: 980 return LLDB_INVALID_REGNUM; 981 } 982 } 983 984 985 bool 986 CompactUnwindInfo::CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start) 987 { 988 unwind_plan.SetSourceName ("compact unwind info"); 989 unwind_plan.SetSourcedFromCompiler (eLazyBoolYes); 990 unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); 991 unwind_plan.SetRegisterKind (eRegisterKindGCC); 992 993 unwind_plan.SetLSDAAddress (function_info.lsda_address); 994 unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address); 995 996 UnwindPlan::RowSP row (new UnwindPlan::Row); 997 998 const int wordsize = 4; 999 int mode = function_info.encoding & UNWIND_X86_MODE_MASK; 1000 switch (mode) 1001 { 1002 case UNWIND_X86_MODE_EBP_FRAME: 1003 { 1004 row->SetCFARegister (translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP)); 1005 row->SetCFAOffset (2 * wordsize); 1006 row->SetOffset (0); 1007 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true); 1008 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); 1009 row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true); 1010 1011 uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET); 1012 1013 uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS); 1014 1015 saved_registers_offset += 2; 1016 1017 for (int i = 0; i < 5; i++) 1018 { 1019 uint32_t regnum = saved_registers_locations & 0x7; 1020 switch (regnum) 1021 { 1022 case UNWIND_X86_REG_NONE: 1023 break; 1024 case UNWIND_X86_REG_EBX: 1025 case UNWIND_X86_REG_ECX: 1026 case UNWIND_X86_REG_EDX: 1027 case UNWIND_X86_REG_EDI: 1028 case UNWIND_X86_REG_ESI: 1029 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (regnum), wordsize * -saved_registers_offset, true); 1030 break; 1031 } 1032 saved_registers_offset--; 1033 saved_registers_locations >>= 3; 1034 } 1035 unwind_plan.AppendRow (row); 1036 return true; 1037 } 1038 break; 1039 1040 case UNWIND_X86_MODE_STACK_IND: 1041 case UNWIND_X86_MODE_STACK_IMMD: 1042 { 1043 uint32_t stack_size = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); 1044 uint32_t register_count = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT); 1045 uint32_t permutation = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION); 1046 1047 if (mode == UNWIND_X86_MODE_STACK_IND && function_info.valid_range_offset_start != 0) 1048 { 1049 uint32_t stack_adjust = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_ADJUST); 1050 1051 // offset into the function instructions; 0 == beginning of first instruction 1052 uint32_t offset_to_subl_insn = EXTRACT_BITS (function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE); 1053 1054 SectionList *sl = m_objfile.GetSectionList (); 1055 if (sl) 1056 { 1057 ProcessSP process_sp = target.GetProcessSP(); 1058 if (process_sp) 1059 { 1060 Address subl_payload_addr (function_info.valid_range_offset_start, sl); 1061 subl_payload_addr.Slide (offset_to_subl_insn); 1062 Error error; 1063 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory (subl_payload_addr.GetLoadAddress (&target), 1064 4, 0, error); 1065 if (large_stack_size != 0 && error.Success ()) 1066 { 1067 // Got the large stack frame size correctly - use it 1068 stack_size = large_stack_size + (stack_adjust * wordsize); 1069 } 1070 else 1071 { 1072 return false; 1073 } 1074 } 1075 else 1076 { 1077 return false; 1078 } 1079 } 1080 else 1081 { 1082 return false; 1083 } 1084 } 1085 1086 row->SetCFARegister (i386_eh_regnum::esp); 1087 row->SetCFAOffset (stack_size * wordsize); 1088 row->SetOffset (0); 1089 row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true); 1090 row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true); 1091 1092 if (register_count > 0) 1093 { 1094 1095 // We need to include (up to) 6 registers in 10 bits. 1096 // That would be 18 bits if we just used 3 bits per reg to indicate 1097 // the order they're saved on the stack. 1098 // 1099 // This is done with Lehmer code permutation, e.g. see 1100 // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms 1101 int permunreg[6]; 1102 1103 // This decodes the variable-base number in the 10 bits 1104 // and gives us the Lehmer code sequence which can then 1105 // be decoded. 1106 1107 switch (register_count) 1108 { 1109 case 6: 1110 permunreg[0] = permutation/120; // 120 == 5! 1111 permutation -= (permunreg[0]*120); 1112 permunreg[1] = permutation/24; // 24 == 4! 1113 permutation -= (permunreg[1]*24); 1114 permunreg[2] = permutation/6; // 6 == 3! 1115 permutation -= (permunreg[2]*6); 1116 permunreg[3] = permutation/2; // 2 == 2! 1117 permutation -= (permunreg[3]*2); 1118 permunreg[4] = permutation; // 1 == 1! 1119 permunreg[5] = 0; 1120 break; 1121 case 5: 1122 permunreg[0] = permutation/120; 1123 permutation -= (permunreg[0]*120); 1124 permunreg[1] = permutation/24; 1125 permutation -= (permunreg[1]*24); 1126 permunreg[2] = permutation/6; 1127 permutation -= (permunreg[2]*6); 1128 permunreg[3] = permutation/2; 1129 permutation -= (permunreg[3]*2); 1130 permunreg[4] = permutation; 1131 break; 1132 case 4: 1133 permunreg[0] = permutation/60; 1134 permutation -= (permunreg[0]*60); 1135 permunreg[1] = permutation/12; 1136 permutation -= (permunreg[1]*12); 1137 permunreg[2] = permutation/3; 1138 permutation -= (permunreg[2]*3); 1139 permunreg[3] = permutation; 1140 break; 1141 case 3: 1142 permunreg[0] = permutation/20; 1143 permutation -= (permunreg[0]*20); 1144 permunreg[1] = permutation/4; 1145 permutation -= (permunreg[1]*4); 1146 permunreg[2] = permutation; 1147 break; 1148 case 2: 1149 permunreg[0] = permutation/5; 1150 permutation -= (permunreg[0]*5); 1151 permunreg[1] = permutation; 1152 break; 1153 case 1: 1154 permunreg[0] = permutation; 1155 break; 1156 } 1157 1158 // Decode the Lehmer code for this permutation of 1159 // the registers v. http://en.wikipedia.org/wiki/Lehmer_code 1160 1161 int registers[6]; 1162 bool used[7] = { false, false, false, false, false, false, false }; 1163 for (int i = 0; i < register_count; i++) 1164 { 1165 int renum = 0; 1166 for (int j = 1; j < 7; j++) 1167 { 1168 if (used[j] == false) 1169 { 1170 if (renum == permunreg[i]) 1171 { 1172 registers[i] = j; 1173 used[j] = true; 1174 break; 1175 } 1176 renum++; 1177 } 1178 } 1179 } 1180 1181 uint32_t saved_registers_offset = 1; 1182 saved_registers_offset++; 1183 1184 for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--) 1185 { 1186 switch (registers[i]) 1187 { 1188 case UNWIND_X86_REG_NONE: 1189 break; 1190 case UNWIND_X86_REG_EBX: 1191 case UNWIND_X86_REG_ECX: 1192 case UNWIND_X86_REG_EDX: 1193 case UNWIND_X86_REG_EDI: 1194 case UNWIND_X86_REG_ESI: 1195 case UNWIND_X86_REG_EBP: 1196 row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_i386 (registers[i]), wordsize * -saved_registers_offset, true); 1197 break; 1198 } 1199 saved_registers_offset++; 1200 } 1201 } 1202 1203 unwind_plan.AppendRow (row); 1204 return true; 1205 } 1206 break; 1207 1208 case UNWIND_X86_MODE_DWARF: 1209 { 1210 return false; 1211 } 1212 break; 1213 } 1214 return false; 1215 } 1216