1254721Semaste//===-- Function.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/Symbol/Function.h" 11254721Semaste#include "lldb/Core/Module.h" 12254721Semaste#include "lldb/Core/Section.h" 13254721Semaste#include "lldb/Host/Host.h" 14254721Semaste#include "lldb/Symbol/ClangASTType.h" 15254721Semaste#include "lldb/Symbol/CompileUnit.h" 16254721Semaste#include "lldb/Symbol/LineTable.h" 17254721Semaste#include "lldb/Symbol/SymbolFile.h" 18254721Semaste#include "lldb/Symbol/SymbolVendor.h" 19254721Semaste#include "llvm/Support/Casting.h" 20254721Semaste 21254721Semasteusing namespace lldb; 22254721Semasteusing namespace lldb_private; 23254721Semaste 24254721Semaste//---------------------------------------------------------------------- 25254721Semaste// Basic function information is contained in the FunctionInfo class. 26254721Semaste// It is designed to contain the name, linkage name, and declaration 27254721Semaste// location. 28254721Semaste//---------------------------------------------------------------------- 29254721SemasteFunctionInfo::FunctionInfo (const char *name, const Declaration *decl_ptr) : 30254721Semaste m_name(name), 31254721Semaste m_declaration(decl_ptr) 32254721Semaste{ 33254721Semaste} 34254721Semaste 35254721Semaste 36254721SemasteFunctionInfo::FunctionInfo (const ConstString& name, const Declaration *decl_ptr) : 37254721Semaste m_name(name), 38254721Semaste m_declaration(decl_ptr) 39254721Semaste{ 40254721Semaste} 41254721Semaste 42254721Semaste 43254721SemasteFunctionInfo::~FunctionInfo() 44254721Semaste{ 45254721Semaste} 46254721Semaste 47254721Semastevoid 48254721SemasteFunctionInfo::Dump(Stream *s, bool show_fullpaths) const 49254721Semaste{ 50254721Semaste if (m_name) 51254721Semaste *s << ", name = \"" << m_name << "\""; 52254721Semaste m_declaration.Dump(s, show_fullpaths); 53254721Semaste} 54254721Semaste 55254721Semaste 56254721Semasteint 57254721SemasteFunctionInfo::Compare(const FunctionInfo& a, const FunctionInfo& b) 58254721Semaste{ 59254721Semaste int result = ConstString::Compare(a.GetName(), b.GetName()); 60254721Semaste if (result) 61254721Semaste return result; 62254721Semaste 63254721Semaste return Declaration::Compare(a.m_declaration, b.m_declaration); 64254721Semaste} 65254721Semaste 66254721Semaste 67254721SemasteDeclaration& 68254721SemasteFunctionInfo::GetDeclaration() 69254721Semaste{ 70254721Semaste return m_declaration; 71254721Semaste} 72254721Semaste 73254721Semasteconst Declaration& 74254721SemasteFunctionInfo::GetDeclaration() const 75254721Semaste{ 76254721Semaste return m_declaration; 77254721Semaste} 78254721Semaste 79254721Semasteconst ConstString& 80254721SemasteFunctionInfo::GetName() const 81254721Semaste{ 82254721Semaste return m_name; 83254721Semaste} 84254721Semaste 85254721Semastesize_t 86254721SemasteFunctionInfo::MemorySize() const 87254721Semaste{ 88254721Semaste return m_name.MemorySize() + m_declaration.MemorySize(); 89254721Semaste} 90254721Semaste 91254721Semaste 92254721SemasteInlineFunctionInfo::InlineFunctionInfo 93254721Semaste( 94254721Semaste const char *name, 95254721Semaste const char *mangled, 96254721Semaste const Declaration *decl_ptr, 97254721Semaste const Declaration *call_decl_ptr 98254721Semaste) : 99254721Semaste FunctionInfo(name, decl_ptr), 100254721Semaste m_mangled(ConstString(mangled), true), 101254721Semaste m_call_decl (call_decl_ptr) 102254721Semaste{ 103254721Semaste} 104254721Semaste 105254721SemasteInlineFunctionInfo::InlineFunctionInfo 106254721Semaste( 107254721Semaste const ConstString& name, 108254721Semaste const Mangled &mangled, 109254721Semaste const Declaration *decl_ptr, 110254721Semaste const Declaration *call_decl_ptr 111254721Semaste) : 112254721Semaste FunctionInfo(name, decl_ptr), 113254721Semaste m_mangled(mangled), 114254721Semaste m_call_decl (call_decl_ptr) 115254721Semaste{ 116254721Semaste} 117254721Semaste 118254721SemasteInlineFunctionInfo::~InlineFunctionInfo() 119254721Semaste{ 120254721Semaste} 121254721Semaste 122254721Semasteint 123254721SemasteInlineFunctionInfo::Compare(const InlineFunctionInfo& a, const InlineFunctionInfo& b) 124254721Semaste{ 125254721Semaste 126254721Semaste int result = FunctionInfo::Compare(a, b); 127254721Semaste if (result) 128254721Semaste return result; 129254721Semaste // only compare the mangled names if both have them 130254721Semaste return Mangled::Compare(a.m_mangled, a.m_mangled); 131254721Semaste} 132254721Semaste 133254721Semastevoid 134254721SemasteInlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const 135254721Semaste{ 136254721Semaste FunctionInfo::Dump(s, show_fullpaths); 137254721Semaste if (m_mangled) 138254721Semaste m_mangled.Dump(s); 139254721Semaste} 140254721Semaste 141254721Semastevoid 142254721SemasteInlineFunctionInfo::DumpStopContext (Stream *s) const 143254721Semaste{ 144254721Semaste// s->Indent("[inlined] "); 145254721Semaste s->Indent(); 146254721Semaste if (m_mangled) 147254721Semaste s->PutCString (m_mangled.GetName().AsCString()); 148254721Semaste else 149254721Semaste s->PutCString (m_name.AsCString()); 150254721Semaste} 151254721Semaste 152254721Semaste 153254721Semasteconst ConstString & 154254721SemasteInlineFunctionInfo::GetName () const 155254721Semaste{ 156254721Semaste if (m_mangled) 157254721Semaste return m_mangled.GetName(); 158254721Semaste return m_name; 159254721Semaste} 160254721Semaste 161254721Semaste 162254721SemasteDeclaration & 163254721SemasteInlineFunctionInfo::GetCallSite () 164254721Semaste{ 165254721Semaste return m_call_decl; 166254721Semaste} 167254721Semaste 168254721Semasteconst Declaration & 169254721SemasteInlineFunctionInfo::GetCallSite () const 170254721Semaste{ 171254721Semaste return m_call_decl; 172254721Semaste} 173254721Semaste 174254721Semaste 175254721SemasteMangled& 176254721SemasteInlineFunctionInfo::GetMangled() 177254721Semaste{ 178254721Semaste return m_mangled; 179254721Semaste} 180254721Semaste 181254721Semasteconst Mangled& 182254721SemasteInlineFunctionInfo::GetMangled() const 183254721Semaste{ 184254721Semaste return m_mangled; 185254721Semaste} 186254721Semaste 187254721Semastesize_t 188254721SemasteInlineFunctionInfo::MemorySize() const 189254721Semaste{ 190254721Semaste return FunctionInfo::MemorySize() + m_mangled.MemorySize(); 191254721Semaste} 192254721Semaste 193254721Semaste//---------------------------------------------------------------------- 194254721Semaste// 195254721Semaste//---------------------------------------------------------------------- 196254721SemasteFunction::Function 197254721Semaste( 198254721Semaste CompileUnit *comp_unit, 199254721Semaste lldb::user_id_t func_uid, 200254721Semaste lldb::user_id_t type_uid, 201254721Semaste const Mangled &mangled, 202254721Semaste Type * type, 203254721Semaste const AddressRange& range 204254721Semaste) : 205254721Semaste UserID (func_uid), 206254721Semaste m_comp_unit (comp_unit), 207254721Semaste m_type_uid (type_uid), 208254721Semaste m_type (type), 209254721Semaste m_mangled (mangled), 210254721Semaste m_block (func_uid), 211254721Semaste m_range (range), 212254721Semaste m_frame_base (), 213254721Semaste m_flags (), 214254721Semaste m_prologue_byte_size (0) 215254721Semaste{ 216254721Semaste m_block.SetParentScope(this); 217254721Semaste assert(comp_unit != NULL); 218254721Semaste} 219254721Semaste 220254721SemasteFunction::Function 221254721Semaste( 222254721Semaste CompileUnit *comp_unit, 223254721Semaste lldb::user_id_t func_uid, 224254721Semaste lldb::user_id_t type_uid, 225254721Semaste const char *mangled, 226254721Semaste Type *type, 227254721Semaste const AddressRange &range 228254721Semaste) : 229254721Semaste UserID (func_uid), 230254721Semaste m_comp_unit (comp_unit), 231254721Semaste m_type_uid (type_uid), 232254721Semaste m_type (type), 233254721Semaste m_mangled (ConstString(mangled), true), 234254721Semaste m_block (func_uid), 235254721Semaste m_range (range), 236254721Semaste m_frame_base (), 237254721Semaste m_flags (), 238254721Semaste m_prologue_byte_size (0) 239254721Semaste{ 240254721Semaste m_block.SetParentScope(this); 241254721Semaste assert(comp_unit != NULL); 242254721Semaste} 243254721Semaste 244254721Semaste 245254721SemasteFunction::~Function() 246254721Semaste{ 247254721Semaste} 248254721Semaste 249254721Semastevoid 250254721SemasteFunction::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no) 251254721Semaste{ 252254721Semaste line_no = 0; 253254721Semaste source_file.Clear(); 254254721Semaste 255254721Semaste if (m_comp_unit == NULL) 256254721Semaste return; 257254721Semaste 258254721Semaste if (m_type != NULL && m_type->GetDeclaration().GetLine() != 0) 259254721Semaste { 260254721Semaste source_file = m_type->GetDeclaration().GetFile(); 261254721Semaste line_no = m_type->GetDeclaration().GetLine(); 262254721Semaste } 263254721Semaste else 264254721Semaste { 265254721Semaste LineTable *line_table = m_comp_unit->GetLineTable(); 266254721Semaste if (line_table == NULL) 267254721Semaste return; 268254721Semaste 269254721Semaste LineEntry line_entry; 270254721Semaste if (line_table->FindLineEntryByAddress (GetAddressRange().GetBaseAddress(), line_entry, NULL)) 271254721Semaste { 272254721Semaste line_no = line_entry.line; 273254721Semaste source_file = line_entry.file; 274254721Semaste } 275254721Semaste } 276254721Semaste} 277254721Semaste 278254721Semastevoid 279254721SemasteFunction::GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no) 280254721Semaste{ 281254721Semaste line_no = 0; 282254721Semaste source_file.Clear(); 283254721Semaste 284254721Semaste // The -1 is kind of cheesy, but I want to get the last line entry for the given function, not the 285254721Semaste // first entry of the next. 286254721Semaste Address scratch_addr(GetAddressRange().GetBaseAddress()); 287254721Semaste scratch_addr.SetOffset (scratch_addr.GetOffset() + GetAddressRange().GetByteSize() - 1); 288254721Semaste 289254721Semaste LineTable *line_table = m_comp_unit->GetLineTable(); 290254721Semaste if (line_table == NULL) 291254721Semaste return; 292254721Semaste 293254721Semaste LineEntry line_entry; 294254721Semaste if (line_table->FindLineEntryByAddress (scratch_addr, line_entry, NULL)) 295254721Semaste { 296254721Semaste line_no = line_entry.line; 297254721Semaste source_file = line_entry.file; 298254721Semaste } 299254721Semaste} 300254721Semaste 301254721SemasteBlock & 302254721SemasteFunction::GetBlock (bool can_create) 303254721Semaste{ 304254721Semaste if (!m_block.BlockInfoHasBeenParsed() && can_create) 305254721Semaste { 306254721Semaste SymbolContext sc; 307254721Semaste CalculateSymbolContext(&sc); 308254721Semaste if (sc.module_sp) 309254721Semaste { 310254721Semaste sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc); 311254721Semaste } 312254721Semaste else 313254721Semaste { 314254721Semaste Host::SystemLog (Host::eSystemLogError, 315254721Semaste "error: unable to find module shared pointer for function '%s' in %s\n", 316254721Semaste GetName().GetCString(), 317254721Semaste m_comp_unit->GetPath().c_str()); 318254721Semaste } 319254721Semaste m_block.SetBlockInfoHasBeenParsed (true, true); 320254721Semaste } 321254721Semaste return m_block; 322254721Semaste} 323254721Semaste 324254721SemasteCompileUnit* 325254721SemasteFunction::GetCompileUnit() 326254721Semaste{ 327254721Semaste return m_comp_unit; 328254721Semaste} 329254721Semaste 330254721Semasteconst CompileUnit* 331254721SemasteFunction::GetCompileUnit() const 332254721Semaste{ 333254721Semaste return m_comp_unit; 334254721Semaste} 335254721Semaste 336254721Semaste 337254721Semastevoid 338254721SemasteFunction::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) 339254721Semaste{ 340254721Semaste Type* func_type = GetType(); 341254721Semaste const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>"; 342254721Semaste 343254721Semaste *s << "id = " << (const UserID&)*this << ", name = \"" << name << "\", range = "; 344254721Semaste 345254721Semaste Address::DumpStyle fallback_style; 346254721Semaste if (level == eDescriptionLevelVerbose) 347254721Semaste fallback_style = Address::DumpStyleModuleWithFileAddress; 348254721Semaste else 349254721Semaste fallback_style = Address::DumpStyleFileAddress; 350254721Semaste GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, fallback_style); 351254721Semaste} 352254721Semaste 353254721Semastevoid 354254721SemasteFunction::Dump(Stream *s, bool show_context) const 355254721Semaste{ 356254721Semaste s->Printf("%p: ", this); 357254721Semaste s->Indent(); 358254721Semaste *s << "Function" << (const UserID&)*this; 359254721Semaste 360254721Semaste m_mangled.Dump(s); 361254721Semaste 362254721Semaste if (m_type) 363254721Semaste { 364254721Semaste s->Printf(", type = %p", m_type); 365254721Semaste } 366254721Semaste else if (m_type_uid != LLDB_INVALID_UID) 367254721Semaste { 368254721Semaste s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid); 369254721Semaste } 370254721Semaste 371254721Semaste s->EOL(); 372254721Semaste // Dump the root object 373254721Semaste if (m_block.BlockInfoHasBeenParsed ()) 374254721Semaste m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context); 375254721Semaste} 376254721Semaste 377254721Semaste 378254721Semastevoid 379254721SemasteFunction::CalculateSymbolContext(SymbolContext* sc) 380254721Semaste{ 381254721Semaste sc->function = this; 382254721Semaste m_comp_unit->CalculateSymbolContext(sc); 383254721Semaste} 384254721Semaste 385254721SemasteModuleSP 386254721SemasteFunction::CalculateSymbolContextModule () 387254721Semaste{ 388254721Semaste SectionSP section_sp (m_range.GetBaseAddress().GetSection()); 389254721Semaste if (section_sp) 390254721Semaste return section_sp->GetModule(); 391254721Semaste 392254721Semaste return this->GetCompileUnit()->GetModule(); 393254721Semaste} 394254721Semaste 395254721SemasteCompileUnit * 396254721SemasteFunction::CalculateSymbolContextCompileUnit () 397254721Semaste{ 398254721Semaste return this->GetCompileUnit(); 399254721Semaste} 400254721Semaste 401254721SemasteFunction * 402254721SemasteFunction::CalculateSymbolContextFunction () 403254721Semaste{ 404254721Semaste return this; 405254721Semaste} 406254721Semaste 407254721Semaste//Symbol * 408254721Semaste//Function::CalculateSymbolContextSymbol () 409254721Semaste//{ 410254721Semaste// return // TODO: find the symbol for the function??? 411254721Semaste//} 412254721Semaste 413254721Semaste 414254721Semastevoid 415254721SemasteFunction::DumpSymbolContext(Stream *s) 416254721Semaste{ 417254721Semaste m_comp_unit->DumpSymbolContext(s); 418254721Semaste s->Printf(", Function{0x%8.8" PRIx64 "}", GetID()); 419254721Semaste} 420254721Semaste 421254721Semastesize_t 422254721SemasteFunction::MemorySize () const 423254721Semaste{ 424254721Semaste size_t mem_size = sizeof(Function) + m_block.MemorySize(); 425254721Semaste return mem_size; 426254721Semaste} 427254721Semaste 428254721Semasteclang::DeclContext * 429254721SemasteFunction::GetClangDeclContext() 430254721Semaste{ 431254721Semaste SymbolContext sc; 432254721Semaste 433254721Semaste CalculateSymbolContext (&sc); 434254721Semaste 435254721Semaste if (!sc.module_sp) 436254721Semaste return NULL; 437254721Semaste 438254721Semaste SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor(); 439254721Semaste 440254721Semaste if (!sym_vendor) 441254721Semaste return NULL; 442254721Semaste 443254721Semaste SymbolFile *sym_file = sym_vendor->GetSymbolFile(); 444254721Semaste 445254721Semaste if (!sym_file) 446254721Semaste return NULL; 447254721Semaste 448254721Semaste return sym_file->GetClangDeclContextForTypeUID (sc, m_uid); 449254721Semaste} 450254721Semaste 451254721SemasteType* 452254721SemasteFunction::GetType() 453254721Semaste{ 454254721Semaste if (m_type == NULL) 455254721Semaste { 456254721Semaste SymbolContext sc; 457254721Semaste 458254721Semaste CalculateSymbolContext (&sc); 459254721Semaste 460254721Semaste if (!sc.module_sp) 461254721Semaste return NULL; 462254721Semaste 463254721Semaste SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor(); 464254721Semaste 465254721Semaste if (sym_vendor == NULL) 466254721Semaste return NULL; 467254721Semaste 468254721Semaste SymbolFile *sym_file = sym_vendor->GetSymbolFile(); 469254721Semaste 470254721Semaste if (sym_file == NULL) 471254721Semaste return NULL; 472254721Semaste 473254721Semaste m_type = sym_file->ResolveTypeUID(m_type_uid); 474254721Semaste } 475254721Semaste return m_type; 476254721Semaste} 477254721Semaste 478254721Semasteconst Type* 479254721SemasteFunction::GetType() const 480254721Semaste{ 481254721Semaste return m_type; 482254721Semaste} 483254721Semaste 484254721SemasteClangASTType 485254721SemasteFunction::GetClangType() 486254721Semaste{ 487254721Semaste Type *function_type = GetType(); 488254721Semaste if (function_type) 489254721Semaste return function_type->GetClangFullType(); 490254721Semaste return ClangASTType(); 491254721Semaste} 492254721Semaste 493254721Semasteuint32_t 494254721SemasteFunction::GetPrologueByteSize () 495254721Semaste{ 496254721Semaste if (m_prologue_byte_size == 0 && m_flags.IsClear(flagsCalculatedPrologueSize)) 497254721Semaste { 498254721Semaste m_flags.Set(flagsCalculatedPrologueSize); 499254721Semaste LineTable* line_table = m_comp_unit->GetLineTable (); 500254721Semaste if (line_table) 501254721Semaste { 502254721Semaste LineEntry first_line_entry; 503254721Semaste uint32_t first_line_entry_idx = UINT32_MAX; 504254721Semaste if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), first_line_entry, &first_line_entry_idx)) 505254721Semaste { 506254721Semaste // Make sure the first line entry isn't already the end of the prologue 507254721Semaste addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS; 508254721Semaste if (first_line_entry.is_prologue_end) 509254721Semaste { 510254721Semaste prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress(); 511254721Semaste } 512254721Semaste else 513254721Semaste { 514254721Semaste // Check the first few instructions and look for one that has 515254721Semaste // is_prologue_end set to true. 516254721Semaste const uint32_t last_line_entry_idx = first_line_entry_idx + 6; 517254721Semaste for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx) 518254721Semaste { 519254721Semaste LineEntry line_entry; 520254721Semaste if (line_table->GetLineEntryAtIndex (idx, line_entry)) 521254721Semaste { 522254721Semaste if (line_entry.is_prologue_end) 523254721Semaste { 524254721Semaste prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress(); 525254721Semaste break; 526254721Semaste } 527254721Semaste } 528254721Semaste } 529254721Semaste } 530254721Semaste 531254721Semaste // If we didn't find the end of the prologue in the line tables, 532254721Semaste // then just use the end address of the first line table entry 533254721Semaste if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) 534254721Semaste { 535254721Semaste // Check the first few instructions and look for one that has 536254721Semaste // a line number that's different than the first entry. 537254721Semaste const uint32_t last_line_entry_idx = first_line_entry_idx + 6; 538254721Semaste for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx) 539254721Semaste { 540254721Semaste LineEntry line_entry; 541254721Semaste if (line_table->GetLineEntryAtIndex (idx, line_entry)) 542254721Semaste { 543254721Semaste if (line_entry.line != first_line_entry.line) 544254721Semaste { 545254721Semaste prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress(); 546254721Semaste break; 547254721Semaste } 548254721Semaste } 549254721Semaste } 550254721Semaste 551254721Semaste if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) 552254721Semaste { 553254721Semaste prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize(); 554254721Semaste } 555254721Semaste } 556254721Semaste const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress(); 557254721Semaste const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize(); 558254721Semaste 559254721Semaste // Verify that this prologue end file address in the function's 560254721Semaste // address range just to be sure 561254721Semaste if (func_start_file_addr < prologue_end_file_addr && prologue_end_file_addr < func_end_file_addr) 562254721Semaste { 563254721Semaste m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr; 564254721Semaste } 565254721Semaste } 566254721Semaste } 567254721Semaste } 568254721Semaste return m_prologue_byte_size; 569254721Semaste} 570254721Semaste 571254721Semaste 572254721Semaste 573