1254721Semaste//===-- Section.cpp ---------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/Section.h" 11254721Semaste#include "lldb/Core/Module.h" 12254721Semaste#include "lldb/Symbol/ObjectFile.h" 13269024Semaste#include "lldb/Target/SectionLoadList.h" 14254721Semaste#include "lldb/Target/Target.h" 15254721Semaste 16254721Semasteusing namespace lldb; 17254721Semasteusing namespace lldb_private; 18254721Semaste 19254721SemasteSection::Section (const ModuleSP &module_sp, 20254721Semaste ObjectFile *obj_file, 21254721Semaste user_id_t sect_id, 22254721Semaste const ConstString &name, 23254721Semaste SectionType sect_type, 24254721Semaste addr_t file_addr, 25254721Semaste addr_t byte_size, 26254721Semaste lldb::offset_t file_offset, 27254721Semaste lldb::offset_t file_size, 28254721Semaste uint32_t flags) : 29254721Semaste ModuleChild (module_sp), 30254721Semaste UserID (sect_id), 31254721Semaste Flags (flags), 32254721Semaste m_obj_file (obj_file), 33254721Semaste m_type (sect_type), 34254721Semaste m_parent_wp (), 35254721Semaste m_name (name), 36254721Semaste m_file_addr (file_addr), 37254721Semaste m_byte_size (byte_size), 38254721Semaste m_file_offset (file_offset), 39254721Semaste m_file_size (file_size), 40254721Semaste m_children (), 41254721Semaste m_fake (false), 42254721Semaste m_encrypted (false), 43254721Semaste m_thread_specific (false) 44254721Semaste{ 45254721Semaste// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n", 46254721Semaste// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString()); 47254721Semaste} 48254721Semaste 49254721SemasteSection::Section (const lldb::SectionSP &parent_section_sp, 50254721Semaste const ModuleSP &module_sp, 51254721Semaste ObjectFile *obj_file, 52254721Semaste user_id_t sect_id, 53254721Semaste const ConstString &name, 54254721Semaste SectionType sect_type, 55254721Semaste addr_t file_addr, 56254721Semaste addr_t byte_size, 57254721Semaste lldb::offset_t file_offset, 58254721Semaste lldb::offset_t file_size, 59254721Semaste uint32_t flags) : 60254721Semaste ModuleChild (module_sp), 61254721Semaste UserID (sect_id), 62254721Semaste Flags (flags), 63254721Semaste m_obj_file (obj_file), 64254721Semaste m_type (sect_type), 65254721Semaste m_parent_wp (), 66254721Semaste m_name (name), 67254721Semaste m_file_addr (file_addr), 68254721Semaste m_byte_size (byte_size), 69254721Semaste m_file_offset (file_offset), 70254721Semaste m_file_size (file_size), 71254721Semaste m_children (), 72254721Semaste m_fake (false), 73254721Semaste m_encrypted (false), 74254721Semaste m_thread_specific (false) 75254721Semaste{ 76254721Semaste// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n", 77254721Semaste// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString()); 78254721Semaste if (parent_section_sp) 79254721Semaste m_parent_wp = parent_section_sp; 80254721Semaste} 81254721Semaste 82254721SemasteSection::~Section() 83254721Semaste{ 84254721Semaste// printf ("Section::~Section(%p)\n", this); 85254721Semaste} 86254721Semaste 87254721Semasteaddr_t 88254721SemasteSection::GetFileAddress () const 89254721Semaste{ 90254721Semaste SectionSP parent_sp (GetParent ()); 91254721Semaste if (parent_sp) 92254721Semaste { 93254721Semaste // This section has a parent which means m_file_addr is an offset into 94254721Semaste // the parent section, so the file address for this section is the file 95254721Semaste // address of the parent plus the offset 96254721Semaste return parent_sp->GetFileAddress() + m_file_addr; 97254721Semaste } 98254721Semaste // This section has no parent, so m_file_addr is the file base address 99254721Semaste return m_file_addr; 100254721Semaste} 101254721Semaste 102254721Semastebool 103254721SemasteSection::SetFileAddress (lldb::addr_t file_addr) 104254721Semaste{ 105254721Semaste SectionSP parent_sp (GetParent ()); 106254721Semaste if (parent_sp) 107254721Semaste { 108254721Semaste if (m_file_addr >= file_addr) 109254721Semaste return parent_sp->SetFileAddress (m_file_addr - file_addr); 110254721Semaste return false; 111254721Semaste } 112254721Semaste else 113254721Semaste { 114254721Semaste // This section has no parent, so m_file_addr is the file base address 115254721Semaste m_file_addr = file_addr; 116254721Semaste return true; 117254721Semaste } 118254721Semaste} 119254721Semaste 120254721Semastelldb::addr_t 121254721SemasteSection::GetOffset () const 122254721Semaste{ 123254721Semaste // This section has a parent which means m_file_addr is an offset. 124254721Semaste SectionSP parent_sp (GetParent ()); 125254721Semaste if (parent_sp) 126254721Semaste return m_file_addr; 127254721Semaste 128254721Semaste // This section has no parent, so there is no offset to be had 129254721Semaste return 0; 130254721Semaste} 131254721Semaste 132254721Semasteaddr_t 133254721SemasteSection::GetLoadBaseAddress (Target *target) const 134254721Semaste{ 135254721Semaste addr_t load_base_addr = LLDB_INVALID_ADDRESS; 136254721Semaste SectionSP parent_sp (GetParent ()); 137254721Semaste if (parent_sp) 138254721Semaste { 139254721Semaste load_base_addr = parent_sp->GetLoadBaseAddress (target); 140254721Semaste if (load_base_addr != LLDB_INVALID_ADDRESS) 141254721Semaste load_base_addr += GetOffset(); 142254721Semaste } 143254721Semaste else 144254721Semaste { 145254721Semaste load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this()); 146254721Semaste } 147254721Semaste return load_base_addr; 148254721Semaste} 149254721Semaste 150254721Semastebool 151254721SemasteSection::ResolveContainedAddress (addr_t offset, Address &so_addr) const 152254721Semaste{ 153254721Semaste const size_t num_children = m_children.GetSize(); 154254721Semaste if (num_children > 0) 155254721Semaste { 156254721Semaste for (size_t i=0; i<num_children; i++) 157254721Semaste { 158254721Semaste Section* child_section = m_children.GetSectionAtIndex (i).get(); 159254721Semaste 160254721Semaste addr_t child_offset = child_section->GetOffset(); 161254721Semaste if (child_offset <= offset && offset - child_offset < child_section->GetByteSize()) 162254721Semaste return child_section->ResolveContainedAddress (offset - child_offset, so_addr); 163254721Semaste } 164254721Semaste } 165254721Semaste so_addr.SetOffset(offset); 166254721Semaste so_addr.SetSection(const_cast<Section *>(this)->shared_from_this()); 167254721Semaste 168254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 169254721Semaste // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections. 170254721Semaste assert(GetModule().get()); 171254721Semaste#endif 172254721Semaste return true; 173254721Semaste} 174254721Semaste 175254721Semastebool 176254721SemasteSection::ContainsFileAddress (addr_t vm_addr) const 177254721Semaste{ 178254721Semaste const addr_t file_addr = GetFileAddress(); 179254721Semaste if (file_addr != LLDB_INVALID_ADDRESS) 180254721Semaste { 181254721Semaste if (file_addr <= vm_addr) 182254721Semaste { 183254721Semaste const addr_t offset = vm_addr - file_addr; 184254721Semaste return offset < GetByteSize(); 185254721Semaste } 186254721Semaste } 187254721Semaste return false; 188254721Semaste} 189254721Semaste 190254721Semasteint 191254721SemasteSection::Compare (const Section& a, const Section& b) 192254721Semaste{ 193254721Semaste if (&a == &b) 194254721Semaste return 0; 195254721Semaste 196254721Semaste const ModuleSP a_module_sp = a.GetModule(); 197254721Semaste const ModuleSP b_module_sp = b.GetModule(); 198254721Semaste if (a_module_sp == b_module_sp) 199254721Semaste { 200254721Semaste user_id_t a_sect_uid = a.GetID(); 201254721Semaste user_id_t b_sect_uid = b.GetID(); 202254721Semaste if (a_sect_uid < b_sect_uid) 203254721Semaste return -1; 204254721Semaste if (a_sect_uid > b_sect_uid) 205254721Semaste return 1; 206254721Semaste return 0; 207254721Semaste } 208254721Semaste else 209254721Semaste { 210254721Semaste // The modules are different, just compare the module pointers 211254721Semaste if (a_module_sp.get() < b_module_sp.get()) 212254721Semaste return -1; 213254721Semaste else 214254721Semaste return 1; // We already know the modules aren't equal 215254721Semaste } 216254721Semaste} 217254721Semaste 218254721Semaste 219254721Semastevoid 220254721SemasteSection::Dump (Stream *s, Target *target, uint32_t depth) const 221254721Semaste{ 222254721Semaste// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 223254721Semaste s->Indent(); 224254721Semaste s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetSectionTypeAsCString (m_type)); 225254721Semaste bool resolved = true; 226254721Semaste addr_t addr = LLDB_INVALID_ADDRESS; 227254721Semaste 228254721Semaste if (GetByteSize() == 0) 229254721Semaste s->Printf("%39s", ""); 230254721Semaste else 231254721Semaste { 232254721Semaste if (target) 233254721Semaste addr = GetLoadBaseAddress (target); 234254721Semaste 235254721Semaste if (addr == LLDB_INVALID_ADDRESS) 236254721Semaste { 237254721Semaste if (target) 238254721Semaste resolved = false; 239254721Semaste addr = GetFileAddress(); 240254721Semaste } 241254721Semaste 242254721Semaste VMRange range(addr, addr + m_byte_size); 243254721Semaste range.Dump (s, 0); 244254721Semaste } 245254721Semaste 246254721Semaste s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get()); 247254721Semaste 248254721Semaste DumpName (s); 249254721Semaste 250254721Semaste s->EOL(); 251254721Semaste 252254721Semaste if (depth > 0) 253254721Semaste m_children.Dump(s, target, false, depth - 1); 254254721Semaste} 255254721Semaste 256254721Semastevoid 257254721SemasteSection::DumpName (Stream *s) const 258254721Semaste{ 259254721Semaste SectionSP parent_sp (GetParent ()); 260254721Semaste if (parent_sp) 261254721Semaste { 262254721Semaste parent_sp->DumpName (s); 263254721Semaste s->PutChar('.'); 264254721Semaste } 265254721Semaste else 266254721Semaste { 267254721Semaste // The top most section prints the module basename 268254721Semaste const char * name = NULL; 269254721Semaste ModuleSP module_sp (GetModule()); 270254721Semaste const FileSpec &file_spec = m_obj_file->GetFileSpec(); 271254721Semaste 272254721Semaste if (m_obj_file) 273254721Semaste name = file_spec.GetFilename().AsCString(); 274254721Semaste if ((!name || !name[0]) && module_sp) 275254721Semaste name = module_sp->GetFileSpec().GetFilename().AsCString(); 276254721Semaste if (name && name[0]) 277254721Semaste s->Printf("%s.", name); 278254721Semaste } 279254721Semaste m_name.Dump(s); 280254721Semaste} 281254721Semaste 282254721Semastebool 283254721SemasteSection::IsDescendant (const Section *section) 284254721Semaste{ 285254721Semaste if (this == section) 286254721Semaste return true; 287254721Semaste SectionSP parent_sp (GetParent ()); 288254721Semaste if (parent_sp) 289254721Semaste return parent_sp->IsDescendant (section); 290254721Semaste return false; 291254721Semaste} 292254721Semaste 293254721Semastebool 294254721SemasteSection::Slide (addr_t slide_amount, bool slide_children) 295254721Semaste{ 296254721Semaste if (m_file_addr != LLDB_INVALID_ADDRESS) 297254721Semaste { 298254721Semaste if (slide_amount == 0) 299254721Semaste return true; 300254721Semaste 301254721Semaste m_file_addr += slide_amount; 302254721Semaste 303254721Semaste if (slide_children) 304254721Semaste m_children.Slide (slide_amount, slide_children); 305254721Semaste 306254721Semaste return true; 307254721Semaste } 308254721Semaste return false; 309254721Semaste} 310254721Semaste 311254721Semaste#pragma mark SectionList 312254721Semaste 313254721SemasteSectionList::SectionList () : 314254721Semaste m_sections() 315254721Semaste{ 316254721Semaste} 317254721Semaste 318254721Semaste 319254721SemasteSectionList::~SectionList () 320254721Semaste{ 321254721Semaste} 322254721Semaste 323254721SemasteSectionList & 324254721SemasteSectionList::operator = (const SectionList& rhs) 325254721Semaste{ 326254721Semaste if (this != &rhs) 327254721Semaste m_sections = rhs.m_sections; 328254721Semaste return *this; 329254721Semaste} 330254721Semaste 331254721Semastesize_t 332254721SemasteSectionList::AddSection (const lldb::SectionSP& section_sp) 333254721Semaste{ 334254721Semaste assert (section_sp.get()); 335254721Semaste size_t section_index = m_sections.size(); 336254721Semaste m_sections.push_back(section_sp); 337254721Semaste return section_index; 338254721Semaste} 339254721Semaste 340254721Semaste// Warning, this can be slow as it's removing items from a std::vector. 341254721Semastebool 342254721SemasteSectionList::DeleteSection (size_t idx) 343254721Semaste{ 344254721Semaste if (idx < m_sections.size()) 345254721Semaste { 346254721Semaste m_sections.erase (m_sections.begin() + idx); 347254721Semaste return true; 348254721Semaste } 349254721Semaste return false; 350254721Semaste} 351254721Semaste 352254721Semastesize_t 353254721SemasteSectionList::FindSectionIndex (const Section* sect) 354254721Semaste{ 355254721Semaste iterator sect_iter; 356254721Semaste iterator begin = m_sections.begin(); 357254721Semaste iterator end = m_sections.end(); 358254721Semaste for (sect_iter = begin; sect_iter != end; ++sect_iter) 359254721Semaste { 360254721Semaste if (sect_iter->get() == sect) 361254721Semaste { 362254721Semaste // The secton was already in this section list 363254721Semaste return std::distance (begin, sect_iter); 364254721Semaste } 365254721Semaste } 366254721Semaste return UINT32_MAX; 367254721Semaste} 368254721Semaste 369254721Semastesize_t 370254721SemasteSectionList::AddUniqueSection (const lldb::SectionSP& sect_sp) 371254721Semaste{ 372254721Semaste size_t sect_idx = FindSectionIndex (sect_sp.get()); 373254721Semaste if (sect_idx == UINT32_MAX) 374254721Semaste { 375254721Semaste sect_idx = AddSection (sect_sp); 376254721Semaste } 377254721Semaste return sect_idx; 378254721Semaste} 379254721Semaste 380254721Semastebool 381254721SemasteSectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp, uint32_t depth) 382254721Semaste{ 383254721Semaste iterator sect_iter, end = m_sections.end(); 384254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) 385254721Semaste { 386254721Semaste if ((*sect_iter)->GetID() == sect_id) 387254721Semaste { 388254721Semaste *sect_iter = sect_sp; 389254721Semaste return true; 390254721Semaste } 391254721Semaste else if (depth > 0) 392254721Semaste { 393254721Semaste if ((*sect_iter)->GetChildren().ReplaceSection(sect_id, sect_sp, depth - 1)) 394254721Semaste return true; 395254721Semaste } 396254721Semaste } 397254721Semaste return false; 398254721Semaste} 399254721Semaste 400254721Semastesize_t 401254721SemasteSectionList::GetNumSections (uint32_t depth) const 402254721Semaste{ 403254721Semaste size_t count = m_sections.size(); 404254721Semaste if (depth > 0) 405254721Semaste { 406254721Semaste const_iterator sect_iter, end = m_sections.end(); 407254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) 408254721Semaste { 409254721Semaste count += (*sect_iter)->GetChildren().GetNumSections(depth - 1); 410254721Semaste } 411254721Semaste } 412254721Semaste return count; 413254721Semaste} 414254721Semaste 415254721SemasteSectionSP 416254721SemasteSectionList::GetSectionAtIndex (size_t idx) const 417254721Semaste{ 418254721Semaste SectionSP sect_sp; 419254721Semaste if (idx < m_sections.size()) 420254721Semaste sect_sp = m_sections[idx]; 421254721Semaste return sect_sp; 422254721Semaste} 423254721Semaste 424254721SemasteSectionSP 425254721SemasteSectionList::FindSectionByName (const ConstString §ion_dstr) const 426254721Semaste{ 427254721Semaste SectionSP sect_sp; 428254721Semaste // Check if we have a valid section string 429254721Semaste if (section_dstr && !m_sections.empty()) 430254721Semaste { 431254721Semaste const_iterator sect_iter; 432254721Semaste const_iterator end = m_sections.end(); 433254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter) 434254721Semaste { 435254721Semaste Section *child_section = sect_iter->get(); 436254721Semaste assert (child_section); 437254721Semaste if (child_section->GetName() == section_dstr) 438254721Semaste { 439254721Semaste sect_sp = *sect_iter; 440254721Semaste } 441254721Semaste else 442254721Semaste { 443254721Semaste sect_sp = child_section->GetChildren().FindSectionByName(section_dstr); 444254721Semaste } 445254721Semaste } 446254721Semaste } 447254721Semaste return sect_sp; 448254721Semaste} 449254721Semaste 450254721SemasteSectionSP 451254721SemasteSectionList::FindSectionByID (user_id_t sect_id) const 452254721Semaste{ 453254721Semaste SectionSP sect_sp; 454254721Semaste if (sect_id) 455254721Semaste { 456254721Semaste const_iterator sect_iter; 457254721Semaste const_iterator end = m_sections.end(); 458254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter) 459254721Semaste { 460254721Semaste if ((*sect_iter)->GetID() == sect_id) 461254721Semaste { 462254721Semaste sect_sp = *sect_iter; 463254721Semaste break; 464254721Semaste } 465254721Semaste else 466254721Semaste { 467254721Semaste sect_sp = (*sect_iter)->GetChildren().FindSectionByID (sect_id); 468254721Semaste } 469254721Semaste } 470254721Semaste } 471254721Semaste return sect_sp; 472254721Semaste} 473254721Semaste 474254721Semaste 475254721SemasteSectionSP 476254721SemasteSectionList::FindSectionByType (SectionType sect_type, bool check_children, size_t start_idx) const 477254721Semaste{ 478254721Semaste SectionSP sect_sp; 479254721Semaste size_t num_sections = m_sections.size(); 480254721Semaste for (size_t idx = start_idx; idx < num_sections; ++idx) 481254721Semaste { 482254721Semaste if (m_sections[idx]->GetType() == sect_type) 483254721Semaste { 484254721Semaste sect_sp = m_sections[idx]; 485254721Semaste break; 486254721Semaste } 487254721Semaste else if (check_children) 488254721Semaste { 489254721Semaste sect_sp = m_sections[idx]->GetChildren().FindSectionByType (sect_type, check_children, 0); 490254721Semaste if (sect_sp) 491254721Semaste break; 492254721Semaste } 493254721Semaste } 494254721Semaste return sect_sp; 495254721Semaste} 496254721Semaste 497254721SemasteSectionSP 498254721SemasteSectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const 499254721Semaste{ 500254721Semaste SectionSP sect_sp; 501254721Semaste const_iterator sect_iter; 502254721Semaste const_iterator end = m_sections.end(); 503254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter) 504254721Semaste { 505254721Semaste Section *sect = sect_iter->get(); 506254721Semaste if (sect->ContainsFileAddress (vm_addr)) 507254721Semaste { 508254721Semaste // The file address is in this section. We need to make sure one of our child 509254721Semaste // sections doesn't contain this address as well as obeying the depth limit 510254721Semaste // that was passed in. 511254721Semaste if (depth > 0) 512254721Semaste sect_sp = sect->GetChildren().FindSectionContainingFileAddress(vm_addr, depth - 1); 513254721Semaste 514254721Semaste if (sect_sp.get() == NULL && !sect->IsFake()) 515254721Semaste sect_sp = *sect_iter; 516254721Semaste } 517254721Semaste } 518254721Semaste return sect_sp; 519254721Semaste} 520254721Semaste 521254721Semastebool 522254721SemasteSectionList::ContainsSection(user_id_t sect_id) const 523254721Semaste{ 524254721Semaste return FindSectionByID (sect_id).get() != NULL; 525254721Semaste} 526254721Semaste 527254721Semastevoid 528254721SemasteSectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const 529254721Semaste{ 530254721Semaste bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty(); 531254721Semaste if (show_header && !m_sections.empty()) 532254721Semaste { 533254721Semaste s->Indent(); 534254721Semaste s->Printf( "SectID Type %s Address File Off. File Size Flags Section Name\n", target_has_loaded_sections ? "Load" : "File"); 535254721Semaste s->Indent(); 536254721Semaste s->PutCString("---------- ---------------- --------------------------------------- ---------- ---------- ---------- ----------------------------\n"); 537254721Semaste } 538254721Semaste 539254721Semaste 540254721Semaste const_iterator sect_iter; 541254721Semaste const_iterator end = m_sections.end(); 542254721Semaste for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) 543254721Semaste { 544254721Semaste (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth); 545254721Semaste } 546254721Semaste 547254721Semaste if (show_header && !m_sections.empty()) 548254721Semaste s->IndentLess(); 549254721Semaste 550254721Semaste} 551254721Semaste 552254721Semastesize_t 553254721SemasteSectionList::Slide (addr_t slide_amount, bool slide_children) 554254721Semaste{ 555254721Semaste size_t count = 0; 556254721Semaste const_iterator pos, end = m_sections.end(); 557254721Semaste for (pos = m_sections.begin(); pos != end; ++pos) 558254721Semaste { 559254721Semaste if ((*pos)->Slide(slide_amount, slide_children)) 560254721Semaste ++count; 561254721Semaste } 562254721Semaste return count; 563254721Semaste} 564