Changeset View
Standalone View
lldb/include/lldb/Symbol/Function.h
Show All 10 Lines | |||||
#define liblldb_Function_h_ | #define liblldb_Function_h_ | ||||
#include "lldb/Core/AddressRange.h" | #include "lldb/Core/AddressRange.h" | ||||
#include "lldb/Core/Mangled.h" | #include "lldb/Core/Mangled.h" | ||||
#include "lldb/Expression/DWARFExpression.h" | #include "lldb/Expression/DWARFExpression.h" | ||||
#include "lldb/Symbol/Block.h" | #include "lldb/Symbol/Block.h" | ||||
#include "lldb/Symbol/Declaration.h" | #include "lldb/Symbol/Declaration.h" | ||||
#include "lldb/Utility/UserID.h" | #include "lldb/Utility/UserID.h" | ||||
#include "llvm/ADT/ArrayRef.h" | |||||
namespace lldb_private { | namespace lldb_private { | ||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
/// @class FunctionInfo Function.h "lldb/Symbol/Function.h" | /// @class FunctionInfo Function.h "lldb/Symbol/Function.h" | ||||
/// A class that contains generic function information. | /// A class that contains generic function information. | ||||
/// | /// | ||||
/// This provides generic function information that gets reused between inline | /// This provides generic function information that gets reused between inline | ||||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | private: | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
// Member variables. | // Member variables. | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
Mangled m_mangled; ///< Mangled inlined function name (can be empty if there | Mangled m_mangled; ///< Mangled inlined function name (can be empty if there | ||||
///is no mangled information). | ///is no mangled information). | ||||
Declaration m_call_decl; | Declaration m_call_decl; | ||||
}; | }; | ||||
class Function; | |||||
//---------------------------------------------------------------------- | |||||
/// @class CallEdge Function.h "lldb/Symbol/Function.h" | |||||
/// | |||||
/// Represent a call made within a Function. This can be used to find a path | |||||
/// in the call graph between two functions. | |||||
//---------------------------------------------------------------------- | |||||
class CallEdge { | |||||
public: | |||||
CallEdge(const char *mangled_name, lldb::addr_t return_pc); | |||||
aprantl: Does this also work for C functions? If yes, would `symbol_name` be a more accurate description? | |||||
Not Done ReplyInline ActionsYes, C functions are handled. I'll use "symbol_name", hopefully that makes it clearer. vsk: Yes, C functions are handled. I'll use "symbol_name", hopefully that makes it clearer. | |||||
Not Done ReplyInline ActionsGreat question. No, a symbol name is not necessarily globally unique. Prior to C11, the one-definition-rule doesn't apply. Even with the ODR, a private symbol in a shared library may have the same name as a strong definition in the main executable. I haven't tried to disambiguate ODR conflicts in this patch. What happens when a conflict occurs is: FindFunctionSymbols prioritizes the symbol in the main executable, and if the call edge's return PC doesn't exactly match what's in the register state we decline to create any artificial frames. I.e. in the presence of ODR conflicts, we only present artificial frames when we're 100% sure they are accurate. Handling ODR conflicts is a 'to do', though. I'll make an explicit note of that here. vsk: Great question. No, a symbol name is not necessarily globally unique. Prior to C11, the one… | |||||
Not Done ReplyInline ActionsThanks! It might be interesting to grep through an XNU dsym to see just how common conflicts are in typical C code. aprantl: Thanks! It might be interesting to grep through an XNU dsym to see just how common conflicts… | |||||
Not Done ReplyInline ActionsOf a total of ~27,000 function names in xnu, 140 names were duplicates. In every case I spot-checked, a subprogram with a duplicate AT_name had a unique AT_linkage_name. So, well under 0.5% in that project. vsk: Of a total of ~27,000 function names in xnu, 140 names were duplicates. In every case I spot… | |||||
CallEdge(CallEdge &&) = default; | |||||
CallEdge &operator=(CallEdge &&) = default; | |||||
/// Get the callee's definition. | |||||
/// | |||||
/// Note that this might lazily invoke the DWARF parser. | |||||
Function *GetCallee(ModuleList &images); | |||||
/// Get the load PC address of the instruction which executes after the call | |||||
/// returns. Returns LLDB_INVALID_ADDRESS iff this is a tail call. \p caller | |||||
/// is the Function containing this call, and \p target is the Target which | |||||
/// made the call. | |||||
lldb::addr_t GetReturnPCAddress(Function &caller, Target &target) const; | |||||
/// Like \ref GetReturnPCAddress, but returns an unresolved file address. | |||||
lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; } | |||||
private: | |||||
void ParseSymbolFileAndResolve(ModuleList &images); | |||||
/// Whether or not an attempt was made to find the callee's definition. | |||||
bool resolved; | |||||
/// Either the callee's mangled name or its definition, discriminated by | |||||
/// \ref resolved. | |||||
union { | |||||
llvm::PointerUnion ? aprantl: `llvm::PointerUnion` ? | |||||
Not Done ReplyInline ActionsIt's not possible to use PointerUnion here because const char * has 1-byte alignment. There's no space in the pointer to store a discriminator bit. vsk: It's not possible to use PointerUnion here because `const char *` has 1-byte alignment. There's… | |||||
Not Done ReplyInline ActionsGood point! aprantl: Good point! | |||||
const char *mangled_name; | |||||
Function *def; | |||||
} lazy_callee; | |||||
/// An invalid address if this is a tail call. Otherwise, the return PC for | |||||
/// the call. Note that this is a file address which must be resolved. | |||||
lldb::addr_t return_pc; | |||||
DISALLOW_COPY_AND_ASSIGN(CallEdge); | |||||
}; | |||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
/// @class Function Function.h "lldb/Symbol/Function.h" | /// @class Function Function.h "lldb/Symbol/Function.h" | ||||
/// A class that describes a function. | /// A class that describes a function. | ||||
/// | /// | ||||
/// Functions belong to CompileUnit objects (Function::m_comp_unit), have | /// Functions belong to CompileUnit objects (Function::m_comp_unit), have | ||||
/// unique user IDs (Function::UserID), know how to reconstruct their symbol | /// unique user IDs (Function::UserID), know how to reconstruct their symbol | ||||
/// context (Function::SymbolContextScope), have a specific function type | /// context (Function::SymbolContextScope), have a specific function type | ||||
/// (Function::m_type_uid), have a simple method name (FunctionInfo::m_name), | /// (Function::m_type_uid), have a simple method name (FunctionInfo::m_name), | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | public: | ||||
/// The source file. | /// The source file. | ||||
/// | /// | ||||
/// @param[out] line_no | /// @param[out] line_no | ||||
/// The line number. | /// The line number. | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no); | void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no); | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
/// Get the outgoing call edges from this function, sorted by their return | |||||
/// PC addresses (in increasing order). | |||||
//------------------------------------------------------------------ | |||||
llvm::MutableArrayRef<CallEdge> GetCallEdges(); | |||||
//------------------------------------------------------------------ | |||||
/// Get the outgoing tail-calling edges from this function. If none exist, | |||||
Typo: tail-calling sgraenitz: Typo: tail-calling | |||||
/// return None. | |||||
//------------------------------------------------------------------ | |||||
llvm::MutableArrayRef<CallEdge> GetTailCallingEdges(); | |||||
//------------------------------------------------------------------ | |||||
/// Get accessor for the block list. | /// Get accessor for the block list. | ||||
/// | /// | ||||
/// @return | /// @return | ||||
/// The block list object that describes all lexical blocks | /// The block list object that describes all lexical blocks | ||||
/// in the function. | /// in the function. | ||||
/// | /// | ||||
/// @see BlockList | /// @see BlockList | ||||
//------------------------------------------------------------------ | //------------------------------------------------------------------ | ||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | protected: | ||||
Block m_block; ///< All lexical blocks contained in this function. | Block m_block; ///< All lexical blocks contained in this function. | ||||
AddressRange m_range; ///< The function address range that covers the widest | AddressRange m_range; ///< The function address range that covers the widest | ||||
///range needed to contain all blocks | ///range needed to contain all blocks | ||||
DWARFExpression m_frame_base; ///< The frame base expression for variables | DWARFExpression m_frame_base; ///< The frame base expression for variables | ||||
///that are relative to the frame pointer. | ///that are relative to the frame pointer. | ||||
Flags m_flags; | Flags m_flags; | ||||
uint32_t | uint32_t | ||||
m_prologue_byte_size; ///< Compute the prologue size once and cache it | m_prologue_byte_size; ///< Compute the prologue size once and cache it | ||||
bool m_call_edges_resolved = false; ///< Whether call site info has been | |||||
/// parsed. | |||||
std::vector<CallEdge> m_call_edges; ///< Outgoing call edges. | |||||
private: | private: | ||||
DISALLOW_COPY_AND_ASSIGN(Function); | DISALLOW_COPY_AND_ASSIGN(Function); | ||||
}; | }; | ||||
} // namespace lldb_private | } // namespace lldb_private | ||||
#endif // liblldb_Function_h_ | #endif // liblldb_Function_h_ |
Does this also work for C functions? If yes, would symbol_name be a more accurate description?
Is this pointer globally unique in the program, or can two mangled names appear in a legal C program that don't refer to the same function?