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