Symtab.cpp revision 3fed8b9b2696fc2ea78005c8f9b1c621d5748042
1//===-- Symtab.cpp ----------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <map> 11 12#include "lldb/Core/Module.h" 13#include "lldb/Core/RegularExpression.h" 14#include "lldb/Core/Timer.h" 15#include "lldb/Symbol/ObjectFile.h" 16#include "lldb/Symbol/Symtab.h" 17 18using namespace lldb; 19using namespace lldb_private; 20 21 22 23Symtab::Symtab(ObjectFile *objfile) : 24 m_objfile(objfile), 25 m_symbols(), 26 m_addr_indexes(), 27 m_name_to_index() 28{ 29} 30 31Symtab::~Symtab() 32{ 33} 34 35void 36Symtab::Reserve(uint32_t count) 37{ 38 m_symbols.reserve (count); 39} 40 41Symbol * 42Symtab::Resize(uint32_t count) 43{ 44 m_symbols.resize (count); 45 return &m_symbols[0]; 46} 47 48uint32_t 49Symtab::AddSymbol(const Symbol& symbol) 50{ 51 uint32_t symbol_idx = m_symbols.size(); 52 m_name_to_index.Clear(); 53 m_addr_indexes.clear(); 54 m_symbols.push_back(symbol); 55 return symbol_idx; 56} 57 58size_t 59Symtab::GetNumSymbols() const 60{ 61 return m_symbols.size(); 62} 63 64void 65Symtab::Dump(Stream *s, Target *target) const 66{ 67 const_iterator pos; 68// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 69 s->Indent(); 70 const FileSpec &file_spec = m_objfile->GetFileSpec(); 71 const char * object_name = NULL; 72 if (m_objfile->GetModule()) 73 object_name = m_objfile->GetModule()->GetObjectName().GetCString(); 74 75 if (file_spec) 76 s->Printf("Symtab, file = %s/%s%s%s%s, num_symbols = %u:\n", 77 file_spec.GetDirectory().AsCString(), 78 file_spec.GetFilename().AsCString(), 79 object_name ? "(" : "", 80 object_name ? object_name : "", 81 object_name ? ")" : "", 82 m_symbols.size()); 83 else 84 s->Printf("Symtab, num_symbols = %u:\n", m_symbols.size()); 85 s->IndentMore(); 86 87 if (!m_symbols.empty()) 88 { 89 const_iterator begin = m_symbols.begin(); 90 const_iterator end = m_symbols.end(); 91 DumpSymbolHeader (s); 92 for (pos = m_symbols.begin(); pos != end; ++pos) 93 { 94 s->Indent(); 95 pos->Dump(s, target, std::distance(begin, pos)); 96 } 97 } 98 s->IndentLess (); 99} 100 101void 102Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const 103{ 104 const size_t num_symbols = GetNumSymbols(); 105 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 106 s->Indent(); 107 s->Printf("Symtab %u symbol indexes (%u symbols total):\n", indexes.size(), m_symbols.size()); 108 s->IndentMore(); 109 110 if (!indexes.empty()) 111 { 112 std::vector<uint32_t>::const_iterator pos; 113 std::vector<uint32_t>::const_iterator end = indexes.end(); 114 DumpSymbolHeader (s); 115 for (pos = indexes.begin(); pos != end; ++pos) 116 { 117 uint32_t idx = *pos; 118 if (idx < num_symbols) 119 { 120 s->Indent(); 121 m_symbols[idx].Dump(s, target, idx); 122 } 123 } 124 } 125 s->IndentLess (); 126} 127 128void 129Symtab::DumpSymbolHeader (Stream *s) 130{ 131 s->Indent(" Debug symbol\n"); 132 s->Indent(" |Synthetic symbol\n"); 133 s->Indent(" ||Externally Visible\n"); 134 s->Indent(" |||\n"); 135 s->Indent("Index UserID DSX Type File Address/Value Load Address Size Flags Name\n"); 136 s->Indent("------- ------ --- ------------ ------------------ ------------------ ------------------ ---------- ----------------------------------\n"); 137} 138 139 140static int 141CompareSymbolID (const void *key, const void *p) 142{ 143 const user_id_t match_uid = *(user_id_t*) key; 144 const user_id_t symbol_uid = ((Symbol *)p)->GetID(); 145 if (match_uid < symbol_uid) 146 return -1; 147 if (match_uid > symbol_uid) 148 return 1; 149 return 0; 150} 151 152Symbol * 153Symtab::FindSymbolByID (lldb::user_id_t symbol_uid) const 154{ 155 Symbol *symbol = (Symbol*)::bsearch (&symbol_uid, 156 &m_symbols[0], 157 m_symbols.size(), 158 (uint8_t *)&m_symbols[1] - (uint8_t *)&m_symbols[0], 159 CompareSymbolID); 160 return symbol; 161} 162 163 164Symbol * 165Symtab::SymbolAtIndex(uint32_t idx) 166{ 167 if (idx < m_symbols.size()) 168 return &m_symbols[idx]; 169 return NULL; 170} 171 172 173const Symbol * 174Symtab::SymbolAtIndex(uint32_t idx) const 175{ 176 if (idx < m_symbols.size()) 177 return &m_symbols[idx]; 178 return NULL; 179} 180 181//---------------------------------------------------------------------- 182// InitNameIndexes 183//---------------------------------------------------------------------- 184void 185Symtab::InitNameIndexes() 186{ 187 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 188 // Create the name index vector to be able to quickly search by name 189 const size_t count = m_symbols.size(); 190 assert(m_objfile != NULL); 191 assert(m_objfile->GetModule() != NULL); 192 m_name_to_index.Reserve (count); 193 194 UniqueCStringMap<uint32_t>::Entry entry; 195 196 for (entry.value = 0; entry.value < count; ++entry.value) 197 { 198 const Symbol *symbol = &m_symbols[entry.value]; 199 200 // Don't let trampolines get into the lookup by name map 201 // If we ever need the trampoline symbols to be searchable by name 202 // we can remove this and then possibly add a new bool to any of the 203 // Symtab functions that lookup symbols by name to indicate if they 204 // want trampolines. 205 if (symbol->IsTrampoline()) 206 continue; 207 208 const Mangled &mangled = symbol->GetMangled(); 209 entry.cstring = mangled.GetMangledName().GetCString(); 210 if (entry.cstring && entry.cstring[0]) 211 m_name_to_index.Append (entry); 212 213 entry.cstring = mangled.GetDemangledName().GetCString(); 214 if (entry.cstring && entry.cstring[0]) 215 m_name_to_index.Append (entry); 216 } 217 m_name_to_index.Sort(); 218} 219 220uint32_t 221Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const 222{ 223 uint32_t prev_size = indexes.size(); 224 225 const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index); 226 227 for (uint32_t i = start_idx; i < count; ++i) 228 { 229 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 230 indexes.push_back(i); 231 } 232 233 return indexes.size() - prev_size; 234} 235 236uint32_t 237Symtab::AppendSymbolIndexesWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes, uint32_t start_idx, uint32_t end_index) const 238{ 239 uint32_t prev_size = indexes.size(); 240 241 const uint32_t count = std::min<uint32_t> (m_symbols.size(), end_index); 242 243 for (uint32_t i = start_idx; i < count; ++i) 244 { 245 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 246 { 247 if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility)) 248 indexes.push_back(i); 249 } 250 } 251 252 return indexes.size() - prev_size; 253} 254 255 256uint32_t 257Symtab::GetIndexForSymbol (const Symbol *symbol) const 258{ 259 const Symbol *first_symbol = &m_symbols[0]; 260 if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size()) 261 return symbol - first_symbol; 262 return UINT32_MAX; 263} 264 265struct SymbolSortInfo 266{ 267 const bool sort_by_load_addr; 268 const Symbol *symbols; 269}; 270 271namespace { 272 struct SymbolIndexComparator { 273 const std::vector<Symbol>& symbols; 274 SymbolIndexComparator(const std::vector<Symbol>& s) : symbols(s) { } 275 bool operator()(uint32_t index_a, uint32_t index_b) { 276 addr_t value_a; 277 addr_t value_b; 278 if (symbols[index_a].GetValue().GetSection() == symbols[index_b].GetValue().GetSection()) { 279 value_a = symbols[index_a].GetValue ().GetOffset(); 280 value_b = symbols[index_b].GetValue ().GetOffset(); 281 } else { 282 value_a = symbols[index_a].GetValue ().GetFileAddress(); 283 value_b = symbols[index_b].GetValue ().GetFileAddress(); 284 } 285 286 if (value_a == value_b) { 287 // The if the values are equal, use the original symbol user ID 288 lldb::user_id_t uid_a = symbols[index_a].GetID(); 289 lldb::user_id_t uid_b = symbols[index_b].GetID(); 290 if (uid_a < uid_b) 291 return true; 292 if (uid_a > uid_b) 293 return false; 294 return false; 295 } else if (value_a < value_b) 296 return true; 297 298 return false; 299 } 300 }; 301} 302 303void 304Symtab::SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const 305{ 306 Timer scoped_timer (__PRETTY_FUNCTION__,__PRETTY_FUNCTION__); 307 // No need to sort if we have zero or one items... 308 if (indexes.size() <= 1) 309 return; 310 311 // Sort the indexes in place using std::stable_sort. 312 // NOTE: The use of std::stable_sort instead of std::sort here is strictly for performance, 313 // not correctness. The indexes vector tends to be "close" to sorted, which the 314 // stable sort handles better. 315 std::stable_sort(indexes.begin(), indexes.end(), SymbolIndexComparator(m_symbols)); 316 317 // Remove any duplicates if requested 318 if (remove_duplicates) 319 std::unique(indexes.begin(), indexes.end()); 320} 321 322uint32_t 323Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& indexes) 324{ 325 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 326 if (symbol_name) 327 { 328 const size_t old_size = indexes.size(); 329 if (m_name_to_index.IsEmpty()) 330 InitNameIndexes(); 331 332 const char *symbol_cstr = symbol_name.GetCString(); 333 const UniqueCStringMap<uint32_t>::Entry *entry_ptr; 334 for (entry_ptr = m_name_to_index.FindFirstValueForName (symbol_cstr); 335 entry_ptr!= NULL; 336 entry_ptr = m_name_to_index.FindNextValueForName (symbol_cstr, entry_ptr)) 337 { 338 indexes.push_back (entry_ptr->value); 339 } 340 return indexes.size() - old_size; 341 } 342 return 0; 343} 344 345uint32_t 346Symtab::AppendSymbolIndexesWithName (const ConstString& symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 347{ 348 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 349 if (symbol_name) 350 { 351 const size_t old_size = indexes.size(); 352 if (m_name_to_index.IsEmpty()) 353 InitNameIndexes(); 354 355 const char *symbol_cstr = symbol_name.GetCString(); 356 const UniqueCStringMap<uint32_t>::Entry *entry_ptr; 357 for (entry_ptr = m_name_to_index.FindFirstValueForName (symbol_cstr); 358 entry_ptr!= NULL; 359 entry_ptr = m_name_to_index.FindNextValueForName (symbol_cstr, entry_ptr)) 360 { 361 if (CheckSymbolAtIndex(entry_ptr->value, symbol_debug_type, symbol_visibility)) 362 indexes.push_back (entry_ptr->value); 363 } 364 return indexes.size() - old_size; 365 } 366 return 0; 367} 368 369uint32_t 370Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, std::vector<uint32_t>& indexes) 371{ 372 if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0) 373 { 374 std::vector<uint32_t>::iterator pos = indexes.begin(); 375 while (pos != indexes.end()) 376 { 377 if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type) 378 ++pos; 379 else 380 indexes.erase(pos); 381 } 382 } 383 return indexes.size(); 384} 385 386uint32_t 387Symtab::AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 388{ 389 if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type, symbol_visibility, indexes) > 0) 390 { 391 std::vector<uint32_t>::iterator pos = indexes.begin(); 392 while (pos != indexes.end()) 393 { 394 if (symbol_type == eSymbolTypeAny || m_symbols[*pos].GetType() == symbol_type) 395 ++pos; 396 else 397 indexes.erase(pos); 398 } 399 } 400 return indexes.size(); 401} 402 403 404uint32_t 405Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, std::vector<uint32_t>& indexes) 406{ 407 uint32_t prev_size = indexes.size(); 408 uint32_t sym_end = m_symbols.size(); 409 410 for (int i = 0; i < sym_end; i++) 411 { 412 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 413 { 414 const char *name = m_symbols[i].GetMangled().GetName().AsCString(); 415 if (name) 416 { 417 if (regexp.Execute (name)) 418 indexes.push_back(i); 419 } 420 } 421 } 422 return indexes.size() - prev_size; 423 424} 425 426uint32_t 427Symtab::AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®exp, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& indexes) 428{ 429 uint32_t prev_size = indexes.size(); 430 uint32_t sym_end = m_symbols.size(); 431 432 for (int i = 0; i < sym_end; i++) 433 { 434 if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) 435 { 436 if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility) == false) 437 continue; 438 439 const char *name = m_symbols[i].GetMangled().GetName().AsCString(); 440 if (name) 441 { 442 if (regexp.Execute (name)) 443 indexes.push_back(i); 444 } 445 } 446 } 447 return indexes.size() - prev_size; 448 449} 450 451Symbol * 452Symtab::FindSymbolWithType (SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t& start_idx) 453{ 454 const size_t count = m_symbols.size(); 455 for (uint32_t idx = start_idx; idx < count; ++idx) 456 { 457 if (symbol_type == eSymbolTypeAny || m_symbols[idx].GetType() == symbol_type) 458 { 459 if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility)) 460 { 461 start_idx = idx; 462 return &m_symbols[idx]; 463 } 464 } 465 } 466 return NULL; 467} 468 469size_t 470Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes) 471{ 472 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 473 // Initialize all of the lookup by name indexes before converting NAME 474 // to a uniqued string NAME_STR below. 475 if (m_name_to_index.IsEmpty()) 476 InitNameIndexes(); 477 478 if (name) 479 { 480 // The string table did have a string that matched, but we need 481 // to check the symbols and match the symbol_type if any was given. 482 AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_indexes); 483 } 484 return symbol_indexes.size(); 485} 486 487size_t 488Symtab::FindAllSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) 489{ 490 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 491 // Initialize all of the lookup by name indexes before converting NAME 492 // to a uniqued string NAME_STR below. 493 if (m_name_to_index.IsEmpty()) 494 InitNameIndexes(); 495 496 if (name) 497 { 498 // The string table did have a string that matched, but we need 499 // to check the symbols and match the symbol_type if any was given. 500 AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes); 501 } 502 return symbol_indexes.size(); 503} 504 505size_t 506Symtab::FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes) 507{ 508 AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type, symbol_visibility, symbol_indexes); 509 return symbol_indexes.size(); 510} 511 512Symbol * 513Symtab::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility) 514{ 515 Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); 516 if (m_name_to_index.IsEmpty()) 517 InitNameIndexes(); 518 519 if (name) 520 { 521 std::vector<uint32_t> matching_indexes; 522 // The string table did have a string that matched, but we need 523 // to check the symbols and match the symbol_type if any was given. 524 if (AppendSymbolIndexesWithNameAndType (name, symbol_type, symbol_debug_type, symbol_visibility, matching_indexes)) 525 { 526 std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end(); 527 for (pos = matching_indexes.begin(); pos != end; ++pos) 528 { 529 Symbol *symbol = SymbolAtIndex(*pos); 530 531 if (symbol->Compare(name, symbol_type)) 532 return symbol; 533 } 534 } 535 } 536 return NULL; 537} 538 539typedef struct 540{ 541 const Symtab *symtab; 542 const addr_t file_addr; 543 Symbol *match_symbol; 544 const uint32_t *match_index_ptr; 545 addr_t match_offset; 546} SymbolSearchInfo; 547 548static int 549SymbolWithFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) 550{ 551 const Symbol *curr_symbol = info->symtab->SymbolAtIndex (index_ptr[0]); 552 if (curr_symbol == NULL) 553 return -1; 554 555 const addr_t info_file_addr = info->file_addr; 556 557 // lldb::Symbol::GetAddressRangePtr() will only return a non NULL address 558 // range if the symbol has a section! 559 const AddressRange *curr_range = curr_symbol->GetAddressRangePtr(); 560 if (curr_range) 561 { 562 const addr_t curr_file_addr = curr_range->GetBaseAddress().GetFileAddress(); 563 if (info_file_addr < curr_file_addr) 564 return -1; 565 if (info_file_addr > curr_file_addr) 566 return +1; 567 info->match_symbol = const_cast<Symbol *>(curr_symbol); 568 info->match_index_ptr = index_ptr; 569 return 0; 570 } 571 572 return -1; 573} 574 575static int 576SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr) 577{ 578 const Symbol *symbol = info->symtab->SymbolAtIndex (index_ptr[0]); 579 if (symbol == NULL) 580 return -1; 581 582 const addr_t info_file_addr = info->file_addr; 583 const AddressRange *curr_range = symbol->GetAddressRangePtr(); 584 if (curr_range) 585 { 586 const addr_t curr_file_addr = curr_range->GetBaseAddress().GetFileAddress(); 587 if (info_file_addr < curr_file_addr) 588 return -1; 589 590 // Since we are finding the closest symbol that is greater than or equal 591 // to 'info->file_addr' we set the symbol here. This will get set 592 // multiple times, but after the search is done it will contain the best 593 // symbol match 594 info->match_symbol = const_cast<Symbol *>(symbol); 595 info->match_index_ptr = index_ptr; 596 info->match_offset = info_file_addr - curr_file_addr; 597 598 if (info_file_addr > curr_file_addr) 599 return +1; 600 return 0; 601 } 602 return -1; 603} 604 605static SymbolSearchInfo 606FindIndexPtrForSymbolContainingAddress(Symtab* symtab, addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) 607{ 608 SymbolSearchInfo info = { symtab, file_addr, NULL, NULL, 0 }; 609 bsearch(&info, indexes, num_indexes, sizeof(uint32_t), (comparison_function)SymbolWithClosestFileAddress); 610 return info; 611} 612 613 614void 615Symtab::InitAddressIndexes() 616{ 617 if (m_addr_indexes.empty()) 618 { 619 AppendSymbolIndexesWithType (eSymbolTypeCode, m_addr_indexes); 620 AppendSymbolIndexesWithType (eSymbolTypeTrampoline, m_addr_indexes); 621 AppendSymbolIndexesWithType (eSymbolTypeData, m_addr_indexes); 622 SortSymbolIndexesByValue(m_addr_indexes, true); 623 m_addr_indexes.push_back(UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol 624 } 625} 626 627size_t 628Symtab::CalculateSymbolSize (Symbol *symbol) 629{ 630 if (m_symbols.empty()) 631 return 0; 632 633 // Make sure this symbol is from this symbol table... 634 if (symbol < &m_symbols.front() || symbol > &m_symbols.back()) 635 return 0; 636 637 // See if this symbol already has a byte size? 638 size_t byte_size = symbol->GetByteSize(); 639 640 if (byte_size) 641 { 642 // It does, just return it 643 return byte_size; 644 } 645 646 // Else if this is an address based symbol, figure out the delta between 647 // it and the next address based symbol 648 if (symbol->GetAddressRangePtr()) 649 { 650 if (m_addr_indexes.empty()) 651 InitAddressIndexes(); 652 const size_t num_addr_indexes = m_addr_indexes.size(); 653 SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress(this, symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(), &m_addr_indexes.front(), num_addr_indexes); 654 if (info.match_index_ptr != NULL) 655 { 656 const lldb::addr_t curr_file_addr = symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(); 657 // We can figure out the address range of all symbols except the 658 // last one by taking the delta between the current symbol and 659 // the next symbol 660 661 for (uint32_t addr_index = info.match_index_ptr - &m_addr_indexes.front() + 1; 662 addr_index < num_addr_indexes; 663 ++addr_index) 664 { 665 Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]); 666 if (next_symbol == NULL) 667 break; 668 669 assert (next_symbol->GetAddressRangePtr()); 670 const lldb::addr_t next_file_addr = next_symbol->GetAddressRangePtr()->GetBaseAddress().GetFileAddress(); 671 if (next_file_addr > curr_file_addr) 672 { 673 byte_size = next_file_addr - curr_file_addr; 674 symbol->GetAddressRangePtr()->SetByteSize(byte_size); 675 symbol->SetSizeIsSynthesized(true); 676 break; 677 } 678 } 679 } 680 } 681 return byte_size; 682} 683 684Symbol * 685Symtab::FindSymbolWithFileAddress (addr_t file_addr) 686{ 687 if (m_addr_indexes.empty()) 688 InitAddressIndexes(); 689 690 SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 }; 691 692 uint32_t* match = (uint32_t*)bsearch(&info, &m_addr_indexes[0], m_addr_indexes.size(), sizeof(uint32_t), (comparison_function)SymbolWithFileAddress); 693 if (match) 694 return SymbolAtIndex (*match); 695 return NULL; 696} 697 698 699Symbol * 700Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) 701{ 702 SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 }; 703 704 bsearch(&info, indexes, num_indexes, sizeof(uint32_t), (comparison_function)SymbolWithClosestFileAddress); 705 706 if (info.match_symbol) 707 { 708 if (info.match_offset == 0) 709 { 710 // We found an exact match! 711 return info.match_symbol; 712 } 713 714 const size_t symbol_byte_size = CalculateSymbolSize(info.match_symbol); 715 716 if (symbol_byte_size == 0) 717 { 718 // We weren't able to find the size of the symbol so lets just go 719 // with that match we found in our search... 720 return info.match_symbol; 721 } 722 723 // We were able to figure out a symbol size so lets make sure our 724 // offset puts "file_addr" in the symbol's address range. 725 if (info.match_offset < symbol_byte_size) 726 return info.match_symbol; 727 } 728 return NULL; 729} 730 731Symbol * 732Symtab::FindSymbolContainingFileAddress (addr_t file_addr) 733{ 734 if (m_addr_indexes.empty()) 735 InitAddressIndexes(); 736 737 return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size()); 738} 739 740