1 //===-- SymbolContext.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SYMBOL_SYMBOLCONTEXT_H 10 #define LLDB_SYMBOL_SYMBOLCONTEXT_H 11 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 #include "lldb/Core/Address.h" 17 #include "lldb/Core/Mangled.h" 18 #include "lldb/Symbol/LineEntry.h" 19 #include "lldb/Utility/Iterable.h" 20 #include "lldb/Utility/Stream.h" 21 #include "lldb/lldb-private.h" 22 23 namespace lldb_private { 24 25 class SymbolContextScope; 26 27 /// \class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" Defines 28 /// a symbol context baton that can be handed other debug core functions. 29 /// 30 /// Many debugger functions require a context when doing lookups. This class 31 /// provides a common structure that can be used as the result of a query that 32 /// can contain a single result. Examples of such queries include 33 /// \li Looking up a load address. 34 class SymbolContext { 35 public: 36 /// Default constructor. 37 /// 38 /// Initialize all pointer members to nullptr and all struct members to 39 /// their default state. 40 SymbolContext(); 41 42 /// Construct with an object that knows how to reconstruct its symbol 43 /// context. 44 /// 45 /// \param[in] sc_scope 46 /// A symbol context scope object that knows how to reconstruct 47 /// it's context. 48 explicit SymbolContext(SymbolContextScope *sc_scope); 49 50 /// Construct with module, and optional compile unit, function, block, line 51 /// table, line entry and symbol. 52 /// 53 /// Initialize all pointer to the specified values. 54 /// 55 /// \param[in] module_sp 56 /// A Module pointer to the module for this context. 57 /// 58 /// \param[in] comp_unit 59 /// A CompileUnit pointer to the compile unit for this context. 60 /// 61 /// \param[in] function 62 /// A Function pointer to the function for this context. 63 /// 64 /// \param[in] block 65 /// A Block pointer to the deepest block for this context. 66 /// 67 /// \param[in] line_entry 68 /// A LineEntry pointer to the line entry for this context. 69 /// 70 /// \param[in] symbol 71 /// A Symbol pointer to the symbol for this context. 72 explicit SymbolContext(const lldb::TargetSP &target_sp, 73 const lldb::ModuleSP &module_sp, 74 CompileUnit *comp_unit = nullptr, 75 Function *function = nullptr, Block *block = nullptr, 76 LineEntry *line_entry = nullptr, 77 Symbol *symbol = nullptr); 78 79 // This version sets the target to a NULL TargetSP if you don't know it. 80 explicit SymbolContext(const lldb::ModuleSP &module_sp, 81 CompileUnit *comp_unit = nullptr, 82 Function *function = nullptr, Block *block = nullptr, 83 LineEntry *line_entry = nullptr, 84 Symbol *symbol = nullptr); 85 86 ~SymbolContext(); 87 88 /// Clear the object's state. 89 /// 90 /// Resets all pointer members to nullptr, and clears any class objects to 91 /// their default state. 92 void Clear(bool clear_target); 93 94 /// Dump the stop context in this object to a Stream. 95 /// 96 /// Dump the best description of this object to the stream. The information 97 /// displayed depends on the amount and quality of the information in this 98 /// context. If a module, function, file and line number are available, they 99 /// will be dumped. If only a module and function or symbol name with offset 100 /// is available, that will be output. Else just the address at which the 101 /// target was stopped will be displayed. 102 /// 103 /// \param[in] s 104 /// The stream to which to dump the object description. 105 /// 106 /// \param[in] so_addr 107 /// The resolved section offset address. 108 /// 109 /// \param[in] show_fullpaths 110 /// When printing file paths (with the Module), whether the 111 /// base name of the Module should be printed or the full path. 112 /// 113 /// \param[in] show_module 114 /// Whether the module name should be printed followed by a 115 /// grave accent "`" character. 116 /// 117 /// \param[in] show_inlined_frames 118 /// If a given pc is in inlined function(s), whether the inlined 119 /// functions should be printed on separate lines in addition to 120 /// the concrete function containing the pc. 121 /// 122 /// \param[in] show_function_arguments 123 /// If false, this method will try to elide the function argument 124 /// types when printing the function name. This may be ambiguous 125 /// for languages that have function overloading - but it may 126 /// make the "function name" too long to include all the argument 127 /// types. 128 /// 129 /// \param[in] show_function_name 130 /// Normally this should be true - the function/symbol name should 131 /// be printed. In disassembly formatting, where we want a format 132 /// like "<*+36>", this should be false and "*" will be printed 133 /// instead. 134 /// 135 /// \param[in] show_inline_callsite_line_info 136 /// When processing an inline block, the line info of the callsite 137 /// is dumped if this flag is \b true, otherwise the line info 138 /// of the actual inlined function is dumped. 139 /// 140 /// \param[in] pattern 141 /// An optional regex pattern to match against the stop context 142 /// description. If specified, parts of the description matching this 143 /// pattern may be highlighted or processed differently. If this parameter 144 /// is an empty string or not provided, no highlighting is applied. 145 /// 146 /// \return 147 /// \b true if some text was dumped, \b false otherwise. 148 bool DumpStopContext( 149 Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, 150 bool show_fullpaths, bool show_module, bool show_inlined_frames, 151 bool show_function_arguments, bool show_function_name, 152 bool show_function_display_name = false, 153 std::optional<Stream::HighlightSettings> settings = std::nullopt) const; 154 155 /// Get the address range contained within a symbol context. 156 /// 157 /// Address range priority is as follows: 158 /// - line_entry address range if line_entry is valid and 159 /// eSymbolContextLineEntry is set in \a scope 160 /// - block address range if block is not nullptr and eSymbolContextBlock 161 /// is set in \a scope 162 /// - function address range if function is not nullptr and 163 /// eSymbolContextFunction is set in \a scope 164 /// - symbol address range if symbol is not nullptr and 165 /// eSymbolContextSymbol is set in \a scope 166 /// 167 /// \param[in] scope 168 /// A mask bits from the \b SymbolContextItem enum telling this function 169 /// which address ranges it can use when trying to extract one from 170 /// the valid (non-nullptr) symbol context classes. 171 /// 172 /// \param[in] range_idx 173 /// The address range index to grab. Since many functions and 174 /// blocks are not always contiguous, they may have more than 175 /// one address range. 176 /// 177 /// \param[in] use_inline_block_range 178 /// If \a scope has the eSymbolContextBlock bit set, and there 179 /// is a valid block in the symbol context, return the block 180 /// address range for the containing inline function block, not 181 /// the deepest most block. This allows us to extract information 182 /// for the address range of the inlined function block, not 183 /// the deepest lexical block. 184 /// 185 /// \param[out] range 186 /// An address range object that will be filled in if \b true 187 /// is returned. 188 /// 189 /// \return 190 /// \b True if this symbol context contains items that describe 191 /// an address range, \b false otherwise. 192 bool GetAddressRange(uint32_t scope, uint32_t range_idx, 193 bool use_inline_block_range, AddressRange &range) const; 194 195 /// Get the address of the function or symbol represented by this symbol 196 /// context. 197 /// 198 /// If both fields are present, the address of the function is returned. If 199 /// both are empty, the result is an invalid address. 200 Address GetFunctionOrSymbolAddress() const; 201 202 llvm::Error GetAddressRangeFromHereToEndLine(uint32_t end_line, 203 AddressRange &range); 204 205 /// Find the best global data symbol visible from this context. 206 /// 207 /// Symbol priority is: 208 /// - extern symbol in the current module if there is one 209 /// - non-extern symbol in the current module if there is one 210 /// - extern symbol in the target 211 /// - non-extern symbol in the target 212 /// It is an error if the highest-priority result is ambiguous. 213 /// 214 /// \param[in] name 215 /// The name of the symbol to search for. 216 /// 217 /// \param[out] error 218 /// An error that will be populated with a message if there was an 219 /// ambiguous result. The error will not be populated if no result 220 /// was found. 221 /// 222 /// \return 223 /// The symbol that was found, or \b nullptr if none was found. 224 const Symbol *FindBestGlobalDataSymbol(ConstString name, Status &error); 225 226 void GetDescription( 227 Stream *s, lldb::DescriptionLevel level, Target *target, 228 std::optional<Stream::HighlightSettings> settings = std::nullopt) const; 229 230 uint32_t GetResolvedMask() const; 231 232 lldb::LanguageType GetLanguage() const; 233 234 /// Find a block that defines the function represented by this symbol 235 /// context. 236 /// 237 /// If this symbol context points to a block that is an inlined function, or 238 /// is contained within an inlined function, the block that defines the 239 /// inlined function is returned. 240 /// 241 /// If this symbol context has no block in it, or the block is not itself an 242 /// inlined function block or contained within one, we return the top level 243 /// function block. 244 /// 245 /// This is a handy function to call when you want to get the block whose 246 /// variable list will include the arguments for the function that is 247 /// represented by this symbol context (whether the function is an inline 248 /// function or not). 249 /// 250 /// \return 251 /// The block object pointer that defines the function that is 252 /// represented by this symbol context object, nullptr otherwise. 253 Block *GetFunctionBlock(); 254 255 /// Determines the name of the instance variable for the this decl context. 256 /// 257 /// For C++ the name is "this", for Objective-C the name is "self". 258 /// 259 /// \return 260 /// Returns a StringRef for the name of the instance variable. 261 llvm::StringRef GetInstanceVariableName(); 262 263 /// Sorts the types in TypeMap according to SymbolContext to TypeList 264 /// 265 void SortTypeList(TypeMap &type_map, TypeList &type_list) const; 266 267 /// Find a name of the innermost function for the symbol context. 268 /// 269 /// For instance, if the symbol context contains an inlined block, it will 270 /// return the inlined function name. 271 /// 272 /// \return 273 /// The name of the function represented by this symbol context. 274 ConstString GetFunctionName( 275 Mangled::NamePreference preference = Mangled::ePreferDemangled) const; 276 277 /// Get the line entry that corresponds to the function. 278 /// 279 /// If the symbol context contains an inlined block, the line entry for the 280 /// start address of the inlined function will be returned, otherwise the 281 /// line entry for the start address of the function will be returned. This 282 /// can be used after doing a Module::FindFunctions(...) or 283 /// ModuleList::FindFunctions(...) call in order to get the correct line 284 /// table information for the symbol context. it will return the inlined 285 /// function name. 286 LineEntry GetFunctionStartLineEntry() const; 287 288 /// Find the block containing the inlined block that contains this block. 289 /// 290 /// For instance, if the symbol context contains an inlined block, it will 291 /// return the inlined function name. 292 /// 293 /// \param[in] curr_frame_pc 294 /// The address within the block of this object. 295 /// 296 /// \param[out] next_frame_sc 297 /// A new symbol context that does what the title says it does. 298 /// 299 /// \param[out] inlined_frame_addr 300 /// This is what you should report as the PC in \a next_frame_sc. 301 /// 302 /// \return 303 /// \b true if this SymbolContext specifies a block contained in an 304 /// inlined block. If this returns \b true, \a next_frame_sc and 305 /// \a inlined_frame_addr will be filled in correctly. 306 bool GetParentOfInlinedScope(const Address &curr_frame_pc, 307 SymbolContext &next_frame_sc, 308 Address &inlined_frame_addr) const; 309 310 /// If available, will return the function name according to the specified 311 /// mangling preference. If this object represents an inlined function, 312 /// returns the name of the inlined function. Returns nullptr if no function 313 /// name could be determined. 314 Mangled GetPossiblyInlinedFunctionName() const; 315 316 // Member variables 317 lldb::TargetSP target_sp; ///< The Target for a given query 318 lldb::ModuleSP module_sp; ///< The Module for a given query 319 CompileUnit *comp_unit = nullptr; ///< The CompileUnit for a given query 320 Function *function = nullptr; ///< The Function for a given query 321 Block *block = nullptr; ///< The Block for a given query 322 LineEntry line_entry; ///< The LineEntry for a given query 323 Symbol *symbol = nullptr; ///< The Symbol for a given query 324 Variable *variable = 325 nullptr; ///< The global variable matching the given query 326 }; 327 328 class SymbolContextSpecifier { 329 public: 330 enum SpecificationType { 331 eNothingSpecified = 0, 332 eModuleSpecified = 1 << 0, 333 eFileSpecified = 1 << 1, 334 eLineStartSpecified = 1 << 2, 335 eLineEndSpecified = 1 << 3, 336 eFunctionSpecified = 1 << 4, 337 eClassOrNamespaceSpecified = 1 << 5, 338 eAddressRangeSpecified = 1 << 6 339 }; 340 341 // This one produces a specifier that matches everything... 342 SymbolContextSpecifier(const lldb::TargetSP &target_sp); 343 344 ~SymbolContextSpecifier(); 345 346 bool AddSpecification(const char *spec_string, SpecificationType type); 347 348 bool AddLineSpecification(uint32_t line_no, SpecificationType type); 349 350 void Clear(); 351 352 bool SymbolContextMatches(const SymbolContext &sc); 353 354 bool AddressMatches(lldb::addr_t addr); 355 356 void GetDescription(Stream *s, lldb::DescriptionLevel level) const; 357 358 private: 359 lldb::TargetSP m_target_sp; 360 std::string m_module_spec; 361 lldb::ModuleSP m_module_sp; 362 std::unique_ptr<FileSpec> m_file_spec_up; 363 size_t m_start_line; 364 size_t m_end_line; 365 std::string m_function_spec; 366 std::string m_class_name; 367 std::unique_ptr<AddressRange> m_address_range_up; 368 uint32_t m_type; // Or'ed bits from SpecificationType 369 }; 370 371 /// \class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h" 372 /// Defines a list of symbol context objects. 373 /// 374 /// This class provides a common structure that can be used to contain the 375 /// result of a query that can contain a multiple results. Examples of such 376 /// queries include: 377 /// \li Looking up a function by name. 378 /// \li Finding all addresses for a specified file and line number. 379 class SymbolContextList { 380 public: 381 /// Default constructor. 382 /// 383 /// Initialize with an empty list. 384 SymbolContextList(); 385 386 /// Destructor. 387 ~SymbolContextList(); 388 389 /// Append a new symbol context to the list. 390 /// 391 /// \param[in] sc 392 /// A symbol context to append to the list. 393 void Append(const SymbolContext &sc); 394 395 void Append(const SymbolContextList &sc_list); 396 397 bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function); 398 399 uint32_t AppendIfUnique(const SymbolContextList &sc_list, 400 bool merge_symbol_into_function); 401 402 /// Clear the object's state. 403 /// 404 /// Clears the symbol context list. 405 void Clear(); 406 407 /// Dump a description of this object to a Stream. 408 /// 409 /// Dump a description of the contents of each symbol context in the list to 410 /// the supplied stream \a s. 411 /// 412 /// \param[in] s 413 /// The stream to which to dump the object description. 414 void Dump(Stream *s, Target *target) const; 415 416 /// Get accessor for a symbol context at index \a idx. 417 /// 418 /// Dump a description of the contents of each symbol context in the list to 419 /// the supplied stream \a s. 420 /// 421 /// \param[in] idx 422 /// The zero based index into the symbol context list. 423 /// 424 /// \param[out] sc 425 /// A reference to the symbol context to fill in. 426 /// 427 /// \return 428 /// Returns \b true if \a idx was a valid index into this 429 /// symbol context list and \a sc was filled in, \b false 430 /// otherwise. 431 bool GetContextAtIndex(size_t idx, SymbolContext &sc) const; 432 433 /// Direct reference accessor for a symbol context at index \a idx. 434 /// 435 /// The index \a idx must be a valid index, no error checking will be done 436 /// to ensure that it is valid. 437 /// 438 /// \param[in] idx 439 /// The zero based index into the symbol context list. 440 /// 441 /// \return 442 /// A const reference to the symbol context to fill in. 443 SymbolContext &operator[](size_t idx) { return m_symbol_contexts[idx]; } 444 445 const SymbolContext &operator[](size_t idx) const { 446 return m_symbol_contexts[idx]; 447 } 448 449 bool RemoveContextAtIndex(size_t idx); 450 451 /// Get accessor for a symbol context list size. 452 /// 453 /// \return 454 /// Returns the number of symbol context objects in the list. 455 uint32_t GetSize() const; 456 457 bool IsEmpty() const; 458 459 uint32_t NumLineEntriesWithLine(uint32_t line) const; 460 461 void GetDescription(Stream *s, lldb::DescriptionLevel level, 462 Target *target) const; 463 464 protected: 465 typedef std::vector<SymbolContext> 466 collection; ///< The collection type for the list. 467 typedef collection::const_iterator const_iterator; 468 469 // Member variables. 470 collection m_symbol_contexts; ///< The list of symbol contexts. 471 472 public: begin()473 const_iterator begin() const { return m_symbol_contexts.begin(); } end()474 const_iterator end() const { return m_symbol_contexts.end(); } 475 476 typedef llvm::iterator_range<collection::const_iterator> 477 SymbolContextIterable; SymbolContexts()478 SymbolContextIterable SymbolContexts() { 479 return SymbolContextIterable(m_symbol_contexts); 480 } 481 }; 482 483 bool operator==(const SymbolContext &lhs, const SymbolContext &rhs); 484 bool operator!=(const SymbolContext &lhs, const SymbolContext &rhs); 485 486 bool operator==(const SymbolContextList &lhs, const SymbolContextList &rhs); 487 bool operator!=(const SymbolContextList &lhs, const SymbolContextList &rhs); 488 489 } // namespace lldb_private 490 491 #endif // LLDB_SYMBOL_SYMBOLCONTEXT_H 492