diff options
Diffstat (limited to 'lldb/include')
204 files changed, 34800 insertions, 0 deletions
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h new file mode 100644 index 00000000000..729d393f5ef --- /dev/null +++ b/lldb/include/lldb/API/LLDB.h @@ -0,0 +1,49 @@ +//===-- LLDB.h --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_LLDB_h_ +#define LLDB_LLDB_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include <LLDB/SBDefines.h> +#include <LLDB/SBAddress.h> +#include <LLDB/SBBlock.h> +#include <LLDB/SBBreakpoint.h> +#include <LLDB/SBBreakpointLocation.h> +#include <LLDB/SBBroadcaster.h> +#include <LLDB/SBCommandContext.h> +#include <LLDB/SBCommandInterpreter.h> +#include <LLDB/SBCommandReturnObject.h> +#include <LLDB/SBCommunication.h> +#include <LLDB/SBCompileUnit.h> +#include <LLDB/SBDebugger.h> +#include <LLDB/SBError.h> +#include <LLDB/SBEvent.h> +#include <LLDB/SBFileSpec.h> +#include <LLDB/SBFrame.h> +#include <LLDB/SBFunction.h> +#include <LLDB/SBHostOS.h> +#include <LLDB/SBInputReader.h> +#include <LLDB/SBLineEntry.h> +#include <LLDB/SBListener.h> +#include <LLDB/SBModule.h> +#include <LLDB/SBProcess.h> +#include <LLDB/SBSourceManager.h> +#include <LLDB/SBSymbol.h> +#include <LLDB/SBSymbolContext.h> +#include <LLDB/SBTarget.h> +#include <LLDB/SBThread.h> +#include <LLDB/SBType.h> +#include <LLDB/SBValue.h> +#include <LLDB/SBValueList.h> + +#endif // LLDB_LLDB_h_ diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h new file mode 100644 index 00000000000..4f0195aa561 --- /dev/null +++ b/lldb/include/lldb/API/SBAddress.h @@ -0,0 +1,75 @@ +//===-- SBAddress.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBAddress_h_ +#define LLDB_SBAddress_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBAddress +{ +public: + + SBAddress (); + + SBAddress (const lldb::SBAddress &rhs); + + ~SBAddress (); + +#ifndef SWIG + const SBAddress & + operator = (const SBAddress &rhs); +#endif + + bool + IsValid () const; + + addr_t + GetFileAddress () const; + + addr_t + GetLoadAddress (const lldb::SBProcess &process) const; + + bool + OffsetAddress (addr_t offset); + +protected: + + friend class SBFrame; + friend class SBLineEntry; + friend class SBSymbolContext; + friend class SBThread; + +#ifndef SWIG + + const lldb_private::Address * + operator->() const; + + const lldb_private::Address & + operator*() const; + +#endif + + + SBAddress (const lldb_private::Address *lldb_object_ptr); + + void + SetAddress (const lldb_private::Address *lldb_object_ptr); + +private: + + std::auto_ptr<lldb_private::Address> m_lldb_object_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBAddress_h_ diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h new file mode 100644 index 00000000000..b8eef00d72e --- /dev/null +++ b/lldb/include/lldb/API/SBBlock.h @@ -0,0 +1,44 @@ +//===-- SBBlock.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBBlock_h_ +#define LLDB_SBBlock_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBBlock +{ +public: + + SBBlock (); + + ~SBBlock (); + + bool + IsValid () const; + + void + AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list); + +private: + friend class SBFrame; + friend class SBSymbolContext; + + SBBlock (lldb_private::Block *lldb_object_ptr); + + + lldb_private::Block *m_lldb_object_ptr; +}; + + +} // namespace lldb + +#endif // LLDB_SBBlock_h_ diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h new file mode 100644 index 00000000000..71394749e0a --- /dev/null +++ b/lldb/include/lldb/API/SBBreakpoint.h @@ -0,0 +1,129 @@ +//===-- SBBreakpoint.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBBreakpoint_h_ +#define LLDB_SBBreakpoint_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBBreakpoint +{ +public: + + typedef bool (*BreakpointHitCallback) (void *baton, + SBProcess &process, + SBThread &thread, + lldb::SBBreakpointLocation &location); + + SBBreakpoint (); + + SBBreakpoint (const lldb::SBBreakpoint& rhs); + + ~SBBreakpoint(); + +#ifndef SWIG + const SBBreakpoint & + operator = (const SBBreakpoint& rhs); +#endif + + break_id_t + GetID () const; + + bool + IsValid() const; + + void + Dump (FILE *f); + + void + ClearAllBreakpointSites (); + + lldb::SBBreakpointLocation + FindLocationByAddress (lldb::addr_t vm_addr); + + lldb::break_id_t + FindLocationIDByAddress (lldb::addr_t vm_addr); + + lldb::SBBreakpointLocation + FindLocationByID (lldb::break_id_t bp_loc_id); + + lldb::SBBreakpointLocation + GetLocationAtIndex (uint32_t index); + + void + ListLocations (FILE *, const char *description_level = "full"); + + void + SetEnabled (bool enable); + + bool + IsEnabled (); + + void + SetIgnoreCount (int32_t count); + + int32_t + GetIgnoreCount () const; + + void + SetThreadID (lldb::tid_t sb_thread_id); + + lldb::tid_t + GetThreadID (); + + void + SetCallback (BreakpointHitCallback callback, void *baton); + + size_t + GetNumResolvedLocations() const; + + size_t + GetNumLocations() const; + + void + GetDescription (FILE *, const char *description_level, bool describe_locations = false); + + + +private: + friend class SBBreakpointLocation; + friend class SBTarget; + + SBBreakpoint (const lldb::BreakpointSP &bp_sp); + +#ifndef SWIG + + lldb_private::Breakpoint * + operator->() const; + + lldb_private::Breakpoint * + get() const; + + lldb::BreakpointSP & + operator *(); + + const lldb::BreakpointSP & + operator *() const; + +#endif + + static bool + PrivateBreakpointHitCallback (void *baton, + lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + lldb::BreakpointSP m_break_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBBreakpoint_h_ diff --git a/lldb/include/lldb/API/SBBreakpointLocation.h b/lldb/include/lldb/API/SBBreakpointLocation.h new file mode 100644 index 00000000000..836995676a3 --- /dev/null +++ b/lldb/include/lldb/API/SBBreakpointLocation.h @@ -0,0 +1,73 @@ +//===-- SBBreakpointLocation.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBBreakpointLocation_h_ +#define LLDB_SBBreakpointLocation_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBBreakpoint.h> + +namespace lldb { + +class SBBreakpointLocation +{ +public: + + SBBreakpointLocation (); + + ~SBBreakpointLocation (); + + bool + IsValid() const; + + lldb::addr_t + GetLoadAddress (); + + void + SetEnabled(bool enabled); + + bool + IsEnabled (); + + int32_t + GetIgnoreCount (); + + void + SetIgnoreCount (int32_t n); + + void + SetThreadID (lldb::tid_t thread_id); + + lldb::tid_t + GetThreadID (); + + bool + IsResolved (); + + void + GetDescription (FILE *f, const char *description_level); + + SBBreakpoint + GetBreakpoint (); + +private: + friend class SBBreakpoint; + + SBBreakpointLocation (const lldb::BreakpointLocationSP &break_loc_sp); + + void + SetLocation (const lldb::BreakpointLocationSP &break_loc_sp); + + lldb::BreakpointLocationSP m_break_loc_sp; + +}; + +} // namespace lldb + +#endif // LLDB_SBBreakpointLocation_h_ diff --git a/lldb/include/lldb/API/SBBroadcaster.h b/lldb/include/lldb/API/SBBroadcaster.h new file mode 100644 index 00000000000..94baef2f015 --- /dev/null +++ b/lldb/include/lldb/API/SBBroadcaster.h @@ -0,0 +1,83 @@ +//===-- SBBroadcaster.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBBroadcaster_h_ +#define LLDB_SBBroadcaster_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBBroadcaster +{ +public: + SBBroadcaster (); + + SBBroadcaster (const char *name); + + ~SBBroadcaster(); + + bool + IsValid () const; + + void + BroadcastEventByType (uint32_t event_type, bool unique = false); + + void + BroadcastEvent (const lldb::SBEvent &event, bool unique = false); + + void + AddInitialEventsToListener (const lldb::SBListener &listener, uint32_t requested_events); + + uint32_t + AddListener (const lldb::SBListener &listener, uint32_t event_mask); + + const char * + GetName (); + + bool + EventTypeHasListeners (uint32_t event_type); + + bool + RemoveListener (const lldb::SBListener &listener, uint32_t event_mask = UINT32_MAX); + +#ifndef SWIG + bool + operator == (const lldb::SBBroadcaster &rhs) const; + + bool + operator != (const lldb::SBBroadcaster &rhs) const; + +#endif + +protected: + friend class SBCommandInterpreter; + friend class SBCommunication; + friend class SBEvent; + friend class SBListener; + friend class SBProcess; + friend class SBTarget; + + SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns); + + lldb_private::Broadcaster * + GetLLDBObjectPtr () const; + + void + SetLLDBObjectPtr (lldb_private::Broadcaster *broadcaster, bool owns); + +private: + + lldb_private::Broadcaster *m_lldb_object; + bool m_lldb_object_owned; +}; + +} // namespace lldb + +#endif // LLDB_SBBroadcaster_h_ diff --git a/lldb/include/lldb/API/SBCommandContext.h b/lldb/include/lldb/API/SBCommandContext.h new file mode 100644 index 00000000000..c77465cbd7a --- /dev/null +++ b/lldb/include/lldb/API/SBCommandContext.h @@ -0,0 +1,36 @@ +//===-- SBCommandContext.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBCommandContext_h_ +#define LLDB_SBCommandContext_h_ + + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBCommandContext +{ +public: + + SBCommandContext (lldb_private::CommandContext *lldb_object); + + ~SBCommandContext (); + + bool + IsValid () const; + +private: + + lldb_private::CommandContext *m_lldb_object; +}; + +} // namespace lldb + +#endif // LLDB_SBCommandContext_h_ diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h new file mode 100644 index 00000000000..bb71cf59d27 --- /dev/null +++ b/lldb/include/lldb/API/SBCommandInterpreter.h @@ -0,0 +1,105 @@ +//===-- SBCommandInterpreter.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBCommandInterpreter_h_ +#define LLDB_SBCommandInterpreter_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBCommandInterpreter +{ +public: + enum + { + eBroadcastBitThreadShouldExit = (1 << 0), + eBroadcastBitResetPrompt = (1 << 1), + eBroadcastBitQuitCommandReceived = (1 << 2) // User entered quit + }; + + + ~SBCommandInterpreter (); + + bool + CommandExists (const char *cmd); + + bool + AliasExists (const char *cmd); + + bool + UserCommandExists (const char *cmd); + + lldb::SBBroadcaster + GetBroadcaster (); + + const char ** + GetEnvironmentVariables (); + + bool + HasCommands (); + + bool + HasAliases (); + + bool + HasUserCommands (); + + bool + HasAliasOptions (); + + bool + HasInterpreterVariables (); + + lldb::SBProcess + GetProcess (); + + ssize_t + WriteToScriptInterpreter (const char *src); + + ssize_t + WriteToScriptInterpreter (const char *src, size_t src_len); + + void + SourceInitFileInHomeDirectory (lldb::SBCommandReturnObject &result); + + void + SourceInitFileInCurrentWorkingDirectory (lldb::SBCommandReturnObject &result); + + lldb::ReturnStatus + HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false); + + int + HandleCompletion (const char *current_line, + const char *cursor, + const char *last_char, + int match_start_point, + int max_return_elements, + SBStringList &matches); + +protected: + + lldb_private::CommandInterpreter & + GetLLDBObjectRef (); + + lldb_private::CommandInterpreter * + GetLLDBObjectPtr (); + +private: + friend class SBDebugger; + + SBCommandInterpreter (lldb_private::CommandInterpreter &interpreter_ptr); // Access using SBDebugger::GetSharedInstance().GetCommandInterpreter(); + + lldb_private::CommandInterpreter &m_interpreter; +}; + + +} // namespace lldb + +#endif // LLDB_SBCommandInterpreter_h_ diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h new file mode 100644 index 00000000000..65ddc70c124 --- /dev/null +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -0,0 +1,80 @@ +//===-- SBCommandReturnObject.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBCommandReturnObject_h_ +#define LLDB_SBCommandReturnObject_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBCommandReturnObject +{ +public: + + SBCommandReturnObject (); + + ~SBCommandReturnObject (); + + bool + IsValid() const; + + const char * + GetOutput (); + + const char * + GetError (); + + size_t + PutOutput (FILE *fh); + + size_t + GetOutputSize (); + + size_t + GetErrorSize (); + + size_t + PutError (FILE *fh); + + void + Clear(); + + lldb::ReturnStatus + GetStatus(); + + bool + Succeeded (); + + bool + HasResult (); + + void + AppendMessage (const char *message); + +protected: + friend class SBCommandInterpreter; + friend class SBOptions; + + lldb_private::CommandReturnObject * + GetLLDBObjectPtr(); + + lldb_private::CommandReturnObject & + GetLLDBObjectRef(); + + void + SetLLDBObjectPtr (lldb_private::CommandReturnObject *ptr); + + private: + std::auto_ptr<lldb_private::CommandReturnObject> m_return_object_ap; +}; + +} // namespace lldb + +#endif // LLDB_SBCommandReturnObject_h_ diff --git a/lldb/include/lldb/API/SBCommunication.h b/lldb/include/lldb/API/SBCommunication.h new file mode 100644 index 00000000000..134a78a557d --- /dev/null +++ b/lldb/include/lldb/API/SBCommunication.h @@ -0,0 +1,97 @@ +//===-- SBCommunication.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBCommunication_h_ +#define LLDB_SBCommunication_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBError.h> + +namespace lldb { + +class SBCommunication +{ +public: + enum { + eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost. + eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available. + eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients. + eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread. + eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet. + eAllEventBits = 0xffffffff + }; + + typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len); + + SBCommunication (); + SBCommunication (const char * broadcaster_name); + ~SBCommunication (); + + + lldb::SBBroadcaster + GetBroadcaster (); + + lldb::ConnectionStatus + AdoptFileDesriptor (int fd, bool owns_fd); + + lldb::ConnectionStatus + CheckIfBytesAvailable (); + + lldb::ConnectionStatus + WaitForBytesAvailableInfinite (); + + lldb::ConnectionStatus + WaitForBytesAvailableWithTimeout (uint32_t timeout_usec); + + lldb::ConnectionStatus + Connect (const char *url); + + lldb::ConnectionStatus + Disconnect (); + + bool + IsConnected () const; + + size_t + Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + lldb::ConnectionStatus &status); + + size_t + Write (const void *src, + size_t src_len, + lldb::ConnectionStatus &status); + + bool + ReadThreadStart (); + + bool + ReadThreadStop (); + + bool + ReadThreadIsRunning (); + + bool + SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback, + void *callback_baton); + + +private: +// void +// CreateIfNeeded (); + + lldb_private::Communication *m_lldb_object; + bool m_lldb_object_owned; +}; + + +} // namespace lldb + +#endif // LLDB_SBCommunication_h_ diff --git a/lldb/include/lldb/API/SBCompileUnit.h b/lldb/include/lldb/API/SBCompileUnit.h new file mode 100644 index 00000000000..3d6e7e48b91 --- /dev/null +++ b/lldb/include/lldb/API/SBCompileUnit.h @@ -0,0 +1,75 @@ +//===-- SBCompileUnit.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBCompileUnit_h_ +#define LLDB_SBCompileUnit_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBFileSpec.h> + +namespace lldb { + +class SBCompileUnit +{ +public: + + SBCompileUnit (); + + ~SBCompileUnit (); + + bool + IsValid () const; + + lldb::SBFileSpec + GetFileSpec () const; + + uint32_t + GetNumLineEntries () const; + + lldb::SBLineEntry + GetLineEntryAtIndex (uint32_t idx) const; + + uint32_t + FindLineEntryIndex (uint32_t start_idx, + uint32_t line, + lldb::SBFileSpec *inline_file_spec) const; + +#ifndef SWIG + + bool + operator == (const lldb::SBCompileUnit &rhs) const; + + bool + operator != (const lldb::SBCompileUnit &rhs) const; + +#endif + +private: + friend class SBFrame; + friend class SBSymbolContext; + + SBCompileUnit (lldb_private::CompileUnit *lldb_object_ptr); + +#ifndef SWIG + + const lldb_private::CompileUnit * + operator->() const; + + const lldb_private::CompileUnit & + operator*() const; + +#endif + + lldb_private::CompileUnit *m_lldb_object_ptr; +}; + + +} // namespace lldb + +#endif // LLDB_SBCompileUnit_h_ diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h new file mode 100644 index 00000000000..3dcc4890f5f --- /dev/null +++ b/lldb/include/lldb/API/SBDebugger.h @@ -0,0 +1,148 @@ +//===-- SBDebugger.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBDebugger_h_ +#define LLDB_SBDebugger_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBDebugger +{ +public: + + static void + Initialize(); + + static void + Terminate(); + + static void + SetAsync (bool b); + + static void + SetInputFile (const char *tty_name); // DEPRECATED: will be removed in next submission + + static void + SetOutputFile (const char *tty_name); // DEPRECATED: will be removed in next submission + + static void + SetErrorFile (const char *tty_name); // DEPRECATED: will be removed in next submission + + static void + SetInputFileHandle (FILE *f, bool transfer_ownership); + + static void + SetOutputFileHandle (FILE *f, bool transfer_ownership); + + static void + SetErrorFileHandle (FILE *f, bool transfer_ownership); + + static FILE * + GetInputFileHandle (); + + static FILE * + GetOutputFileHandle (); + + static FILE * + GetErrorFileHandle (); + + static lldb::SBCommandInterpreter + GetCommandInterpreter (); + + static void + HandleCommand (const char *command); + + static lldb::SBListener + GetListener (); + + static void + HandleProcessEvent (const lldb::SBProcess &process, + const lldb::SBEvent &event, + FILE *out, + FILE *err); + + static lldb::SBTarget + CreateTargetWithFileAndTargetTriple (const char *filename, + const char *target_triple); + + static lldb::SBTarget + CreateTargetWithFileAndArch (const char *filename, + const char *archname); + + static lldb::SBTarget + CreateTarget (const char *filename); + + static lldb::SBTarget + GetTargetAtIndex (uint32_t idx); + + static lldb::SBTarget + FindTargetWithProcessID (pid_t pid); + + static lldb::SBTarget + FindTargetWithFileAndArch (const char *filename, + const char *arch); + + static uint32_t + GetNumTargets (); + + static lldb::SBTarget + GetCurrentTarget (); + + static void + UpdateCurrentThread (lldb::SBProcess &process); + + static void + ReportCurrentLocation (FILE *out = stdout, + FILE *err = stderr); + + static lldb::SBSourceManager & + GetSourceManager (); + + static bool + GetDefaultArchitecture (char *arch_name, size_t arch_name_len); + + static bool + SetDefaultArchitecture (const char *arch_name); + + static lldb::ScriptLanguage + GetScriptingLanguage (const char *script_language_name); + + static const char * + GetVersionString (); + + static const char * + StateAsCString (lldb::StateType state); + + static bool + StateIsRunningState (lldb::StateType state); + + static bool + StateIsStoppedState (lldb::StateType state); + + static void + DispatchInput (void *baton, const void *data, size_t data_len); + + static void + PushInputReader (lldb::SBInputReader &reader); + +private: +#ifndef SWIG + friend class SBProcess; + + static lldb::SBTarget + FindTargetWithLLDBProcess (const lldb::ProcessSP &processSP); +#endif +}; // class SBDebugger + + +} // namespace lldb + +#endif // LLDB_SBDebugger_h_ diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h new file mode 100644 index 00000000000..f1e3c38a42e --- /dev/null +++ b/lldb/include/lldb/API/SBDefines.h @@ -0,0 +1,62 @@ +//===-- SBDefines.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBDefines_h_ +#define LLDB_SBDefines_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include <LLDB/lldb-defines.h> +#include <LLDB/lldb-enumerations.h> +#include <LLDB/lldb-forward.h> +#include <LLDB/lldb-forward-rtti.h> +#include <LLDB/lldb-types.h> + +// Forward Declarations + +namespace lldb { + +class SBAddress; +class SBBlock; +class SBBreakpoint; +class SBBreakpointLocation; +class SBBroadcaster; +class SBCommandContext; +class SBCommandInterpreter; +class SBCommandReturnObject; +class SBCommunication; +class SBCompileUnit; +class SBDebugger; +class SBError; +class SBEvent; +class SBEventList; +class SBFileSpec; +class SBFrame; +class SBFunction; +class SBHostOS; +class SBInputReader; +class SBInstruction; +class SBLineEntry; +class SBListener; +class SBModule; +class SBProcess; +class SBSourceManager; +class SBSymbol; +class SBSymbolContext; +class SBStringList; +class SBTarget; +class SBThread; +class SBValue; + +} + +#endif // LLDB_SBDefines_h_ diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h new file mode 100644 index 00000000000..1d23c736d2a --- /dev/null +++ b/lldb/include/lldb/API/SBError.h @@ -0,0 +1,102 @@ +//===-- SBError.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBError_h_ +#define LLDB_SBError_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBError { +public: + SBError (); + + SBError (const SBError &rhs); + + ~SBError(); + +#ifndef SWIG + + const SBError & + operator =(const SBError &rhs); + +#endif + + const char * + GetCString () const; + + void + Clear (); + + bool + Fail () const; + + bool + Success () const; + + uint32_t + GetError () const; + + lldb::ErrorType + GetType () const; + + void + SetError (uint32_t err, lldb::ErrorType type); + + void + SetErrorToErrno (); + + void + SetErrorToGenericError (); + + void + SetErrorString (const char *err_str); + + int + SetErrorStringWithFormat (const char *format, ...); + + bool + IsValid () const; + +protected: + friend class SBArguments; + friend class SBCommunication; + friend class SBHostOS; + friend class SBInputReader; + friend class SBProcess; + +#ifndef SWIG + + lldb_private::Error * + get(); + + lldb_private::Error * + operator->(); + + const lldb_private::Error & + operator*() const; + +#endif + + + void + SetError (const lldb_private::Error &lldb_error); + +private: + std::auto_ptr<lldb_private::Error> m_lldb_object_ap; + + void + CreateIfNeeded (); +}; + + +} // namespace lldb + +#endif // LLDB_SBError_h_ diff --git a/lldb/include/lldb/API/SBEvent.h b/lldb/include/lldb/API/SBEvent.h new file mode 100644 index 00000000000..2267d8d4ce2 --- /dev/null +++ b/lldb/include/lldb/API/SBEvent.h @@ -0,0 +1,89 @@ +//===-- SBEvent.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBEvent_h_ +#define LLDB_SBEvent_h_ + +#include <vector> + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBBroadcaster; + +class SBEvent +{ +public: + SBEvent(); + + // Make an event that contains a C string. + SBEvent (uint32_t event, const char *cstr, uint32_t cstr_len); + + ~SBEvent(); + + bool + IsValid() const; + + void + Dump (FILE *f) const; + + const char * + GetDataFlavor (); + + uint32_t + GetType () const; + + lldb::SBBroadcaster + GetBroadcaster () const; + + bool + BroadcasterMatchesPtr (const lldb::SBBroadcaster *broadcaster); + + bool + BroadcasterMatchesRef (const lldb::SBBroadcaster &broadcaster); + + void + Clear(); + + static const char * + GetCStringFromEvent (const lldb::SBEvent &event); + +protected: + friend class SBListener; + friend class SBBroadcaster; + friend class SBDebugger; + friend class SBProcess; + + SBEvent (lldb::EventSP &event_sp); + + lldb::EventSP & + GetSharedPtr () const; + + void + SetEventSP (lldb::EventSP &event_sp); + + void + SetLLDBObjectPtr (lldb_private::Event* event); + + lldb_private::Event * + GetLLDBObjectPtr (); + + const lldb_private::Event * + GetLLDBObjectPtr () const; + +private: + + mutable lldb::EventSP m_event_sp; + mutable lldb_private::Event *m_lldb_object; +}; + +} // namespace lldb + +#endif // LLDB_SBEvent_h_ diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h new file mode 100644 index 00000000000..dd6718ec942 --- /dev/null +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -0,0 +1,83 @@ +//===-- SBFileSpec.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBFileSpec_h_ +#define LLDB_SBFileSpec_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBFileSpec +{ +public: + SBFileSpec (); + + SBFileSpec (const lldb::SBFileSpec &rhs); + + SBFileSpec (const char *path); + + ~SBFileSpec (); + +#ifndef SWIG + const SBFileSpec & + operator = (const lldb::SBFileSpec &rhs); +#endif + + bool + IsValid() const; + + bool + Exists () const; + + const char * + GetFileName() const; + + const char * + GetDirectory() const; + + uint32_t + GetPath (char *dst_path, size_t dst_len) const; + + static int + ResolvePath (const char *src_path, char *dst_path, size_t dst_len); + +private: + friend class SBLineEntry; + friend class SBCompileUnit; + friend class SBHostOS; + friend class SBModule; + friend class SBSourceManager; + friend class SBTarget; + + void + SetFileSpec (const lldb_private::FileSpec& fs); +#ifndef SWIG + + const lldb_private::FileSpec * + operator->() const; + + const lldb_private::FileSpec * + get() const; + + const lldb_private::FileSpec & + operator*() const; + + const lldb_private::FileSpec & + ref() const; + +#endif + + std::auto_ptr <lldb_private::FileSpec> m_lldb_object_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBFileSpec_h_ diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h new file mode 100644 index 00000000000..36106bdbff5 --- /dev/null +++ b/lldb/include/lldb/API/SBFrame.h @@ -0,0 +1,130 @@ +//===-- SBFrame.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBFrame_h_ +#define LLDB_SBFrame_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBValueList.h> + +namespace lldb { + +class SBValue; + +class SBFrame +{ +public: + SBFrame (); + + ~SBFrame(); + + bool + IsValid() const; + + uint32_t + GetFrameID () const; + + lldb::addr_t + GetPC () const; + + bool + SetPC (lldb::addr_t new_pc); + + lldb::addr_t + GetSP () const; + + lldb::addr_t + GetFP () const; + + lldb::SBAddress + GetPCAddress () const; + + lldb::SBSymbolContext + GetSymbolContext (uint32_t resolve_scope) const; + + lldb::SBModule + GetModule () const; + + lldb::SBCompileUnit + GetCompileUnit () const; + + lldb::SBFunction + GetFunction () const; + + lldb::SBBlock + GetBlock () const; + + lldb::SBLineEntry + GetLineEntry () const; + + lldb::SBThread + GetThread () const; + + const char * + Disassemble () const; + + void + Clear(); + +#ifndef SWIG + bool + operator == (const lldb::SBFrame &rhs) const; + + bool + operator != (const lldb::SBFrame &rhs) const; + +#endif + + lldb::SBValueList + GetVariables (bool arguments, + bool locals, + bool statics, + bool in_scope_only); + + lldb::SBValueList + GetRegisters (); + + lldb::SBValue + LookupVar (const char *var_name); + + lldb::SBValue + LookupVarInScope (const char *var_name, const char *scope); + +protected: + friend class SBValue; + + lldb_private::StackFrame * + GetLLDBObjectPtr (); + +private: + friend class SBThread; + +#ifndef SWIG + + lldb_private::StackFrame * + operator->() const; + + // Mimic shared pointer... + lldb_private::StackFrame * + get() const; + +#endif + + + SBFrame (const lldb::StackFrameSP &lldb_object_sp); + + void + SetFrame (const lldb::StackFrameSP &lldb_object_sp); + + lldb::StackFrameSP m_lldb_object_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBFrame_h_ diff --git a/lldb/include/lldb/API/SBFunction.h b/lldb/include/lldb/API/SBFunction.h new file mode 100644 index 00000000000..613d8b0fe09 --- /dev/null +++ b/lldb/include/lldb/API/SBFunction.h @@ -0,0 +1,55 @@ +//===-- SBFunction.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBFunction_h_ +#define LLDB_SBFunction_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBFunction +{ +public: + + SBFunction (); + + ~SBFunction (); + + bool + IsValid () const; + + const char * + GetName() const; + + const char * + GetMangledName () const; + +#ifndef SWIG + bool + operator == (const lldb::SBFunction &rhs) const; + + bool + operator != (const lldb::SBFunction &rhs) const; +#endif + +private: + friend class SBFrame; + friend class SBSymbolContext; + + SBFunction (lldb_private::Function *lldb_object_ptr); + + + lldb_private::Function *m_lldb_object_ptr; +}; + + +} // namespace lldb + +#endif // LLDB_SBFunction_h_ diff --git a/lldb/include/lldb/API/SBHostOS.h b/lldb/include/lldb/API/SBHostOS.h new file mode 100644 index 00000000000..53943cac7a6 --- /dev/null +++ b/lldb/include/lldb/API/SBHostOS.h @@ -0,0 +1,54 @@ +//===-- SBHostOS.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBHostOS_h_ +#define LLDB_SBHostOS_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBFileSpec.h> + +namespace lldb { + +class SBHostOS +{ +public: + + static lldb::SBFileSpec + GetProgramFileSpec (); + + static void + ThreadCreated (const char *name); + + static lldb::thread_t + ThreadCreate (const char *name, + void *(*thread_function)(void *), + void *thread_arg, + lldb::SBError *err); + + static bool + ThreadCancel (lldb::thread_t thread, + lldb::SBError *err); + + static bool + ThreadDetach (lldb::thread_t thread, + lldb::SBError *err); + static bool + ThreadJoin (lldb::thread_t thread, + void **result, + lldb::SBError *err); + + +private: + +}; + + +} // namespace lldb + +#endif // LLDB_SBHostOS_h_ diff --git a/lldb/include/lldb/API/SBInputReader.h b/lldb/include/lldb/API/SBInputReader.h new file mode 100644 index 00000000000..5b2590e29b6 --- /dev/null +++ b/lldb/include/lldb/API/SBInputReader.h @@ -0,0 +1,100 @@ +//===-- SBInputReader.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBInputReader_h_ +#define LLDB_SBInputReader_h_ + +#include <LLDB/SBDefines.h> + +#include <termios.h> + +namespace lldb { + +class SBInputReader +{ +public: + + typedef size_t (*Callback) (void *baton, + SBInputReader *reader, + InputReaderAction notification, + const char *bytes, + size_t bytes_len); + + SBInputReader (); + + SBInputReader (const lldb::InputReaderSP &reader_sp); + + SBInputReader (const lldb::SBInputReader &rhs); + + ~SBInputReader (); + + + SBError + Initialize (Callback callback, + void *callback_baton, + lldb::InputReaderGranularity granularity, + const char *end_token, + const char *prompt, + bool echo); + + bool + IsValid () const; + +#ifndef SWIG + const SBInputReader & + operator = (const lldb::SBInputReader &rhs); +#endif + + bool + IsActive () const; + + bool + IsDone () const; + + void + SetIsDone (bool value); + + InputReaderGranularity + GetGranularity (); + +protected: + friend class SBDebugger; + +#ifndef SWIG + + lldb_private::InputReader * + operator->() const; + + lldb::InputReaderSP & + operator *(); + + const lldb::InputReaderSP & + operator *() const; +#endif + + lldb_private::InputReader * + get() const; + +private: + + static size_t + PrivateCallback (void *baton, + lldb_private::InputReader *reader, + lldb::InputReaderAction notification, + const char *bytes, + size_t bytes_len); + + lldb::InputReaderSP m_reader_sp; + Callback m_callback_function; + void *m_callback_baton; +}; + +} // namespace lldb + +#endif // LLDB_SBInputReader_h_ diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h new file mode 100644 index 00000000000..256b1c017b8 --- /dev/null +++ b/lldb/include/lldb/API/SBInstruction.h @@ -0,0 +1,57 @@ +//===-- SBInstruction.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBInstruction_h_ +#define LLDB_SBInstruction_h_ + +#include <LLDB/SBDefines.h> + +// There's a lot to be fixed here, but need to wait for underlying insn implementation +// to be revised & settle down first. + +//class lldb_private::Disassembler::Instruction; + +namespace lldb { + +class SBInstruction +{ +public: + + //SBInstruction (lldb_private::Disassembler::Instruction *lldb_insn); + + SBInstruction (); + + ~SBInstruction (); + + //bool + //IsValid(); + + //size_t + //GetByteSize (); + + //void + //SetByteSize (size_t byte_size); + + //bool + //DoesBranch (); + + void + Print (FILE *out); + +private: + + //lldb_private::Disassembler::Instruction::SharedPtr m_lldb_object_sp; + + +}; + + +} // namespace lldb + +#endif // LLDB_SBInstruction_h_ diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h new file mode 100644 index 00000000000..455807466fa --- /dev/null +++ b/lldb/include/lldb/API/SBInstructionList.h @@ -0,0 +1,53 @@ +//===-- SBInstructionList.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBInstructionList_h_ +#define LLDB_SBInstructionList_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBInstructionList +{ +public: + + SBInstructionList (); + + ~SBInstructionList (); + + size_t + GetSize (); + + lldb::SBInstruction + GetInstructionAtIndex (uint32_t idx); + + void + Clear (); + + void + AppendInstruction (lldb::SBInstruction inst); + + + void + Print (FILE *out); + +private: + + // If we have an instruction list, it will need to be backed by an + // lldb_private class that contains the list, we can't inherit from + // std::vector here... + //std::vector <SBInstruction> m_insn_list; + +}; + + +} // namespace lldb + +#endif // LLDB_SBInstructionList_h_ diff --git a/lldb/include/lldb/API/SBLineEntry.h b/lldb/include/lldb/API/SBLineEntry.h new file mode 100644 index 00000000000..2e18bb73cf1 --- /dev/null +++ b/lldb/include/lldb/API/SBLineEntry.h @@ -0,0 +1,88 @@ +//===-- SBLineEntry.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBLineEntry_h_ +#define LLDB_SBLineEntry_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBAddress.h> +#include <LLDB/SBFileSpec.h> + +namespace lldb { + +class SBLineEntry +{ +public: + + SBLineEntry (); + + SBLineEntry (const lldb::SBLineEntry &rhs); + + ~SBLineEntry (); + +#ifndef SWIG + const lldb::SBLineEntry & + operator = (const lldb::SBLineEntry &rhs); +#endif + + lldb::SBAddress + GetStartAddress () const; + + lldb::SBAddress + GetEndAddress () const; + + bool + IsValid () const; + + lldb::SBFileSpec + GetFileSpec () const; + + uint32_t + GetLine () const; + + uint32_t + GetColumn () const; + +#ifndef SWIG + bool + operator == (const lldb::SBLineEntry &rhs) const; + + bool + operator != (const lldb::SBLineEntry &rhs) const; + +#endif + +private: + friend class SBCompileUnit; + friend class SBFrame; + friend class SBSymbolContext; + +#ifndef SWIG + + const lldb_private::LineEntry * + operator->() const; + + const lldb_private::LineEntry & + operator*() const; + +#endif + + + SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr); + + void + SetLineEntry (const lldb_private::LineEntry &lldb_object_ref); + + std::auto_ptr<lldb_private::LineEntry> m_lldb_object_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBLineEntry_h_ diff --git a/lldb/include/lldb/API/SBListener.h b/lldb/include/lldb/API/SBListener.h new file mode 100644 index 00000000000..8fd28f7635f --- /dev/null +++ b/lldb/include/lldb/API/SBListener.h @@ -0,0 +1,119 @@ +//===-- SBListener.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBListener_h_ +#define LLDB_SBListener_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBListener +{ +public: + friend class SBBroadcaster; + friend class SBCommandInterpreter; + friend class SBDebugger; + friend class SBTarget; + + SBListener (const char *name); + + SBListener (lldb_private::Listener &listener); + + SBListener (); + + ~SBListener (); + + void + AddEvent (const lldb::SBEvent &event); + + void + Clear (); + + bool + IsValid () const; + + uint32_t + StartListeningForEvents (const lldb::SBBroadcaster& broadcaster, + uint32_t event_mask); + + bool + StopListeningForEvents (const lldb::SBBroadcaster& broadcaster, + uint32_t event_mask); + + // Returns true if an event was recieved, false if we timed out. + bool + WaitForEvent (uint32_t num_seconds, + lldb::SBEvent &event); + + bool + WaitForEventForBroadcaster (uint32_t num_seconds, + const lldb::SBBroadcaster &broadcaster, + lldb::SBEvent &sb_event); + + bool + WaitForEventForBroadcasterWithType (uint32_t num_seconds, + const lldb::SBBroadcaster &broadcaster, + uint32_t event_type_mask, + lldb::SBEvent &sb_event); + + bool + PeekAtNextEvent (lldb::SBEvent &sb_event); + + bool + PeekAtNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster, + lldb::SBEvent &sb_event); + + bool + PeekAtNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster, + uint32_t event_type_mask, + lldb::SBEvent &sb_event); + + bool + GetNextEvent (lldb::SBEvent &sb_event); + + bool + GetNextEventForBroadcaster (const lldb::SBBroadcaster &broadcaster, + lldb::SBEvent &sb_event); + + bool + GetNextEventForBroadcasterWithType (const lldb::SBBroadcaster &broadcaster, + uint32_t event_type_mask, + lldb::SBEvent &sb_event); + + bool + HandleBroadcastEvent (const lldb::SBEvent &event); + +private: + +#ifndef SWIG + + lldb_private::Listener * + operator->() const; + + lldb_private::Listener * + get() const; + + lldb_private::Listener & + operator *(); + + const lldb_private::Listener & + operator *() const; + +#endif + + + + lldb_private::Listener *m_lldb_object_ptr; + bool m_lldb_object_ptr_owned; +}; + +} // namespace lldb + +#endif // LLDB_SBListener_h_ diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h new file mode 100644 index 00000000000..13aa5931a14 --- /dev/null +++ b/lldb/include/lldb/API/SBModule.h @@ -0,0 +1,79 @@ +//===-- SBModule.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBModule_h_ +#define LLDB_SBModule_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBModule +{ +public: + + SBModule (); + + ~SBModule (); + + bool + IsValid () const; + + lldb::SBFileSpec + GetFileSpec () const; + + const uint8_t * + GetUUIDBytes () const; + +#ifndef SWIG + bool + operator == (const lldb::SBModule &rhs) const; + + bool + operator != (const lldb::SBModule &rhs) const; + +#endif + + +private: + friend class SBSymbolContext; + friend class SBTarget; + friend class SBFrame; + + explicit SBModule (const lldb::ModuleSP& module_sp); + + void + SetModule (const lldb::ModuleSP& module_sp); +#ifndef SWIG + + lldb::ModuleSP & + operator *(); + + + lldb_private::Module * + operator ->(); + + const lldb_private::Module * + operator ->() const; + + lldb_private::Module * + get(); + + const lldb_private::Module * + get() const; + +#endif + + lldb::ModuleSP m_lldb_object_sp; +}; + + +} // namespace lldb + +#endif // LLDB_SBModule_h_ diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h new file mode 100644 index 00000000000..caba20447cd --- /dev/null +++ b/lldb/include/lldb/API/SBProcess.h @@ -0,0 +1,195 @@ +//===-- SBProcess.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBProcess_h_ +#define LLDB_SBProcess_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBError.h> +#include <LLDB/SBTarget.h> + +namespace lldb { + +class SBEvent; + +class SBProcess +{ +public: + //------------------------------------------------------------------ + /// Broadcaster event bits definitions. + //------------------------------------------------------------------ + enum + { + eBroadcastBitStateChanged = (1 << 0), + eBroadcastBitInterrupt = (1 << 1), + eBroadcastBitSTDOUT = (1 << 2), + eBroadcastBitSTDERR = (1 << 3), + }; + + SBProcess (); + + SBProcess (const lldb::SBProcess& rhs); + + ~SBProcess(); + + void + Clear (); + + bool + IsValid() const; + + lldb::SBTarget + GetTarget() const; + + size_t + PutSTDIN (const char *src, size_t src_len); + + size_t + GetSTDOUT (char *dst, size_t dst_len) const; + + size_t + GetSTDERR (char *dst, size_t dst_len) const; + + void + ReportCurrentState (const lldb::SBEvent &event, FILE *out) const; + + void + AppendCurrentStateReport (const lldb::SBEvent &event, lldb::SBCommandReturnObject &result); + + //------------------------------------------------------------------ + // Thread related functions + //------------------------------------------------------------------ + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (size_t index); + + lldb::SBThread + GetThreadByID (lldb::tid_t sb_thread_id); + + lldb::SBThread + GetCurrentThread () const; + + bool + SetCurrentThread (const lldb::SBThread &thread); + + bool + SetCurrentThreadByID (uint32_t tid); + + //------------------------------------------------------------------ + // Stepping related functions + //------------------------------------------------------------------ + + lldb::StateType + GetState (); + + int + GetExitStatus (); + + const char * + GetExitDescription (); + + lldb::pid_t + GetProcessID (); + + uint32_t + GetAddressByteSize() const; + + SBError + Destroy (); + + void + DisplayThreadsInfo (FILE *out = NULL, FILE *err = NULL, bool only_threads_with_stop_reason = true); + + void + ListThreads (); + + bool + WaitUntilProcessHasStopped (lldb::SBCommandReturnObject &result); + + lldb::pid_t + AttachByPID (lldb::pid_t pid); // DEPRECATED: will be removed in a few builds in favor of SBError AttachByPID(pid_t) + + SBError + Attach (lldb::pid_t pid); + + SBError + AttachByName (const char *name, bool wait_for_launch); + + SBError + Continue (); + + SBError + Stop (); + + SBError + Kill (); + + SBError + Detach (); + + SBError + Signal (int signal); + + void + Backtrace (bool all_threads = false, uint32_t num_frames = 0); + + size_t + ReadMemory (addr_t addr, void *buf, size_t size, SBError &error); + + size_t + WriteMemory (addr_t addr, const void *buf, size_t size, SBError &error); + + // Events + static lldb::StateType + GetStateFromEvent (const lldb::SBEvent &event); + + static bool + GetRestartedFromEvent (const lldb::SBEvent &event); + + static lldb::SBProcess + GetProcessFromEvent (const lldb::SBEvent &event); + + lldb::SBBroadcaster + GetBroadcaster () const; + +protected: + friend class SBAddress; + friend class SBBreakpoint; + friend class SBBreakpointLocation; + friend class SBCommandInterpreter; + friend class SBDebugger; + friend class SBTarget; + friend class SBThread; + friend class SBValue; + +#ifndef SWIG + + lldb_private::Process * + operator->() const; + + // Mimic shared pointer... + lldb_private::Process * + get() const; + +#endif + + + SBProcess (const lldb::ProcessSP &process_sp); + + void + SetProcess (const lldb::ProcessSP &process_sp); + + lldb::ProcessSP m_lldb_object_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBProcess_h_ diff --git a/lldb/include/lldb/API/SBSourceManager.h b/lldb/include/lldb/API/SBSourceManager.h new file mode 100644 index 00000000000..54ac612ac2a --- /dev/null +++ b/lldb/include/lldb/API/SBSourceManager.h @@ -0,0 +1,47 @@ +//===-- SBSourceManager.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBSourceManager_h_ +#define LLDB_SBSourceManager_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBSourceManager +{ +public: + ~SBSourceManager(); + + size_t + DisplaySourceLinesWithLineNumbers (const lldb::SBFileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char* current_line_cstr, + FILE *f); + + +protected: + friend class SBCommandInterpreter; + friend class SBDebugger; + + SBSourceManager(lldb_private::SourceManager &source_manager); + + lldb_private::SourceManager & + GetLLDBManager (); + +private: + + lldb_private::SourceManager &m_source_manager; +}; + +} // namespace lldb + +#endif // LLDB_SBSourceManager_h_ diff --git a/lldb/include/lldb/API/SBStringList.h b/lldb/include/lldb/API/SBStringList.h new file mode 100644 index 00000000000..2d1300fe183 --- /dev/null +++ b/lldb/include/lldb/API/SBStringList.h @@ -0,0 +1,72 @@ +//===-- SBStringList.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBStringList_h_ +#define LLDB_SBStringList_h_ + + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBStringList +{ +public: + + SBStringList (); + + SBStringList (const lldb_private::StringList *lldb_strings); + + SBStringList (const lldb::SBStringList &rhs); + + ~SBStringList (); + + bool + IsValid() const; + + void + AppendString (const char *str); + + void + AppendList (const char **strv, int strc); + + void + AppendList (lldb::SBStringList strings); + + uint32_t + GetSize () const; + + const char * + GetStringAtIndex (size_t idx); + + void + Clear (); + +#ifndef SWIG + + const lldb_private::StringList * + operator->() const; + + const lldb_private::StringList & + operator*() const; + + const lldb::SBStringList & + operator = (const lldb::SBStringList &rhs); + +#endif + +private: + + std::auto_ptr<lldb_private::StringList> m_lldb_object_ap; + +}; + +} // namespace lldb + +#endif // LLDB_SBStringList_h_ diff --git a/lldb/include/lldb/API/SBSymbol.h b/lldb/include/lldb/API/SBSymbol.h new file mode 100644 index 00000000000..b7a3058d3c1 --- /dev/null +++ b/lldb/include/lldb/API/SBSymbol.h @@ -0,0 +1,55 @@ +//===-- SBSymbol.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBSymbol_h_ +#define LLDB_SBSymbol_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBSymbol +{ +public: + + SBSymbol (); + + ~SBSymbol (); + + bool + IsValid () const; + + + const char * + GetName() const; + + const char * + GetMangledName () const; + +#ifndef SWIG + bool + operator == (const lldb::SBSymbol &rhs) const; + + bool + operator != (const lldb::SBSymbol &rhs) const; +#endif + + +private: + friend class SBSymbolContext; + + SBSymbol (lldb_private::Symbol *lldb_object_ptr); + + lldb_private::Symbol *m_lldb_object_ptr; +}; + + +} // namespace lldb + +#endif // LLDB_SBSymbol_h_ diff --git a/lldb/include/lldb/API/SBSymbolContext.h b/lldb/include/lldb/API/SBSymbolContext.h new file mode 100644 index 00000000000..fd14511883e --- /dev/null +++ b/lldb/include/lldb/API/SBSymbolContext.h @@ -0,0 +1,73 @@ +//===-- SBSymbolContext.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBSymbolContext_h_ +#define LLDB_SBSymbolContext_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBBlock.h> +#include <LLDB/SBCompileUnit.h> +#include <LLDB/SBFunction.h> +#include <LLDB/SBLineEntry.h> +#include <LLDB/SBModule.h> +#include <LLDB/SBSymbol.h> + +namespace lldb { + +class SBSymbolContext +{ +public: + SBSymbolContext (); + + SBSymbolContext (const lldb::SBSymbolContext& rhs); + + ~SBSymbolContext (); + + bool + IsValid () const; + +#ifndef SWIG + const lldb::SBSymbolContext & + operator = (const lldb::SBSymbolContext &rhs); +#endif + + SBModule GetModule (); + SBCompileUnit GetCompileUnit (); + SBFunction GetFunction (); + SBBlock GetBlock (); + SBLineEntry GetLineEntry (); + SBSymbol GetSymbol (); + +protected: + friend class SBFrame; + friend class SBThread; + +#ifndef SWIG + + lldb_private::SymbolContext* + operator->() const; + +#endif + + lldb_private::SymbolContext * + GetLLDBObjectPtr() const; + + SBSymbolContext (const lldb_private::SymbolContext *sc_ptr); + + void + SetSymbolContext (const lldb_private::SymbolContext *sc_ptr); + +private: + std::auto_ptr<lldb_private::SymbolContext> m_lldb_object_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBSymbolContext_h_ diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h new file mode 100644 index 00000000000..e950b4cda43 --- /dev/null +++ b/lldb/include/lldb/API/SBTarget.h @@ -0,0 +1,167 @@ +//===-- SBTarget.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBTarget_h_ +#define LLDB_SBTarget_h_ + +#include <LLDB/SBDefines.h> +#include <LLDB/SBBroadcaster.h> +#include <LLDB/SBFileSpec.h> + +namespace lldb { + +class SBBreakpoint; + +class SBTarget +{ +public: + //------------------------------------------------------------------ + // Broadcaster bits. + //------------------------------------------------------------------ + enum + { + eBroadcastBitBreakpointChanged = (1 << 0), + eBroadcastBitModulesLoaded = (1 << 1), + eBroadcastBitModulesUnloaded = (1 << 2) + }; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SBTarget (const lldb::SBTarget& rhs); + + SBTarget (); // Required for SWIG. + + //------------------------------------------------------------------ + // Destructor + //------------------------------------------------------------------ + ~SBTarget(); + + const lldb::SBTarget& + Assign (const lldb::SBTarget& rhs); + + bool + IsValid() const; + + lldb::SBProcess + GetProcess (); + + lldb::SBProcess + CreateProcess (); + + lldb::SBProcess + LaunchProcess (char const **argv, + char const **envp, + const char *tty, + bool stop_at_entry); + + lldb::SBFileSpec + GetExecutable (); + + uint32_t + GetNumModules () const; + + lldb::SBModule + GetModuleAtIndex (uint32_t idx); + + lldb::SBModule + FindModule (const lldb::SBFileSpec &file_spec); + + bool + DeleteTargetFromList (lldb_private::TargetList *list); + + bool + MakeCurrentTarget (); + + lldb::SBBreakpoint + BreakpointCreateByLocation (const char *file, uint32_t line); + + lldb::SBBreakpoint + BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line); + + lldb::SBBreakpoint + BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL); + + lldb::SBBreakpoint + BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL); + + lldb::SBBreakpoint + BreakpointCreateByAddress (addr_t address); + + bool + BreakpointDelete (break_id_t break_id); + + void + ListAllBreakpoints (); + + lldb::SBBreakpoint + FindBreakpointByID (break_id_t break_id); + + bool + EnableAllBreakpoints (); + + bool + DisableAllBreakpoints (); + + bool + DeleteAllBreakpoints (); + + lldb::SBBroadcaster + GetBroadcaster () const; + + //void + //Disassemble (); + + void + Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_address_end = LLDB_INVALID_ADDRESS, + const char *module_name = NULL); + + void + Disassemble (const char *function_name, const char *module_name = NULL); + +#ifndef SWIG + bool + operator == (const lldb::SBTarget &rhs) const; + + bool + operator != (const lldb::SBTarget &rhs) const; + +#endif + +protected: + friend class SBDebugger; + friend class SBProcess; + + //------------------------------------------------------------------ + // Constructors are private, use static Target::Create function to + // create an instance of this class. + //------------------------------------------------------------------ + + SBTarget (const lldb::TargetSP& target_sp); + + void + SetLLBDTarget (const lldb::TargetSP& target_sp); + + lldb_private::Target * + GetLLDBObjectPtr(); + + const lldb_private::Target * + GetLLDBObjectPtr() const; + +private: + //------------------------------------------------------------------ + // For Target only + //------------------------------------------------------------------ + + lldb::TargetSP m_target_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBTarget_h_ diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h new file mode 100644 index 00000000000..220424fd87f --- /dev/null +++ b/lldb/include/lldb/API/SBThread.h @@ -0,0 +1,152 @@ +//===-- SBThread.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBThread_h_ +#define LLDB_SBThread_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBFrame; + +class SBThread +{ +public: + SBThread (); + + SBThread (const lldb::SBThread &thread); + + ~SBThread(); + + bool + IsValid() const; + + lldb::StopReason + GetStopReason(); + + size_t + GetStopDescription (char *dst, size_t dst_len); + + lldb::tid_t + GetThreadID () const; + + uint32_t + GetIndexID () const; + + const char * + GetName () const; + + const char * + GetQueueName() const; + + void + DisplayFramesForCurrentContext (FILE *out, + FILE *err, + uint32_t first_frame, + uint32_t num_frames, + bool show_frame_info, + uint32_t num_frames_with_source, + uint32_t source_lines_before = 3, + uint32_t source_lines_after = 3); + + bool + DisplaySingleFrameForCurrentContext (FILE *out, + FILE *err, + lldb::SBFrame &frame, + bool show_frame_info, + bool show_source, + uint32_t source_lines_after, + uint32_t source_lines_before); + + void + StepOver (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + + void + StepInto (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + + void + StepOut (); + + void + StepInstruction(bool step_over); + + void + RunToAddress (lldb::addr_t addr); + + void + Backtrace (uint32_t num_frames = 0); + + uint32_t + GetNumFrames (); + + lldb::SBFrame + GetFrameAtIndex (uint32_t idx); + + lldb::SBProcess + GetProcess (); + +#ifndef SWIG + + const lldb::SBThread & + operator = (const lldb::SBThread &rhs); + + bool + operator == (const lldb::SBThread &rhs) const; + + bool + operator != (const lldb::SBThread &rhs) const; + +#endif + + +protected: + friend class SBBreakpoint; + friend class SBBreakpointLocation; + friend class SBFrame; + friend class SBProcess; + friend class SBDebugger; + friend class SBValue; + + lldb_private::Thread * + GetLLDBObjectPtr (); + +#ifndef SWIG + + const lldb_private::Thread * + operator->() const; + + const lldb_private::Thread & + operator*() const; + + + lldb_private::Thread * + operator->(); + + lldb_private::Thread & + operator*(); + +#endif + + SBThread (const lldb::ThreadSP& lldb_object_sp); + + void + SetThread (const lldb::ThreadSP& lldb_object_sp); + +private: + //------------------------------------------------------------------ + // Classes that inherit from Thread can see and modify these + //------------------------------------------------------------------ + + lldb::ThreadSP m_lldb_object_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBThread_h_ diff --git a/lldb/include/lldb/API/SBType.h b/lldb/include/lldb/API/SBType.h new file mode 100644 index 00000000000..f647fbf20fc --- /dev/null +++ b/lldb/include/lldb/API/SBType.h @@ -0,0 +1,31 @@ +//===-- SBType.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBType_h_ +#define LLDB_SBType_h_ + +#include <LLDB/SBDefines.h> + +namespace lldb { + +class SBType +{ +public: + + static bool + IsPointerType (void *opaque_type); + +private: + +}; + + +} // namespace lldb + +#endif // LLDB_SBType_h_ diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h new file mode 100644 index 00000000000..395ca00a4f8 --- /dev/null +++ b/lldb/include/lldb/API/SBValue.h @@ -0,0 +1,126 @@ +//===-- SBValue.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBValue_h_ +#define LLDB_SBValue_h_ + +#include <LLDB/SBDefines.h> + +class lldb_private::Variable; +class lldb_private::ValueObject; +class lldb_private::ExecutionContext; + +namespace lldb { + +class SBValue +{ +public: + SBValue (); + + ~SBValue (); + + bool + IsValid() const; + + void + Print (FILE *out_file, lldb::SBFrame *frame, bool print_type, bool print_value); + + const char * + GetName(); + + const char * + GetTypeName (); + + size_t + GetByteSize (); + + bool + IsInScope (const lldb::SBFrame &frame); + + const char * + GetValue (const lldb::SBFrame &frame); + + bool + GetValueDidChange (); + + const char * + GetSummary (const lldb::SBFrame &frame); + + const char * + GetLocation (const lldb::SBFrame &frame); + + bool + SetValueFromCString (const lldb::SBFrame &frame, const char *value_str); + + lldb::SBValue + GetChildAtIndex (uint32_t idx); + + // Matches children of this object only and will match base classes and + // member names if this is a clang typed object. + uint32_t + GetIndexOfChildWithName (const char *name); + + // Matches child members of this object and child members of any base + // classes. + lldb::SBValue + GetChildMemberWithName (const char *name); + + uint32_t + GetNumChildren (); + + bool + ValueIsStale (); + + void * + GetOpaqueType(); + + //void + //DumpType (); + + lldb::SBValue + Dereference (); + + bool + TypeIsPtrType (); + + +protected: + friend class SBValueList; + friend class SBFrame; + + SBValue (const lldb::ValueObjectSP &value_sp); + +#ifndef SWIG + + // Mimic shared pointer... + lldb_private::ValueObject * + get() const; + + lldb_private::ValueObject * + operator->() const; + + lldb::ValueObjectSP & + operator*(); + + const lldb::ValueObjectSP & + operator*() const; + +#endif + +private: + + lldb_private::ExecutionContext + GetCurrentExecutionContext (); + + lldb::ValueObjectSP m_lldb_object_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBValue_h_ diff --git a/lldb/include/lldb/API/SBValueList.h b/lldb/include/lldb/API/SBValueList.h new file mode 100644 index 00000000000..49b5fef10c7 --- /dev/null +++ b/lldb/include/lldb/API/SBValueList.h @@ -0,0 +1,79 @@ +//===-- SBValueList.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBValueList_h_ +#define LLDB_SBValueList_h_ + +#include <LLDB/SBDefines.h> + +class lldb_private::ValueObjectList; + +namespace lldb { + +class SBValueList +{ +public: + + SBValueList (); + + SBValueList (const lldb::SBValueList &rhs); + + ~SBValueList(); + + bool + IsValid() const; + + void + Append (const lldb::SBValue &val_obj); + + uint32_t + GetSize() const; + + lldb::SBValue + GetValueAtIndex (uint32_t idx) const; + + lldb::SBValue + FindValueObjectByUID (lldb::user_id_t uid); + + +#ifndef SWIG + const lldb::SBValueList & + operator = (const lldb::SBValueList &rhs); + + lldb_private::ValueObjectList * + operator -> (); + + lldb_private::ValueObjectList & + operator* (); + + const lldb_private::ValueObjectList * + operator -> () const; + + const lldb_private::ValueObjectList & + operator* () const; +#endif + +private: + friend class SBFrame; + + SBValueList (const lldb_private::ValueObjectList *lldb_object_ptr); + + void + Append (lldb::ValueObjectSP& val_obj_sp); + + void + CreateIfNeeded (); + + std::auto_ptr<lldb_private::ValueObjectList> m_lldb_object_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBValueList_h_ diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h new file mode 100644 index 00000000000..1f08636b54e --- /dev/null +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -0,0 +1,511 @@ +//===-- Breakpoint.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Breakpoint_h_ +#define liblldb_Breakpoint_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointLocationList.h" +#include "lldb/Breakpoint/BreakpointOptions.h" +#include "lldb/Breakpoint/BreakpointLocationCollection.h" +#include "lldb/Breakpoint/Stoppoint.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/Event.h" +#include "lldb/Core/StringList.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Breakpoint Breakpoint.h "lldb/Breakpoint/Breakpoint.h" +/// @brief Class that manages logical breakpoint setting. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// A breakpoint has four main parts, a filter, a resolver, the list of breakpoint +/// locations that have been determined for the filter/resolver pair, and finally +/// a set of options for the breakpoint. +/// +/// \b Filter: +/// This is an object derived from SearchFilter. It manages the search +/// for breakpoint location matches through the symbols in the module list of the target +/// that owns it. It also filters out locations based on whatever logic it wants. +/// +/// \b Resolver: +/// This is an object derived from BreakpointResolver. It provides a +/// callback to the filter that will find breakpoint locations. How it does this is +/// determined by what kind of resolver it is. +/// +/// The Breakpoint class also provides constructors for the common breakpoint cases +/// which make the appropriate filter and resolver for you. +/// +/// \b Location List: +/// This stores the breakpoint locations that have been determined +/// to date. For a given breakpoint, there will be only one location with a given +/// address. Adding a location at an already taken address will just return the location +/// already at that address. Locations can be looked up by ID, or by address. +/// +/// \b Options: +/// This includes: +/// \b Enabled/Disabled +/// \b Ignore Count +/// \b Callback +/// \b Condition +/// Note, these options can be set on the breakpoint, and they can also be set on the +/// individual locations. The options set on the breakpoint take precedence over the +/// options set on the individual location. +/// So for instance disabling the breakpoint will cause NONE of the locations to get hit. +/// But if the breakpoint is enabled, then the location's enabled state will be checked +/// to determine whether to insert that breakpoint location. +/// Similarly, if the breakpoint condition says "stop", we won't check the location's condition. +/// But if the breakpoint condition says "continue", then we will check the location for whether +/// to actually stop or not. +/// One subtle point worth observing here is that you don't actually stop at a Breakpoint, you +/// always stop at one of its locations. So the "should stop" tests are done by the location, +/// not by the breakpoint. +//---------------------------------------------------------------------- +class Breakpoint: + public Stoppoint +{ +public: + + static const ConstString & + GetEventIdentifier (); + + + //------------------------------------------------------------------ + /// An enum specifying the match style for breakpoint settings. At + /// present only used for function name style breakpoints. + //------------------------------------------------------------------ + typedef enum + { + Exact, + Regexp, + Glob + } MatchType; + + class BreakpointEventData : + public EventData + { + public: + + static const ConstString & + GetFlavorString (); + + virtual const ConstString & + GetFlavor () const; + + + enum EventSubType + { + eBreakpointInvalidType = (1 << 0), + eBreakpointAdded = (1 << 1), + eBreakpointRemoved = (1 << 2), + eBreakpointLocationsAdded = (1 << 3), + eBreakpointLocationsRemoved = (1 << 4), + eBreakpointLocationResolved = (1 << 5) + }; + + BreakpointEventData (EventSubType sub_type, + lldb::BreakpointSP &new_breakpoint_sp); + + virtual + ~BreakpointEventData(); + + EventSubType + GetSubType () const; + + lldb::BreakpointSP & + GetBreakpoint (); + + + virtual void + Dump (Stream *s) const; + + static BreakpointEventData * + GetEventDataFromEvent (const lldb::EventSP &event_sp); + + static EventSubType + GetSubTypeFromEvent (const lldb::EventSP &event_sp); + + static lldb::BreakpointSP + GetBreakpointFromEvent (const lldb::EventSP &event_sp); + + private: + EventSubType m_sub_type; + lldb::BreakpointSP m_new_breakpoint_sp; + BreakpointLocationCollection m_locations; + + DISALLOW_COPY_AND_ASSIGN (BreakpointEventData); + }; + + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is not virtual since there should be no reason to subclass + /// breakpoints. The varieties of breakpoints are specified instead by + /// providing different resolvers & filters. + //------------------------------------------------------------------ + ~Breakpoint(); + + //------------------------------------------------------------------ + // Methods + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Tell whether this breakpoint is an "internal" breakpoint. + /// @return + /// Returns \b true if this is an internal breakpoint, \b false otherwise. + //------------------------------------------------------------------ + bool + IsInternal () const; + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + void + Dump (Stream *s); + + //------------------------------------------------------------------ + // The next set of methods provide ways to tell the breakpoint to update + // it's location list - usually done when modules appear or disappear. + //------------------------------------------------------------------ + + + //------------------------------------------------------------------ + /// Tell this breakpoint to clear all its breakpoint sites. Done + /// when the process holding the breakpoint sites is destroyed. + //------------------------------------------------------------------ + void + ClearAllBreakpointSites (); + + //------------------------------------------------------------------ + /// Tell this breakpoint to scan it's target's module list and resolve any + /// new locations that match the breakpoint's specifications. + //------------------------------------------------------------------ + void + ResolveBreakpoint (); + + //------------------------------------------------------------------ + /// Tell this breakpoint to scan a given module list and resolve any + /// new locations that match the breakpoint's specifications. + /// + /// @param[in] changedModules + /// The list of modules to look in for new locations. + //------------------------------------------------------------------ + void + ResolveBreakpointInModules (ModuleList &changedModules); + + + //------------------------------------------------------------------ + /// Like ResolveBreakpointInModules, but allows for "unload" events, in + /// which case we will remove any locations that are in modules that got + /// unloaded. + /// + /// @param[in] changedModules + /// The list of modules to look in for new locations. + /// @param[in] load_event + /// If \b true then the modules were loaded, if \b false, unloaded. + //------------------------------------------------------------------ + void + ModulesChanged (ModuleList &changedModules, + bool load_event); + + + //------------------------------------------------------------------ + // The next set of methods provide access to the breakpoint locations + // for this breakpoint. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Add a location to the breakpoint's location list. This is only meant + /// to be called by the breakpoint's resolver. FIXME: how do I ensure that? + /// + /// @param[in] addr + /// The Address specifying the new location. + /// @param[out] new_location + /// Set to \b true if a new location was created, to \b false if there + /// already was a location at this Address. + /// @return + /// Returns a pointer to the new location. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + AddLocation (Address &addr, + bool *new_location = NULL); + + //------------------------------------------------------------------ + /// Find a breakpoint location by Address. + /// + /// @param[in] addr + /// The Address specifying the location. + /// @return + /// Returns a shared pointer to the location at \a addr. The pointer + /// in the shared pointer will be NULL if there is no location at that address. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + FindLocationByAddress (Address &addr); + + //------------------------------------------------------------------ + /// Find a breakpoint location ID by Address. + /// + /// @param[in] addr + /// The Address specifying the location. + /// @return + /// Returns the UID of the location at \a addr, or \b LLDB_INVALID_ID if + /// there is no breakpoint location at that address. + //------------------------------------------------------------------ + lldb::break_id_t + FindLocationIDByAddress (Address &addr); + + //------------------------------------------------------------------ + /// Find a breakpoint location for a given breakpoint location ID. + /// + /// @param[in] bp_loc_id + /// The ID specifying the location. + /// @return + /// Returns a shared pointer to the location with ID \a bp_loc_id. The pointer + /// in the shared pointer will be NULL if there is no location with that ID. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + FindLocationByID (lldb::break_id_t bp_loc_id); + + //------------------------------------------------------------------ + /// Get breakpoint locations by index. + /// + /// @param[in] index + /// The location index. + /// + /// @return + /// Returns a shared pointer to the location with index \a + /// index. The shared pointer might contain NULL if \a index is + /// greater than then number of actual locations. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + GetLocationAtIndex (uint32_t index); + + + const lldb::BreakpointSP + GetSP (); + + //------------------------------------------------------------------ + // The next section deals with various breakpoint options. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// If \a enable is \b true, enable the breakpoint, if \b false disable it. + //------------------------------------------------------------------ + void + SetEnabled (bool enable); + + //------------------------------------------------------------------ + /// Check the Enable/Disable state. + /// @return + /// \b true if the breakpoint is enabled, \b false if disabled. + //------------------------------------------------------------------ + bool + IsEnabled (); + + //------------------------------------------------------------------ + /// Set the breakpoint to ignore the next \a count breakpoint hits. + /// @param[in] count + /// The number of breakpoint hits to ignore. + //------------------------------------------------------------------ + void + SetIgnoreCount (int32_t count); + + //------------------------------------------------------------------ + /// Return the current Ignore Count. + /// @return + /// The number of breakpoint hits to be ignored. + //------------------------------------------------------------------ + int32_t + GetIgnoreCount () const; + + //------------------------------------------------------------------ + /// Set the valid thread to be checked when the breakpoint is hit. + /// @param[in] thread_id + /// If this thread hits the breakpoint, we stop, otherwise not. + //------------------------------------------------------------------ + void + SetThreadID (lldb::tid_t thread_id); + + //------------------------------------------------------------------ + /// Return the current stop thread value. + /// @return + /// The thread id for which the breakpoint hit will stop, LLDB_INVALID_THREAD_ID for all threads. + //------------------------------------------------------------------ + lldb::tid_t + GetThreadID (); + + //------------------------------------------------------------------ + /// Set the callback action invoked when the breakpoint is hit. The callback + /// Will return a bool indicating whether the target should stop at this breakpoint or not. + /// @param[in] callback + /// The method that will get called when the breakpoint is hit. + /// @param[in] baton + /// A void * pointer that will get passed back to the callback function. + //------------------------------------------------------------------ + void + SetCallback (BreakpointHitCallback callback, + void *baton, + bool is_synchronous = false); + + void + SetCallback (BreakpointHitCallback callback, + const lldb::BatonSP &callback_baton_sp, + bool is_synchronous = false); + + void + ClearCallback (); + + //------------------------------------------------------------------ + /// Set the condition expression to be checked when the breakpoint is hit. + /// @param[in] expression + /// The method that will get called when the breakpoint is hit. + //------------------------------------------------------------------ + void + SetCondition (void *expression); + + //------------------------------------------------------------------ + // The next section are various utility functions. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Return the number of breakpoint locations that have resolved to + /// actual breakpoint sites. + /// + /// @return + /// The number locations resolved breakpoint sites. + //------------------------------------------------------------------ + size_t + GetNumResolvedLocations() const; + + //------------------------------------------------------------------ + /// Return the number of breakpoint locations. + /// + /// @return + /// The number breakpoint locations. + //------------------------------------------------------------------ + size_t + GetNumLocations() const; + + //------------------------------------------------------------------ + /// Put a description of this breakpoint into the stream \a s. + /// + /// @param[in] s + /// Stream into which to dump the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void + GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations = false); + + //------------------------------------------------------------------ + /// Accessor for the breakpoint Target. + /// @return + /// This breakpoint's Target. + //------------------------------------------------------------------ + Target & + GetTarget (); + + const Target & + GetTarget () const; + + void + GetResolverDescription (Stream *s); + + void + GetFilterDescription (Stream *s); + + //------------------------------------------------------------------ + /// Returns the BreakpointOptions structure set at the breakpoint level. + /// + /// Meant to be used by the BreakpointLocation class. + /// + /// @return + /// A pointer to this breakpoint's BreakpointOptions. + //------------------------------------------------------------------ + BreakpointOptions * + GetOptions (); + + +protected: + friend class Target; + friend class BreakpointLocation; // To call InvokeCallback + //------------------------------------------------------------------ + /// Constructors and Destructors + /// Only the Target can make a breakpoint, and it owns the breakpoint lifespans. + /// The constructor takes a filter and a resolver. Up in Target there are convenience + /// variants that make breakpoints for some common cases. + //------------------------------------------------------------------ + // This is the generic constructor + Breakpoint(Target &target, lldb::SearchFilterSP &filter_sp, lldb::BreakpointResolverSP &resolver_sp); + + //------------------------------------------------------------------ + // Protected Methods + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Invoke the callback action when the breakpoint is hit. + /// + /// Meant to be used by the BreakpointLocation class. + /// + /// @param[in] context + /// Described the breakpoint event. + /// + /// @param[in] bp_loc_id + /// Which breakpoint location hit this breakpoint. + /// + /// @return + /// \b true if the target should stop at this breakpoint and \b false not. + //------------------------------------------------------------------ + bool + InvokeCallback (StoppointCallbackContext *context, + lldb::break_id_t bp_loc_id); + +protected: + + //------------------------------------------------------------------ + /// Returns the shared pointer that this breakpoint holds for the + /// breakpoint location passed in as \a bp_loc_ptr. Passing in a + /// breakpoint location that doesn't belong to this breakpoint will + /// cause an assert. + /// + /// Meant to be used by the BreakpointLocation::GetSP() function. + /// + /// @return + /// A copy of the shared pointer for the given location. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + GetLocationSP (BreakpointLocation *bp_loc_ptr); + +private: + //------------------------------------------------------------------ + // For Breakpoint only + //------------------------------------------------------------------ + Target &m_target; // The target that holds this breakpoint. + lldb::SearchFilterSP m_filter_sp; // The filter that constrains the breakpoint's domain. + lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint. + BreakpointOptions m_options; // Settable breakpoint options + BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint. + + DISALLOW_COPY_AND_ASSIGN(Breakpoint); +}; + +} // namespace lldb_private + +#endif // liblldb_Breakpoint_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointID.h b/lldb/include/lldb/Breakpoint/BreakpointID.h new file mode 100644 index 00000000000..9e352100b9e --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointID.h @@ -0,0 +1,117 @@ +//===-- BreakpointID.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointID_h_ +#define liblldb_BreakpointID_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// class BreakpointID +//---------------------------------------------------------------------- + +class BreakpointID +{ +public: + + BreakpointID (lldb::break_id_t bp_id = LLDB_INVALID_BREAK_ID, + lldb::break_id_t loc_id = LLDB_INVALID_BREAK_ID); + + virtual + ~BreakpointID (); + + lldb::break_id_t + GetBreakpointID () + { + return m_break_id; + } + + lldb::break_id_t + GetLocationID () + { + return m_location_id; + } + + void + SetID (lldb::break_id_t bp_id, lldb::break_id_t loc_id) + { + m_break_id = bp_id; + m_location_id = loc_id; + } + + void + SetBreakpointID (lldb::break_id_t bp_id) + { + m_break_id = bp_id; + } + + void + SetBreakpointLocationID (lldb::break_id_t loc_id) + { + m_location_id = loc_id; + } + + void + GetDescription (Stream *s, lldb::DescriptionLevel level); + + static bool + IsRangeIdentifier (const char *str); + + static bool + IsValidIDExpression (const char *str); + + static const char *g_range_specifiers[]; + + //------------------------------------------------------------------ + /// Takes an input string containing the description of a breakpoint or breakpoint and location + /// and returns the breakpoint ID and the breakpoint location id. + /// + /// @param[in] input + /// A string containing JUST the breakpoint description. + /// @param[out] break_id + /// This is the break id. + /// @param[out] break_loc_id + /// This is breakpoint location id, or LLDB_INVALID_BREAK_ID is no location was specified. + /// @return + /// \b true if the call was able to extract a breakpoint location from the string. \b false otherwise. + //------------------------------------------------------------------ + static bool + ParseCanonicalReference (const char *input, lldb::break_id_t *break_id, lldb::break_id_t *break_loc_id); + + + //------------------------------------------------------------------ + /// Takes a breakpoint ID and the breakpoint location id and returns + /// a string containing the canonical description for the breakpoint + /// or breakpoint location. + /// + /// @param[out] break_id + /// This is the break id. + /// + /// @param[out] break_loc_id + /// This is breakpoint location id, or LLDB_INVALID_BREAK_ID is no + /// location is to be specified. + //------------------------------------------------------------------ + static void + GetCanonicalReference (Stream *s, lldb::break_id_t break_id, lldb::break_id_t break_loc_id); + +protected: + lldb::break_id_t m_break_id; + lldb::break_id_t m_location_id; +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointID_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointIDList.h b/lldb/include/lldb/Breakpoint/BreakpointIDList.h new file mode 100644 index 00000000000..bc88087616d --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointIDList.h @@ -0,0 +1,82 @@ +//===-- BreakpointIDList.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointIDList_h_ +#define liblldb_BreakpointIDList_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Breakpoint/BreakpointID.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// class BreakpointIDList +//---------------------------------------------------------------------- + + +class BreakpointIDList +{ +public: + typedef std::vector<BreakpointID> BreakpointIDArray; + + BreakpointIDList (); + + virtual + ~BreakpointIDList (); + + int + Size(); + + BreakpointID & + GetBreakpointIDAtIndex (int index); + + bool + RemoveBreakpointIDAtIndex (int index); + + void + Clear(); + + bool + AddBreakpointID (BreakpointID bp_id); + + bool + AddBreakpointID (const char *bp_id); + + bool + FindBreakpointID (BreakpointID &bp_id, int *position); + + bool + FindBreakpointID (const char *bp_id, int *position); + + void + InsertStringArray (const char **string_array, int array_size, CommandReturnObject &result); + + static bool + StringContainsIDRangeExpression (const char *in_string, int *range_start_len, int *range_end_pos); + + static void + FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result, Args &new_args); + +private: + BreakpointIDArray m_breakpoint_ids; + BreakpointID m_invalid_id; + + DISALLOW_COPY_AND_ASSIGN(BreakpointIDList); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointIDList_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointList.h b/lldb/include/lldb/Breakpoint/BreakpointList.h new file mode 100644 index 00000000000..225bb3ba498 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointList.h @@ -0,0 +1,177 @@ +//===-- BreakpointList.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointList_h_ +#define liblldb_BreakpointList_h_ + +// C Includes +// C++ Includes +#include <list> +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointList BreakpointList.h "lldb/Breakpoint/BreakpointList.h" +/// @brief This class manages a list of breakpoints. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// Allows adding and removing breakpoints and find by ID and index. +//---------------------------------------------------------------------- + +class BreakpointList +{ +public: + BreakpointList (bool is_internal); + + ~BreakpointList(); + + //------------------------------------------------------------------ + /// Add the breakpoint \a bp_sp to the list. + /// + /// @param[in] bp_sp + /// Shared pointer to the breakpoint that will get added to the list. + /// + /// @result + /// Returns breakpoint id. + //------------------------------------------------------------------ + virtual lldb::break_id_t + Add (lldb::BreakpointSP& bp_sp); + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint with id \a breakID. + /// + /// @param[in] breakID + /// The breakpoint ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointSP + FindBreakpointByID (lldb::break_id_t breakID); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint with id \a breakID. Const version. + /// + /// @param[in] breakID + /// The breakpoint ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointSP + FindBreakpointByID (lldb::break_id_t breakID) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint with index \a i. + /// + /// @param[in] i + /// The breakpoint index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointSP + GetBreakpointByIndex (uint32_t i); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint with index \a i, const version + /// + /// @param[in] i + /// The breakpoint index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointSP + GetBreakpointByIndex (uint32_t i) const; + + //------------------------------------------------------------------ + /// Returns the number of elements in this breakpoint list. + /// + /// @result + /// The number of elements. + //------------------------------------------------------------------ + size_t + GetSize() const { return m_breakpoints.size(); } + + //------------------------------------------------------------------ + /// Removes the breakpoint given by \b breakID from this list. + /// + /// @param[in] breakID + /// The breakpoint index to remove. + /// + /// @result + /// \b true if the breakpoint \a breakID was in the list. + //------------------------------------------------------------------ + bool + Remove (lldb::break_id_t breakID); + + void + SetEnabledAll (bool enabled); + + //------------------------------------------------------------------ + /// Removes all the breakpoints from this list. + //------------------------------------------------------------------ + void + RemoveAll (); + + //------------------------------------------------------------------ + /// Tell all the breakpoints to update themselves due to a change in the + /// modules in \a module_list. \a added says whether the module was loaded + /// or unloaded. + /// + /// @param[in] module_list + /// The module list that has changed. + /// + /// @param[in] added + /// \b true if the modules are loaded, \b false if unloaded. + //------------------------------------------------------------------ + void + UpdateBreakpoints (ModuleList &module_list, bool added); + + void + ClearAllBreakpointSites (); + +protected: + typedef std::list<lldb::BreakpointSP> bp_collection; + + bp_collection::iterator + GetBreakpointIDIterator(lldb::break_id_t breakID); + + bp_collection::const_iterator + GetBreakpointIDConstIterator(lldb::break_id_t breakID) const; + + mutable Mutex m_mutex; + bp_collection m_breakpoints; // The breakpoint list, currently a list. + lldb::break_id_t m_next_break_id; + bool m_is_internal; + +private: + DISALLOW_COPY_AND_ASSIGN (BreakpointList); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointList_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h new file mode 100644 index 00000000000..d51184d8760 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -0,0 +1,354 @@ +//===-- BreakpointLocation.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointLocation_h_ +#define liblldb_BreakpointLocation_h_ + +// C Includes + +// C++ Includes +#include <list> +#include <memory> + +// Other libraries and framework includes + +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Breakpoint/StoppointLocation.h" +#include "lldb/Core/Address.h" +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointOptions.h" +#include "lldb/Target/Process.h" +#include "lldb/Core/StringList.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointLocation BreakpointLocation.h "lldb/Breakpoint/BreakpointLocation.h" +/// @brief Class that manages one unique (by address) instance of a logical breakpoint. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// A breakpoint location is defined by the breakpoint that produces it, +/// and the address that resulted in this particular instantiation. +/// Each breakpoint location also may have a breakpoint site if its +/// address has been loaded into the program. +/// Finally it has a settable options object. +/// +/// FIXME: Should we also store some fingerprint for the location, so +/// we can map one location to the "equivalent location" on rerun? This +/// would be useful if you've set options on the locations. +//---------------------------------------------------------------------- + +class BreakpointLocation : public StoppointLocation +{ +public: + + ~BreakpointLocation (); + + //------------------------------------------------------------------ + /// Gets the load address for this breakpoint location + /// @return + /// Returns breakpoint location load address, \b + /// LLDB_INVALID_ADDRESS if not yet set. + //------------------------------------------------------------------ + lldb::addr_t + GetLoadAddress (); + + //------------------------------------------------------------------ + /// Gets the Address for this breakpoint location + /// @return + /// Returns breakpoint location Address. + //------------------------------------------------------------------ + Address & + GetAddress (); + //------------------------------------------------------------------ + /// Gets the Breakpoint that created this breakpoint location + /// @return + /// Returns the owning breakpoint. + //------------------------------------------------------------------ + Breakpoint & + GetBreakpoint (); + + //------------------------------------------------------------------ + /// Determines whether we should stop due to a hit at this + /// breakpoint location. + /// + /// Side Effects: This may evaluate the breakpoint condition, and + /// run the callback. So this command may do a considerable amount + /// of work. + /// + /// @return + /// \b true if this breakpoint location thinks we should stop, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldStop (StoppointCallbackContext *context); + + //------------------------------------------------------------------ + // The next section deals with various breakpoint options. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// If \a enable is \b true, enable the breakpoint, if \b false + /// disable it. + //------------------------------------------------------------------ + void + SetEnabled(bool enabled); + + //------------------------------------------------------------------ + /// Check the Enable/Disable state. + /// + /// @return + /// \b true if the breakpoint is enabled, \b false if disabled. + //------------------------------------------------------------------ + bool + IsEnabled (); + + //------------------------------------------------------------------ + /// Return the current Ignore Count. + /// + /// @return + /// The number of breakpoint hits to be ignored. + //------------------------------------------------------------------ + int32_t + GetIgnoreCount (); + + //------------------------------------------------------------------ + /// Set the breakpoint to ignore the next \a count breakpoint hits. + /// + /// @param[in] count + /// The number of breakpoint hits to ignore. + //------------------------------------------------------------------ + void + SetIgnoreCount (int32_t n); + + //------------------------------------------------------------------ + /// Set the callback action invoked when the breakpoint is hit. + /// + /// The callback will return a bool indicating whether the target + /// should stop at this breakpoint or not. + /// + /// @param[in] callback + /// The method that will get called when the breakpoint is hit. + /// + /// @param[in] callback_baton_sp + /// A shared pointer to a Baton that provides the void * needed + /// for the callback. + /// + /// @see lldb_private::Baton + //------------------------------------------------------------------ + void + SetCallback (BreakpointHitCallback callback, + const lldb::BatonSP &callback_baton_sp, + bool is_synchronous); + + void + SetCallback (BreakpointHitCallback callback, + void *baton, + bool is_synchronous); + + void + ClearCallback (); + + //------------------------------------------------------------------ + /// Set the condition expression to be checked when the breakpoint is hit. + /// + /// @param[in] expression + /// The method that will get called when the breakpoint is hit. + //------------------------------------------------------------------ + void + SetCondition (void *condition); + + + //------------------------------------------------------------------ + /// Set the valid thread to be checked when the breakpoint is hit. + /// + /// @param[in] thread_id + /// If this thread hits the breakpoint, we stop, otherwise not. + //------------------------------------------------------------------ + void + SetThreadID (lldb::tid_t thread_id); + + //------------------------------------------------------------------ + /// Return the current stop thread value. + /// + /// @return + /// The thread id for which the breakpoint hit will stop, + /// LLDB_INVALID_THREAD_ID for all threads. + //------------------------------------------------------------------ + lldb::tid_t + GetThreadID (); + + //------------------------------------------------------------------ + // The next section deals with this location's breakpoint sites. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Try to resolve the breakpoint site for this location. + /// + /// @return + /// \b true if we were successful at setting a breakpoint site, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + ResolveBreakpointSite (); + + //------------------------------------------------------------------ + /// Clear this breakpoint location's breakpoint site - for instance + /// when disabling the breakpoint. + /// + /// @return + /// \b true if there was a breakpoint site to be cleared, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + ClearBreakpointSite (); + + //------------------------------------------------------------------ + /// Return whether this breakpoint location has a breakpoint site. + /// @return + /// \b true if there was a breakpoint site for this breakpoint + /// location, \b false otherwise. + //------------------------------------------------------------------ + bool + IsResolved () const; + + //------------------------------------------------------------------ + // The next section are generic report functions. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Print a description of this breakpoint location to the stream + /// \a s. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void + GetDescription (Stream *s, lldb::DescriptionLevel level); + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Use this to set location specific breakpoint options. + /// + /// It will create a copy of the containing breakpoint's options if + /// that hasn't been done already + /// + /// @return + /// A pointer to the breakpoint options. + //------------------------------------------------------------------ + BreakpointOptions * + GetLocationOptions (); + + //------------------------------------------------------------------ + /// Use this to access location specific breakpoint options. + /// + /// @return + /// A pointer to the containing breakpoint's options if this + /// location doesn't have its own copy. + //------------------------------------------------------------------ + BreakpointOptions * + GetOptionsNoCopy (); + +protected: + friend class Breakpoint; + friend class CommandObjectBreakpointCommandAdd; + friend class Process; + + //------------------------------------------------------------------ + /// Invoke the callback action when the breakpoint is hit. + /// + /// Meant to be used by the BreakpointLocation class. + /// + /// @param[in] context + /// Described the breakpoint event. + /// + /// @param[in] bp_loc_id + /// Which breakpoint location hit this breakpoint. + /// + /// @return + /// \b true if the target should stop at this breakpoint and \b + /// false not. + //------------------------------------------------------------------ + bool + InvokeCallback (StoppointCallbackContext *context); + + //------------------------------------------------------------------ + /// Set the breakpoint site for this location to \a bp_site_sp. + /// + /// @param[in] bp_site_sp + /// The breakpoint site we are setting for this location. + /// + /// @return + /// \b true if we were successful at setting the breakpoint site, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + SetBreakpointSite (lldb::BreakpointSiteSP& bp_site_sp); + +private: + + //------------------------------------------------------------------ + // Constructors and Destructors + // + // Only the Breakpoint can make breakpoint locations, and it owns + // them. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Constructor. + /// + /// @param[in] owner + /// A back pointer to the breakpoint that owns this location. + /// + /// @param[in] addr + /// The Address defining this location. + /// + /// @param[in] tid + /// The thread for which this breakpoint location is valid, or + /// LLDB_INVALID_THREAD_ID if it is valid for all threads. + /// + /// @param[in] hardware + /// \b true if a hardware breakpoint is requested. + //------------------------------------------------------------------ + + BreakpointLocation (lldb::break_id_t bid, + Breakpoint &owner, + Address &addr, + lldb::tid_t tid = LLDB_INVALID_THREAD_ID, + bool hardware = false); + + //------------------------------------------------------------------ + // Data members: + //------------------------------------------------------------------ + Address m_address; ///< The address defining this location. + Breakpoint &m_owner; ///< The breakpoint that produced this object. + std::auto_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options. + lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.) + + DISALLOW_COPY_AND_ASSIGN (BreakpointLocation); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointLocation_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h new file mode 100644 index 00000000000..9e04a2c4277 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -0,0 +1,187 @@ +//===-- BreakpointLocationCollection.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointLocationCollection_h_ +#define liblldb_BreakpointLocationCollection_h_ + +// C Includes +// C++ Includes +#include <vector> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class BreakpointLocationCollection +{ +public: + BreakpointLocationCollection(); + + ~BreakpointLocationCollection(); + + //------------------------------------------------------------------ + /// Add the breakpoint \a bp_loc_sp to the list. + /// + /// @param[in] bp_sp + /// Shared pointer to the breakpoint location that will get added + /// to the list. + /// + /// @result + /// Returns breakpoint location id. + //------------------------------------------------------------------ + void + Add (const lldb::BreakpointLocationSP& bp_loc_sp); + + //------------------------------------------------------------------ + /// Removes the breakpoint location given by \b breakID from this + /// list. + /// + /// @param[in] break_id + /// The breakpoint index to remove. + /// + /// @param[in] break_loc_id + /// The breakpoint location index in break_id to remove. + /// + /// @result + /// \b true if the breakpoint was in the list. + //------------------------------------------------------------------ + bool + Remove (lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with id \a + /// breakID. + /// + /// @param[in] break_id + /// The breakpoint ID to seek for. + /// + /// @param[in] break_loc_id + /// The breakpoint location ID in \a break_id to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + FindByIDPair (lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with id \a + /// breakID, const version. + /// + /// @param[in] breakID + /// The breakpoint location ID to seek for. + /// + /// @param[in] break_loc_id + /// The breakpoint location ID in \a break_id to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointLocationSP + FindByIDPair (lldb::user_id_t break_id, lldb::user_id_t break_loc_id) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with index + /// \a i. + /// + /// @param[in] i + /// The breakpoint location index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + GetByIndex (uint32_t i); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with index + /// \a i, const version. + /// + /// @param[in] i + /// The breakpoint location index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointLocationSP + GetByIndex (uint32_t i) const; + + //------------------------------------------------------------------ + /// Returns the number of elements in this breakpoint location list. + /// + /// @result + /// The number of elements. + //------------------------------------------------------------------ + size_t + GetSize() const { return m_break_loc_collection.size(); } + + //------------------------------------------------------------------ + /// Enquires of all the breakpoint locations in this list whether + /// we should stop at a hit at \a breakID. + /// + /// @param[in] context + /// This contains the information about this stop. + /// + /// @param[in] breakID + /// This break ID that we hit. + /// + /// @return + /// \b true if we should stop, \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldStop (StoppointCallbackContext *context); + + //------------------------------------------------------------------ + /// Print a description of the breakpoint locations in this list + /// to the stream \a s. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void GetDescription (Stream *s, lldb::DescriptionLevel level); + + + +protected: + //------------------------------------------------------------------ + // Classes that inherit from BreakpointLocationCollection can see + // and modify these + //------------------------------------------------------------------ + +private: + //------------------------------------------------------------------ + // For BreakpointLocationCollection only + //------------------------------------------------------------------ + + typedef std::vector<lldb::BreakpointLocationSP> collection; + + collection::iterator + GetIDPairIterator(lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + + collection::const_iterator + GetIDPairConstIterator(lldb::user_id_t break_id, lldb::user_id_t break_loc_id) const; + + collection m_break_loc_collection; + +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointLocationCollection_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h new file mode 100644 index 00000000000..5c1c8ff5114 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointLocationList.h @@ -0,0 +1,285 @@ +//===-- BreakpointLocationList.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointLocationList_h_ +#define liblldb_BreakpointLocationList_h_ + +// C Includes +// C++ Includes +#include <vector> +#include <map> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Address.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointLocationList BreakpointLocationList.h "lldb/Breakpoint/BreakpointLocationList.h" +/// @brief This class is used by Breakpoint to manage a list of breakpoint locations, +// each breakpoint location in the list +/// has a unique ID, and is unique by Address as well. +//---------------------------------------------------------------------- + +class BreakpointLocationList +{ +// Only Breakpoints can make the location list, or add elements to it. +// This is not just some random collection of locations. Rather, the act of adding the location +// to this list sets its ID, and implicitly all the locations have the same breakpoint ID as +// well. If you need a generic container for breakpoint locations, use BreakpointLocationCollection. +friend class Breakpoint; + +public: + ~BreakpointLocationList(); + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location at address + /// \a addr - const version. + /// + /// @param[in] addr + /// The address to look for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointLocationSP + FindByAddress (Address &addr) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with id \a + /// breakID. + /// + /// @param[in] breakID + /// The breakpoint location ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + FindByID (lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with id + /// \a breakID, const version. + /// + /// @param[in] breakID + /// The breakpoint location ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointLocationSP + FindByID (lldb::user_id_t breakID) const; + + //------------------------------------------------------------------ + /// Returns the breakpoint location id to the breakpoint location + /// at address \a addr. + /// + /// @param[in] addr + /// The address to match. + /// + /// @result + /// The ID of the breakpoint location, or LLDB_INVALID_BREAK_ID. + //------------------------------------------------------------------ + lldb::user_id_t + FindIDByAddress (Address &addr); + + //------------------------------------------------------------------ + /// Returns a breakpoint location list of the breakpoint locations + /// in the module \a module. This list is allocated, and owned by + /// the caller. + /// + /// @param[in] module + /// The module to seek in. + /// + /// @param[in] + /// A breakpoint collection that gets any breakpoint locations + /// that match \a module appended to. + /// + /// @result + /// The number of matches + //------------------------------------------------------------------ + size_t + FindInModule (Module *module, + BreakpointLocationCollection& bp_loc_list); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with + /// index \a i. + /// + /// @param[in] i + /// The breakpoint location index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + GetByIndex (uint32_t i); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint location with index + /// \a i, const version. + /// + /// @param[in] i + /// The breakpoint location index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint. May contain a NULL + /// pointer if the breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointLocationSP + GetByIndex (uint32_t i) const; + + //------------------------------------------------------------------ + /// Removes all the locations in this list from their breakpoint site + /// owners list. + //------------------------------------------------------------------ + void + ClearAllBreakpointSites (); + + //------------------------------------------------------------------ + /// Tells all the breakopint locations in this list to attempt to + /// resolve any possible breakpoint sites. + //------------------------------------------------------------------ + void + ResolveAllBreakpointSites (); + + //------------------------------------------------------------------ + /// Returns the number of breakpoint locations in this list with + /// resolved breakpoints. + /// + /// @result + /// Number of qualifying breakpoint locations. + //------------------------------------------------------------------ + size_t + GetNumResolvedLocations() const; + + //------------------------------------------------------------------ + /// Removes the breakpoint location given by \b breakID from this + /// list. + /// + /// @param[in] breakID + /// The breakpoint location index to remove. + /// + /// @result + /// \b true if the breakpoint \a breakID was in the list. + //------------------------------------------------------------------ + bool + Remove (lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Enquires of the breakpoint location in this list with ID \a + /// breakID whether we should stop. + /// + /// @param[in] context + /// This contains the information about this stop. + /// + /// @param[in] breakID + /// This break ID that we hit. + /// + /// @return + /// \b true if we should stop, \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldStop (StoppointCallbackContext *context, + lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Returns the number of elements in this breakpoint location list. + /// + /// @result + /// The number of elements. + //------------------------------------------------------------------ + size_t + GetSize() const + { + return m_locations.size(); + } + + //------------------------------------------------------------------ + /// Print a description of the breakpoint locations in this list to + /// the stream \a s. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void + GetDescription (Stream *s, + lldb::DescriptionLevel level); + +protected: + + //------------------------------------------------------------------ + /// This is the standard constructor. + /// + /// It creates an empty breakpoint location list. It is protected + /// here because only Breakpoints are allowed to create the + /// breakpoint location list. + //------------------------------------------------------------------ + BreakpointLocationList(); + + //------------------------------------------------------------------ + /// Add the breakpoint \a bp_loc_sp to the list. + /// + /// @param[in] bp_sp + /// Shared pointer to the breakpoint location that will get + /// added to the list. + /// + /// @result + /// Returns breakpoint location id. + //------------------------------------------------------------------ + virtual lldb::user_id_t + Add (lldb::BreakpointLocationSP& bp_loc_sp); + + typedef std::vector<lldb::BreakpointLocationSP> collection; + typedef std::map<lldb_private::Address, + lldb::BreakpointLocationSP, + Address::ModulePointerAndOffsetLessThanFunctionObject> addr_map; + + // The breakpoint locations are stored in their Parent Breakpoint's location list by an + // index that is unique to this list, and not across all breakpoint location lists. + // This is only set in the Breakpoint's AddLocation method. + // There is another breakpoint location list, the owner's list in the BreakpointSite, + // but that should not reset the ID. Unfortunately UserID's SetID method is public. + lldb::break_id_t + GetNextID(); + + collection::iterator + GetIDIterator(lldb::user_id_t breakID); + + collection::const_iterator + GetIDConstIterator(lldb::user_id_t breakID) const; + + collection m_locations; + addr_map m_address_to_location; + mutable Mutex m_mutex; + lldb::break_id_t m_next_id; +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointLocationList_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h new file mode 100644 index 00000000000..e7a3e3bf1d2 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -0,0 +1,210 @@ +//===-- BreakpointOptions.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointOptions_h_ +#define liblldb_BreakpointOptions_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Baton.h" +#include "lldb/Core/StringList.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointOptions BreakpointOptions.h "lldb/Breakpoint/BreakpointOptions.h" +/// @brief Class that manages the options on a breakpoint or breakpoint location. +//---------------------------------------------------------------------- + +class BreakpointOptions +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + //------------------------------------------------------------------ + /// Default constructor. The breakpoint is enabled, and has no condition, + /// callback, ignore count, etc... + //------------------------------------------------------------------ + BreakpointOptions(); + BreakpointOptions(const BreakpointOptions& rhs); + + + //------------------------------------------------------------------ + /// This constructor allows you to specify all the breakpoint options. + /// + /// @param[in] condition + /// The expression which if it evaluates to \b true if we are to stop + /// + /// @param[in] callback + /// This is the plugin for some code that gets run, returns \b true if we are to stop. + /// + /// @param[in] baton + /// Client data that will get passed to the callback. + /// + /// @param[in] enabled + /// Is this breakpoint enabled. + /// + /// @param[in] ignore + /// How many breakpoint hits we should ignore before stopping. + /// + /// @param[in] thread_id + /// Only stop if \a thread_id hits the breakpoint. + //------------------------------------------------------------------ + BreakpointOptions(void *condition, + BreakpointHitCallback callback, + void *baton, + bool enabled = true, + int32_t ignore = 0, + lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID); + + virtual ~BreakpointOptions(); + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const BreakpointOptions& + operator=(const BreakpointOptions& rhs); + + //------------------------------------------------------------------ + // Callbacks + //------------------------------------------------------------------ + void SetCallback (BreakpointHitCallback callback, const lldb::BatonSP &baton_sp, bool synchronous = false); + bool InvokeCallback (StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + bool IsCallbackSynchronous () { + return m_callback_is_synchronous; + }; + Baton *GetBaton (); + void ClearCallback (); + + //------------------------------------------------------------------ + // Enabled/Ignore Count + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Check the Enable/Disable state. + /// @return + /// \b true if the breakpoint is enabled, \b false if disabled. + //------------------------------------------------------------------ + bool + IsEnabled () const; + + //------------------------------------------------------------------ + /// If \a enable is \b true, enable the breakpoint, if \b false disable it. + //------------------------------------------------------------------ + void + SetEnabled (bool enabled); + + void + SetIgnoreCount (int32_t n); + + //------------------------------------------------------------------ + /// Return the current Ignore Count. + /// @return + /// The number of breakpoint hits to be ignored. + //------------------------------------------------------------------ + int32_t + GetIgnoreCount () const; + + //------------------------------------------------------------------ + /// Set the breakpoint to ignore the next \a count breakpoint hits. + /// @param[in] count + /// The number of breakpoint hits to ignore. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Return the current stop thread value. + /// @return + /// The thread id for which the breakpoint hit will stop, + /// LLDB_INVALID_THREAD_ID for all threads. + //------------------------------------------------------------------ + lldb::tid_t + GetThreadID () const; + + //------------------------------------------------------------------ + /// Set the valid thread to be checked when the breakpoint is hit. + /// @param[in] thread_id + /// If this thread hits the breakpoint, we stop, otherwise not. + //------------------------------------------------------------------ + void + SetThreadID (lldb::tid_t thread_id); + + //------------------------------------------------------------------ + /// This is the default empty callback. + /// @return + /// The thread id for which the breakpoint hit will stop, + /// LLDB_INVALID_THREAD_ID for all threads. + //------------------------------------------------------------------ + static bool + NullCallback (void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + + struct CommandData + { + CommandData () : + user_source(), + script_source() + { + } + + ~CommandData () + { + } + + StringList user_source; + StringList script_source; + }; + + class CommandBaton : public Baton + { + public: + CommandBaton (CommandData *data) : + Baton (data) + { + } + + virtual + ~CommandBaton () + { + delete ((CommandData *)m_data); + m_data = NULL; + } + + virtual void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + + }; + +protected: + //------------------------------------------------------------------ + // Classes that inherit from BreakpointOptions can see and modify these + //------------------------------------------------------------------ + +private: + //------------------------------------------------------------------ + // For BreakpointOptions only + //------------------------------------------------------------------ + BreakpointHitCallback m_callback; // This is the callback function pointer + lldb::BatonSP m_callback_baton_sp; // This is the client data for the callback + bool m_callback_is_synchronous; + bool m_enabled; + int32_t m_ignore_count; // Number of times to ignore this breakpoint + lldb::tid_t m_thread_id; // Thread for which this breakpoint will take + +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointOptions_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h new file mode 100644 index 00000000000..1b1284f7970 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -0,0 +1,123 @@ +//===-- BreakpointResolver.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolver_h_ +#define liblldb_BreakpointResolver_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Address.h" +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/ConstString.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolver BreakpointResolver.h "lldb/Breakpoint/BreakpointResolver.h" +/// @brief This class works with SearchFilter to resolve logical breakpoints to their +/// of concrete breakpoint locations. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// The BreakpointResolver is a Searcher. In that protocol, +/// the SearchFilter asks the question "At what depth of the symbol context +/// descent do you want your callback to get called?" of the filter. The resolver +/// answers this question (in the GetDepth method) and provides the resolution callback. +/// Each Breakpoint has a BreakpointResolver, and it calls either ResolveBreakpoint +/// or ResolveBreakpointInModules to tell it to look for new breakpoint locations. +//---------------------------------------------------------------------- + +class BreakpointResolver : + public Searcher +{ +public: + //------------------------------------------------------------------ + /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint + /// to make sense. It can be constructed without a breakpoint, but you have to + /// call SetBreakpoint before ResolveBreakpoint. + /// + /// @param[in] bkpt + /// The breakpoint that owns this resolver. + /// + /// @result + /// Returns breakpoint location id. + //------------------------------------------------------------------ + BreakpointResolver (Breakpoint *bkpt); + + //------------------------------------------------------------------ + /// The Destructor is virtual, all significant breakpoint resolvers derive + /// from this class. + //------------------------------------------------------------------ + virtual + ~BreakpointResolver (); + + //------------------------------------------------------------------ + /// This sets the breakpoint for this resolver. + /// + /// @param[in] bkpt + /// The breakpoint that owns this resolver. + //------------------------------------------------------------------ + void + SetBreakpoint (Breakpoint *bkpt); + + //------------------------------------------------------------------ + /// In response to this method the resolver scans all the modules in the breakpoint's + /// target, and adds any new locations it finds. + /// + /// @param[in] filter + /// The filter that will manage the search for this resolver. + //------------------------------------------------------------------ + virtual void + ResolveBreakpoint (SearchFilter &filter); + + //------------------------------------------------------------------ + /// In response to this method the resolver scans the modules in the module list + /// \a modules, and adds any new locations it finds. + /// + /// @param[in] filter + /// The filter that will manage the search for this resolver. + //------------------------------------------------------------------ + virtual void + ResolveBreakpointInModules (SearchFilter &filter, + ModuleList &modules); + + //------------------------------------------------------------------ + /// Prints a canonical description for the breakpoint to the stream \a s. + /// + /// @param[in] s + /// Stream to which the output is copied. + //------------------------------------------------------------------ + virtual void + GetDescription (Stream *s) = 0; + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + virtual void + Dump (Stream *s) const = 0; + +protected: + Target *m_target; // Every resolver has a target. + Breakpoint *m_breakpoint; // This is the breakpoint we add locations to. + +private: + DISALLOW_COPY_AND_ASSIGN(BreakpointResolver); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolver_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h new file mode 100644 index 00000000000..6807bc0d8df --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -0,0 +1,68 @@ +//===-- BreakpointResolverAddress.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolverAddress_h_ +#define liblldb_BreakpointResolverAddress_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointResolver.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolverAddress BreakpointResolverAddress.h "lldb/Breakpoint/BreakpointResolverAddress.h" +/// @brief This class sets breakpoints on a given Address. This breakpoint only takes +/// once, and then it won't attempt to reset itself. +//---------------------------------------------------------------------- + +class BreakpointResolverAddress: + public BreakpointResolver +{ +public: + BreakpointResolverAddress (Breakpoint *bkpt, + const Address &addr); + + virtual + ~BreakpointResolverAddress (); + + virtual void + ResolveBreakpoint (SearchFilter &filter); + + virtual void + ResolveBreakpointInModules (SearchFilter &filter, + ModuleList &modules); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing); + + virtual Searcher::Depth + GetDepth (); + + virtual void + GetDescription (Stream *s); + + virtual void + Dump (Stream *s) const; + +protected: + Address m_addr; + +private: + DISALLOW_COPY_AND_ASSIGN(BreakpointResolverAddress); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolverAddress_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h new file mode 100644 index 00000000000..285ef525f9f --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -0,0 +1,65 @@ +//===-- BreakpointResolverFileLine.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolverFileLine_h_ +#define liblldb_BreakpointResolverFileLine_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointResolver.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolverFileLine BreakpointResolverFileLine.h "lldb/Breakpoint/BreakpointResolverFileLine.h" +/// @brief This class sets breakpoints by file and line. Optionally, it will look for inlined +/// instances of the file and line specification. +//---------------------------------------------------------------------- + +class BreakpointResolverFileLine : + public BreakpointResolver +{ +public: + BreakpointResolverFileLine (Breakpoint *bkpt, + const FileSpec &resolver, + uint32_t line_no, + bool check_inlines); + + virtual + ~BreakpointResolverFileLine (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing); + + virtual Searcher::Depth + GetDepth (); + + virtual void + GetDescription (Stream *s); + + virtual void + Dump (Stream *s) const; + +protected: + FileSpec m_file_spec; // This is the file spec we are looking for. + uint32_t m_line_number; // This is the line number that we are looking for. + bool m_inlines; // This determines whether the resolver looks for inlined functions or not. + +private: + DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileLine); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolverFileLine_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h new file mode 100644 index 00000000000..63e6b86837a --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -0,0 +1,75 @@ +//===-- BreakpointResolverName.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolverName_h_ +#define liblldb_BreakpointResolverName_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointResolver.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolverName BreakpointResolverName.h "lldb/Breakpoint/BreakpointResolverName.h" +/// @brief This class sets breakpoints on a given function name, either by exact match +/// or by regular expression. +//---------------------------------------------------------------------- + +class BreakpointResolverName: + public BreakpointResolver +{ +public: + + BreakpointResolverName (Breakpoint *bkpt, + const char *func_name, + Breakpoint::MatchType type = Breakpoint::Exact); + + // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. + BreakpointResolverName (Breakpoint *bkpt, + RegularExpression &func_regex); + + BreakpointResolverName (Breakpoint *bkpt, + const char *class_name, + const char *method, + Breakpoint::MatchType type); + + virtual + ~BreakpointResolverName (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing); + + virtual Searcher::Depth + GetDepth (); + + virtual void + GetDescription (Stream *s); + + virtual void + Dump (Stream *s) const; + +protected: + ConstString m_func_name; + ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop on methods of this class. + RegularExpression m_regex; + Breakpoint::MatchType m_match_type; + +private: + DISALLOW_COPY_AND_ASSIGN(BreakpointResolverName); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolverName_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h new file mode 100644 index 00000000000..aeb385ba18e --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -0,0 +1,258 @@ +//===-- BreakpointSite.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointSite_h_ +#define liblldb_BreakpointSite_h_ + +// C Includes + +// C++ Includes +#include <list> + +// Other libraries and framework includes + +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Breakpoint/StoppointLocation.h" +#include "lldb/Breakpoint/BreakpointLocationCollection.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointSite BreakpointSite.h "lldb/Breakpoint/BreakpointSite.h" +/// @brief Class that manages the actual breakpoint that will be inserted +/// into the running program. +/// +/// The BreakpointSite class handles the physical breakpoint that is +/// actually inserted in the target program. As such, it is also the +/// one that gets hit, when the program stops. It keeps a list of all +/// BreakpointLocations that share this phsyical site. When the +/// breakpoint is hit, all the locations are informed by the breakpoint +/// site. Breakpoint sites are owned by the process. +//---------------------------------------------------------------------- + +class BreakpointSite : public StoppointLocation +{ +public: + + enum Type + { + eSoftware, // Breakpoint opcode has been written to memory and m_saved_opcode + // and m_trap_opcode contain the saved and written opcode. + eHardware, // Breakpoint site is set as a hardware breakpoint + eExternal // Breakpoint site is managed by an external debug nub or + // debug interface where memory reads trasparently will not + // display any breakpoint opcodes. + }; + + virtual ~BreakpointSite (); + + //---------------------------------------------------------------------- + // This section manages the breakpoint traps + //---------------------------------------------------------------------- + + //------------------------------------------------------------------ + /// Returns the Opcode Bytes for this breakpoint + //------------------------------------------------------------------ + uint8_t * + GetTrapOpcodeBytes (); + + //------------------------------------------------------------------ + /// Returns the Opcode Bytes for this breakpoint - const version + //------------------------------------------------------------------ + const uint8_t * + GetTrapOpcodeBytes () const; + + //------------------------------------------------------------------ + /// Get the size of the trap opcode for this address + //------------------------------------------------------------------ + size_t + GetTrapOpcodeMaxByteSize () const; + + //------------------------------------------------------------------ + /// Sets the trap opcode + //------------------------------------------------------------------ + bool + SetTrapOpcode (const uint8_t *trap_opcode, + size_t trap_opcode_size); + + //------------------------------------------------------------------ + /// Gets the original instruction bytes that were overwritten by the trap + //------------------------------------------------------------------ + uint8_t * + GetSavedOpcodeBytes (); + + //------------------------------------------------------------------ + /// Gets the original instruction bytes that were overwritten by the trap const version + //------------------------------------------------------------------ + const uint8_t * + GetSavedOpcodeBytes () const; + + //------------------------------------------------------------------ + /// Says whether \a addr and size \a size intersects with the address \a intersect_addr + //------------------------------------------------------------------ + bool + IntersectsRange (lldb::addr_t addr, + size_t size, + lldb::addr_t *intersect_addr, + size_t *intersect_size, + size_t *opcode_offset) const; + + //------------------------------------------------------------------ + /// Tells whether the current breakpoint site is enabled or not + /// + /// This is a low-level enable bit for the breakpoint sites. If a + /// breakpoint site has no enabled owners, it should just get + /// removed. This enable/disable is for the low-level target code + /// to enable and disable breakpoint sites when single stepping, + /// etc. + //------------------------------------------------------------------ + bool + IsEnabled () const; + + //------------------------------------------------------------------ + /// Sets whether the current breakpoint site is enabled or not + /// + /// @param[in] enabled + /// \b true if the breakoint is enabled, \b false otherwise. + //------------------------------------------------------------------ + void + SetEnabled (bool enabled); + + //------------------------------------------------------------------ + /// Enquires of the breakpoint locations that produced this breakpoint site whether + /// we should stop at this location. + /// + /// @param[in] context + /// This contains the information about this stop. + /// + /// @return + /// \b true if we should stop, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + ShouldStop (StoppointCallbackContext *context); + + //------------------------------------------------------------------ + /// Standard Dump method + /// + /// @param[in] context + /// The stream to dump this output. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// The "Owners" are the breakpoint locations that share this + /// breakpoint site. The method adds the \a owner to this breakpoint + /// site's owner list. + /// + /// @param[in] context + /// \a owner is the Breakpoint Location to add. + //------------------------------------------------------------------ + void + AddOwner (lldb::BreakpointLocationSP &owner); + + //------------------------------------------------------------------ + /// This method returns the number of breakpoint locations currently + /// located at this breakpoint site. + /// + /// @return + /// The number of owners. + //------------------------------------------------------------------ + uint32_t + GetNumberOfOwners (); + + //------------------------------------------------------------------ + /// This method returns the the breakpoint location at index \a index + /// located at this breakpoint site. The owners are listed ordinally + /// from 0 to GetNumberOfOwners() - 1 so you can use this method to iterate + /// over the owners + /// + /// @param[in] index + /// The index in the list of owners for which you wish the owner location. + /// @return + /// A shared pointer to the breakpoint location at that index. + //------------------------------------------------------------------ + lldb::BreakpointLocationSP + GetOwnerAtIndex (uint32_t index); + + //------------------------------------------------------------------ + /// Print a description of this breakpoint site to the stream \a s. + /// GetDescription tells you about the breakpoint site's owners. + /// Use BreakpointSite::Dump(Stream *) to get information about the + /// breakpoint site itself. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void + GetDescription (Stream *s, + lldb::DescriptionLevel level); + + bool + IsBreakpointAtThisSite (lldb::break_id_t bp_id); + + BreakpointSite::Type + GetType () const + { + return m_type; + } + + void + SetType (BreakpointSite::Type type) + { + m_type = type; + } + +private: + friend class Process; + + //------------------------------------------------------------------ + /// The method removes the owner at \a break_loc_id from this breakpoint list. + /// + /// @param[in] context + /// \a break_loc_id is the Breakpoint Location to remove. + //------------------------------------------------------------------ + uint32_t + RemoveOwner (lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + BreakpointSite::Type m_type;///< The type of this breakpoint site. + uint8_t m_saved_opcode[8]; ///< The saved opcode bytes if this breakpoint site uses trap opcodes. + uint8_t m_trap_opcode[8]; ///< The opcode that was used to create the breakpoint if it is a software breakpoint site. + bool m_enabled; ///< Boolean indicating if this breakpoint site enabled or not. + + // Consider adding an optimization where if there is only one + // owner, we don't store a list. The usual case will be only one owner... + BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site. + + static lldb::break_id_t + GetNextID(); + + // Only the Process can create breakpoint sites in + // Process::CreateBreakpointSite (lldb::BreakpointLocationSP &, bool). + BreakpointSite (BreakpointSiteList *list, + lldb::BreakpointLocationSP& owner, + lldb::addr_t m_addr, + lldb::tid_t tid, + bool use_hardware); + + DISALLOW_COPY_AND_ASSIGN(BreakpointSite); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointSite_h_ diff --git a/lldb/include/lldb/Breakpoint/BreakpointSiteList.h b/lldb/include/lldb/Breakpoint/BreakpointSiteList.h new file mode 100644 index 00000000000..bfa8c51e3e8 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/BreakpointSiteList.h @@ -0,0 +1,217 @@ +//===-- BreakpointSiteList.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointSiteList_h_ +#define liblldb_BreakpointSiteList_h_ + +// C Includes +// C++ Includes +#include <map> +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/BreakpointSite.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointSiteList BreakpointSiteList.h "lldb/Breakpoint/BreakpointSiteList.h" +/// @brief Class that manages lists of BreakpointSite shared pointers. +//---------------------------------------------------------------------- +class BreakpointSiteList +{ +// At present Process directly accesses the map of BreakpointSites so it can +// do quick lookups into the map (using GetMap). +// FIXME: Find a better interface for this. +friend class Process; + +public: + //------------------------------------------------------------------ + /// Default constructor makes an empty list. + //------------------------------------------------------------------ + BreakpointSiteList(); + + //------------------------------------------------------------------ + /// Destructor, currently does nothing. + //------------------------------------------------------------------ + ~BreakpointSiteList(); + + //------------------------------------------------------------------ + /// Add a BreakpointSite to the list. + /// + /// @param[in] bp_site_sp + /// A shared pointer to a breakpoint site being added to the list. + /// + /// @return + /// The ID of the BreakpointSite in the list. + //------------------------------------------------------------------ + lldb::user_id_t + Add (const lldb::BreakpointSiteSP& bp_site_sp); + + //------------------------------------------------------------------ + /// Standard Dump routine, doesn't do anything at present. + /// @param[in] s + /// Stream into which to dump the description. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint site at address + /// \a addr. + /// + /// @param[in] addr + /// The address to look for. + /// + /// @result + /// A shared pointer to the breakpoint site. May contain a NULL + /// pointer if no breakpoint site exists with a matching address. + //------------------------------------------------------------------ + lldb::BreakpointSiteSP + FindByAddress (lldb::addr_t addr); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint site with id \a breakID. + /// + /// @param[in] breakID + /// The breakpoint site ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint site. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointSiteSP + FindByID (lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint site with id \a breakID - const version. + /// + /// @param[in] breakID + /// The breakpoint site ID to seek for. + /// + /// @result + /// A shared pointer to the breakpoint site. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointSiteSP + FindByID (lldb::user_id_t breakID) const; + + //------------------------------------------------------------------ + /// Returns the breakpoint site id to the breakpoint site at address \a addr. + /// + /// @param[in] addr + /// The address to match. + /// + /// @result + /// The ID of the breakpoint site, or LLDB_INVALID_BREAK_ID. + //------------------------------------------------------------------ + lldb::user_id_t + FindIDByAddress (lldb::addr_t addr); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint site with index \a i. + /// + /// @param[in] i + /// The breakpoint site index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint site. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + lldb::BreakpointSiteSP + GetByIndex (uint32_t i); + + //------------------------------------------------------------------ + /// Returns a shared pointer to the breakpoint site with index \a i - const version. + /// + /// @param[in] i + /// The breakpoint site index to seek for. + /// + /// @result + /// A shared pointer to the breakpoint site. May contain a NULL pointer if the + /// breakpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::BreakpointSiteSP + GetByIndex (uint32_t i) const; + + //------------------------------------------------------------------ + /// Removes the breakpoint site given by \b breakID from this list. + /// + /// @param[in] breakID + /// The breakpoint site index to remove. + /// + /// @result + /// \b true if the breakpoint site \a breakID was in the list. + //------------------------------------------------------------------ + bool + Remove (lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Removes the breakpoint site at address \a addr from this list. + /// + /// @param[in] addr + /// The address from which to remove a breakpoint site. + /// + /// @result + /// \b true if \a addr had a breakpoint site to remove from the list. + //------------------------------------------------------------------ + bool + RemoveByAddress (lldb::addr_t addr); + + void + SetEnabledForAll(const bool enable, const lldb::user_id_t except_id = LLDB_INVALID_BREAK_ID); + + typedef void (*BreakpointSiteSPMapFunc) (lldb::BreakpointSiteSP &bp, void *baton); + + //------------------------------------------------------------------ + /// Enquires of the breakpoint site on in this list with ID \a breakID whether + /// we should stop for the breakpoint or not. + /// + /// @param[in] context + /// This contains the information about this stop. + /// + /// @param[in] breakID + /// This break ID that we hit. + /// + /// @return + /// \b true if we should stop, \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldStop (StoppointCallbackContext *context, lldb::user_id_t breakID); + + //------------------------------------------------------------------ + /// Returns the number of elements in the list. + /// + /// @result + /// The number of elements. + //------------------------------------------------------------------ + size_t + GetSize() const { return m_bp_site_list.size(); } + +protected: + typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection; + + collection::iterator + GetIDIterator(lldb::user_id_t breakID); + + collection::const_iterator + GetIDConstIterator(lldb::user_id_t breakID) const; + + // This function exposes the m_bp_site_list. I use the in Process because there + // are places there where you want to iterate over the list, and it is less efficient + // to do it by index. FIXME: Find a better way to do this. + + const collection * + GetMap (); + + collection m_bp_site_list; // The breakpoint site list. +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointSiteList_h_ diff --git a/lldb/include/lldb/Breakpoint/Stoppoint.h b/lldb/include/lldb/Breakpoint/Stoppoint.h new file mode 100644 index 00000000000..c294830f15e --- /dev/null +++ b/lldb/include/lldb/Breakpoint/Stoppoint.h @@ -0,0 +1,63 @@ +//===-- Stoppoint.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Stoppoint_h_ +#define liblldb_Stoppoint_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" + +namespace lldb_private { + +class Stoppoint +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Stoppoint(); + + virtual + ~Stoppoint(); + + //------------------------------------------------------------------ + // Methods + //------------------------------------------------------------------ + virtual void + Dump (Stream *) = 0; + + virtual bool + IsEnabled () = 0; + + virtual void + SetEnabled (bool enable) = 0; + + lldb::break_id_t + GetID () const; + + void + SetID (lldb::break_id_t bid); + +protected: + lldb::break_id_t m_bid; + +private: + //------------------------------------------------------------------ + // For Stoppoint only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Stoppoint); +}; + +} // namespace lldb_private + +#endif // liblldb_Stoppoint_h_ diff --git a/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h b/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h new file mode 100644 index 00000000000..f2a6401e748 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/StoppointCallbackContext.h @@ -0,0 +1,58 @@ +//===-- StoppointCallbackContext.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StoppointCallbackContext_h_ +#define liblldb_StoppointCallbackContext_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Target/ExecutionContext.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class StoppointCallbackContext StoppointCallbackContext.h "lldb/Breakpoint/StoppointCallbackContext.h" +/// @brief Class holds the information that a breakpoint callback needs to evaluate this stop. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// When we hit a breakpoint we need to package up whatever information is needed +/// to evaluate breakpoint commands and conditions. This class is the container of +/// that information. +//---------------------------------------------------------------------- + +class StoppointCallbackContext +{ +public: + StoppointCallbackContext(); + + StoppointCallbackContext(Event *event, Process* process, Thread *thread = NULL, StackFrame * frame = NULL, bool synchronously = false); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the event, process and thread to NULL, and the frame index to an + /// invalid value. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Event *event; // This is the event, the callback can modify this to indicate + // the meaning of the breakpoint hit + ExecutionContext context; // This tells us where we have stopped, what thread. + bool is_synchronous; // Is the callback being executed synchronously with the breakpoint, + // or asynchronously as the event is retrieved? +}; + +} // namespace lldb_private + +#endif // liblldb_StoppointCallbackContext_h_ diff --git a/lldb/include/lldb/Breakpoint/StoppointLocation.h b/lldb/include/lldb/Breakpoint/StoppointLocation.h new file mode 100644 index 00000000000..b52551005a6 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/StoppointLocation.h @@ -0,0 +1,111 @@ +//===-- StoppointLocation.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StoppointLocation_h_ +#define liblldb_StoppointLocation_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +// #include "lldb/Breakpoint/BreakpointOptions.h" + +namespace lldb_private { + +class StoppointLocation +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StoppointLocation (lldb::break_id_t bid, + lldb::addr_t m_addr, + lldb::tid_t tid, + bool hardware); + + StoppointLocation (lldb::break_id_t bid, + lldb::addr_t m_addr, + lldb::tid_t tid, + size_t size, + bool hardware); + + virtual + ~StoppointLocation (); + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + // Methods + //------------------------------------------------------------------ + virtual lldb::addr_t + GetLoadAddress () const; + + size_t + GetByteSize () const; + + uint32_t + GetHitCount () const; + + void + IncrementHitCount (); + + uint32_t + GetHardwareIndex () const; + + lldb::tid_t + GetThreadID() const; + + bool + HardwarePreferred () const; + + bool + IsHardware () const; + + virtual bool + ShouldStop (StoppointCallbackContext *context); + + virtual void + Dump (Stream *stream) const; + + void + SetHardwareIndex (uint32_t index); + + lldb::break_id_t + GetID () const; + +protected: + //------------------------------------------------------------------ + // Classes that inherit from StoppointLocation can see and modify these + //------------------------------------------------------------------ + lldb::break_id_t m_loc_id; // Break ID + lldb::tid_t m_tid; // The thread ID if this stoppoint location is thread specific, or LLDB_INVALID_THREAD_ID if not thread specific. + lldb::addr_t m_addr; // The load address of this stop point. The base Stoppoint doesn't + // store a full Address since that's not needed for the breakpoint sites. + bool m_hw_preferred; // 1 if this point has been requested to be set using hardware (which may fail due to lack of resources) + uint32_t m_hw_index; // The hardware resource index for this breakpoint/watchpoint + uint32_t m_byte_size; // The size in bytes of stop location. e.g. the length of the trap opcode for + // software breakpoints, or the optional length in bytes for + // hardware breakpoints, or the length of the watchpoint. + uint32_t m_hit_count; // Number of times this breakpoint has been hit + +private: + //------------------------------------------------------------------ + // For StoppointLocation only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(StoppointLocation); + StoppointLocation(); // Disallow default constructor +}; + +} // namespace lldb_private + +#endif // liblldb_StoppointLocation_h_ diff --git a/lldb/include/lldb/Breakpoint/WatchpointLocation.h b/lldb/include/lldb/Breakpoint/WatchpointLocation.h new file mode 100644 index 00000000000..9bf559d7166 --- /dev/null +++ b/lldb/include/lldb/Breakpoint/WatchpointLocation.h @@ -0,0 +1,69 @@ +//===-- WatchpointLocation.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_WatchpointLocation_h_ +#define liblldb_WatchpointLocation_h_ + +// C Includes + +// C++ Includes +#include <list> + +// Other libraries and framework includes + +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Breakpoint/StoppointLocation.h" + +namespace lldb_private { + +class WatchpointLocation : + public StoppointLocation +{ +public: + + WatchpointLocation (lldb::addr_t m_addr, lldb::tid_t tid, bool hardware); + + ~WatchpointLocation (); + + bool + IsEnabled () const; + + void + SetEnabled (uint32_t enabled); + + bool WatchpointRead () const; + bool WatchpointWrite () const; + int32_t GetIgnoreCount () const; + void SetIgnoreCount (int32_t n); + void SetWatchpointType (uint32_t type); + bool BreakpointWasHit (StoppointCallbackContext *context); + bool SetCallback (WatchpointHitCallback callback, void *callback_baton); + void Dump (Stream *s) const; + +private: + bool m_enabled; // Is this breakpoint enabled + uint32_t m_watch_read:1, // 1 if we stop when the watched data is read from + m_watch_write:1, // 1 if we stop when the watched data is written to + m_watch_was_read:1, // Set to 1 when watchpoint is hit for a read access + m_watch_was_written:1; // Set to 1 when watchpoint is hit for a write access + int32_t m_ignore_count; // Number of times to ignore this breakpoint + WatchpointHitCallback m_callback; + void * m_callback_baton; // Callback user data to pass to callback + + static lldb::break_id_t + GetNextID(); + + DISALLOW_COPY_AND_ASSIGN (WatchpointLocation); +}; + +} // namespace lldb_private + +#endif // liblldb_WatchpointLocation_h_ diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h new file mode 100644 index 00000000000..14991085ec8 --- /dev/null +++ b/lldb/include/lldb/Core/Address.h @@ -0,0 +1,425 @@ +//===-- Address.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Address_h_ +#define liblldb_Address_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Symbol/SymbolContextScope.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Address Address.h "lldb/Core/Address.h" +/// @brief A section + offset based address class. +/// +/// The Address class allows addresses to be relative to a section +/// that can move during runtime due to images (executables, shared +/// libraries, bundles, frameworks) being loaded at different +/// addresses than the addresses found in the object file that +/// represents them on disk. There are currently two types of addresses +/// for a section: +/// @li file addresses +/// @li load addresses +/// +/// File addresses represent the virtual addresses that are in the "on +/// disk" object files. These virtual addresses are converted to be +/// relative to unique sections scoped to the object file so that +/// when/if the addresses slide when the images are loaded/unloaded +/// in memory, we can easily track these changes without having to +/// update every object (compile unit ranges, line tables, function +/// address ranges, lexical block and inlined subroutine address +/// ranges, global and static variables) each time an image is loaded or +/// unloaded. +/// +/// Load addresses represent the virtual addresses where each section +/// ends up getting loaded at runtime. Before executing a program, it +/// is common for all of the load addresses to be unresolved. When a +/// DynamicLoader plug-in receives notification that shared libraries +/// have been loaded/unloaded, the load addresses of the main executable +/// and any images (shared libraries) will be resolved/unresolved. When +/// this happens, breakpoints that are in one of these sections can be +/// set/cleared. +//---------------------------------------------------------------------- +class Address : + public SymbolContextScope +{ +public: + //------------------------------------------------------------------ + /// Dump styles allow the Address::Dump(Stream *,DumpStyle) const + /// function to display Address contents in a variety of ways. + //------------------------------------------------------------------ + typedef enum { + DumpStyleInvalid, ///< Invalid dump style + DumpStyleSectionNameOffset, ///< Display as the section name + offset. + ///< \code + /// // address for printf in libSystem.B.dylib as a section name + offset + /// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf + /// \endcode + DumpStyleSectionPointerOffset, ///< Display as the section pointer + offset (debug output). + ///< \code + /// // address for printf in libSystem.B.dylib as a section pointer + offset + /// (lldb::Section *)0x35cc50 + 0x000000000005cfdf \endcode + DumpStyleFileAddress, ///< Display as the file address (if any). + ///< \code + /// // address for printf in libSystem.B.dylib as a file address + /// 0x000000000005dcff \endcode + DumpStyleModuleWithFileAddress, ///< Display as the file address with the module name prepended (if any). + ///< \code + /// // address for printf in libSystem.B.dylib as a file address + /// libSystem.B.dylib[0x000000000005dcff] \endcode + DumpStyleLoadAddress, ///< Display as the load address (if resolved). + ///< \code + /// // address for printf in libSystem.B.dylib as a load address + /// 0x00007fff8306bcff \endcode + DumpStyleResolvedDescription ///< Display the name that an address resolves to + } DumpStyle; + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize with a invalid section (NULL) and an invalid + /// offset (LLDB_INVALID_ADDRESS). + //------------------------------------------------------------------ + Address (); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Makes a copy of the another Address object \a rhs. + /// + /// @param[in] rhs + /// A const Address object reference to copy. + //------------------------------------------------------------------ + Address (const Address& rhs); + + //------------------------------------------------------------------ + /// Construct with a section pointer and offset. + /// + /// Initialize the address with the supplied \a section and \a + /// offset. + /// + /// @param[in] section + /// A section pointer to a valid lldb::Section, or NULL if the + /// address doesn't have a section or will get resolved later. + /// + /// @param[in] offset + /// The offset in bytes into \a section. + //------------------------------------------------------------------ + Address (const Section* section, lldb::addr_t offset); + + //------------------------------------------------------------------ + /// Construct with a virtual address and section list. + /// + /// Initialize and resolve the address with the supplied virtual + /// address \a file_addr. + /// + /// @param[in] file_addr + /// A virtual file address. + /// + /// @param[in] section_list + /// A list of sections, one of which may contain the \a file_addr. + //------------------------------------------------------------------ + Address (lldb::addr_t file_addr, const SectionList * section_list); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Address (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies the address value from another Address object \a rhs + /// into \a this object. + /// + /// @param[in] rhs + /// A const Address object reference to copy. + /// + /// @return + /// A const Address object reference to \a this. + //------------------------------------------------------------------ +#ifndef SWIG + const Address& + operator= (const Address& rhs); +#endif + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the section to an invalid value (NULL) and an invalid + /// offset (LLDB_INVALID_ADDRESS). + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Compare two Address objects. + /// + /// @param[in] lhs + /// The Left Hand Side const Address object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const Address object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int + CompareFileAddress (const Address& lhs, const Address& rhs); + + static int + CompareLoadAddress (const Address& lhs, const Address& rhs, Process *process); + + static int + CompareModulePointerAndOffset (const Address& lhs, const Address& rhs); + + // For use with std::map, std::multi_map + class ModulePointerAndOffsetLessThanFunctionObject + { + public: + ModulePointerAndOffsetLessThanFunctionObject () {} + + bool + operator() (const Address& a, const Address& b) const + { + return Address::CompareModulePointerAndOffset(a, b) < 0; + } + }; + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. There are many ways to display a section + /// offset based address, and \a style lets the user choose. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] style + /// The display style for the address. + /// + /// @param[in] fallback_style + /// The display style for the address. + /// + /// @return + /// Returns \b true if the address was able to be displayed. + /// File and load addresses may be unresolved and it may not be + /// possible to display a valid value, \b false will be returned + /// in such cases. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + bool + Dump (Stream *s, + ExecutionContextScope *exe_scope, + DumpStyle style, + DumpStyle fallback_style = DumpStyleInvalid) const; + + //------------------------------------------------------------------ + /// Dump a debug description of this object to a Stream. + /// + /// Dump a debug description of the contents of this object to the + /// supplied stream \a s. + /// + /// The debug description contains verbose internal state such + /// and pointer values, reference counts, etc. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + DumpDebug (Stream *s) const; + + //------------------------------------------------------------------ + /// Get the file address. + /// + /// If an address comes from a file on disk that has section + /// relative addresses, then it has a virtual address that is + /// relative to unique section in the object file. + /// + /// @return + /// The valid file virtual address, or LLDB_INVALID_ADDRESS if + /// the address doesn't have a file virtual address (image is + /// from memory only with no representation on disk). + //------------------------------------------------------------------ + lldb::addr_t + GetFileAddress () const; + + //------------------------------------------------------------------ + /// Get the load address. + /// + /// If an address comes from a file on disk that has section + /// relative addresses, then it has a virtual address that is + /// relative to unique section in the object file. Sections get + /// resolved at runtime by DynamicLoader plug-ins as images + /// (executables and shared libraries) get loaded/unloaded. If a + /// section is loaded, then the load address can be resolved. + /// + /// @return + /// The valid load virtual address, or LLDB_INVALID_ADDRESS if + /// the address is currently not loaded. + //------------------------------------------------------------------ + lldb::addr_t + GetLoadAddress (Process *process) const; + + //------------------------------------------------------------------ + /// Get the section relative offset value. + /// + /// @return + /// The current offset, or LLDB_INVALID_ADDRESS if this address + /// doesn't contain a valid offset. + //------------------------------------------------------------------ + lldb::addr_t + GetOffset () const; + + //------------------------------------------------------------------ + /// Check if an address is section offset. + /// + /// When converting a virtual file or load address into a section + /// offset based address, we often need to know if, given a section + /// list, if the address was able to be converted to section offset. + /// This function returns true if the current value contained in + /// this object is section offset based. + /// + /// @return + /// Returns \b true if the address has a valid section and + /// offset, \b false otherwise. + //------------------------------------------------------------------ + bool + IsSectionOffset() const; + + //------------------------------------------------------------------ + /// Check if the object state is valid. + /// + /// A valid Address object contains either a section pointer and + /// and offset (for section offset based addresses), or just a valid + /// offset (for absolute addresses that have no section). + /// + /// @return + /// Returns \b true if the the offset is valid, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + IsValid() const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Resolve a file virtual address using a section list. + /// + /// Given a list of sections, attempt to resolve \a addr as a + /// an offset into one of the file sections. + /// + /// @return + /// Returns \b true if \a addr was able to be resolved, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + ResolveAddressUsingFileSections (lldb::addr_t addr, const SectionList *sections); + + bool + IsLinkedAddress () const; + + void + ResolveLinkedAddress (); + + //------------------------------------------------------------------ + /// Get accessor for the module for this address. + /// + /// @return + /// Returns the Module pointer that this address is an offset + /// in, or NULL if this address doesn't belong in a module, or + /// isn't resolved yet. + //------------------------------------------------------------------ + Module * + GetModule () const; + + //------------------------------------------------------------------ + /// Get const accessor for the section. + /// + /// @return + /// Returns the const lldb::Section pointer that this address is an + /// offset in, or NULL if this address is absolute. + //------------------------------------------------------------------ + const Section* + GetSection() const; + + //------------------------------------------------------------------ + /// Set accessor for the offset. + /// + /// @param[in] offset + /// A new offset value for this object. + /// + /// @return + /// Returns \b true if the offset changed, \b false otherwise. + //------------------------------------------------------------------ + bool + SetOffset (lldb::addr_t offset); + + //------------------------------------------------------------------ + /// Set accessor for the section. + /// + /// @param[in] section + /// A new lldb::Section pointer to use as the section base. Can + /// be NULL for absolute addresses that are not relative to + /// any section. + //------------------------------------------------------------------ + void + SetSection (const Section* section); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void + CalculateSymbolContext (SymbolContext *sc); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + void + DumpSymbolContext (Stream *s); + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + const Section* m_section; ///< The section for the address, can be NULL. + lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value. +}; + +//bool operator< (const Address& lhs, const Address& rhs); +//bool operator<= (const Address& lhs, const Address& rhs); +//bool operator> (const Address& lhs, const Address& rhs); +//bool operator>= (const Address& lhs, const Address& rhs); +bool operator== (const Address& lhs, const Address& rhs); +bool operator!= (const Address& lhs, const Address& rhs); + +//Stream& operator << (Stream& strm, const Address& so_addr); + +} // namespace lldb_private + +#endif // liblldb_Address_h_ diff --git a/lldb/include/lldb/Core/AddressRange.h b/lldb/include/lldb/Core/AddressRange.h new file mode 100644 index 00000000000..2d890327150 --- /dev/null +++ b/lldb/include/lldb/Core/AddressRange.h @@ -0,0 +1,280 @@ +//===-- AddressRange.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_AddressRange_h_ +#define liblldb_AddressRange_h_ + +#include "lldb/Core/Address.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class AddressRange AddressRange.h "lldb/Core/AddressRange.h" +/// @brief A section + offset based address range class. +//---------------------------------------------------------------------- +class AddressRange +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize with a invalid section (NULL), an invalid + /// offset (LLDB_INVALID_ADDRESS), and zero byte size. + //------------------------------------------------------------------ + AddressRange (); + + //------------------------------------------------------------------ + /// Construct with a section pointer, offset, and byte_size. + /// + /// Initialize the address with the supplied \a section, \a + /// offset and \a byte_size. + /// + /// @param[in] section + /// A section pointer to a valid lldb::Section, or NULL if the + /// address doesn't have a section or will get resolved later. + /// + /// @param[in] offset + /// The offset in bytes into \a section. + /// + /// @param[in] byte_size + /// The size in bytes of the address range. + //------------------------------------------------------------------ + AddressRange (const Section* section, lldb::addr_t offset, lldb::addr_t byte_size); + + //------------------------------------------------------------------ + /// Construct with a virtual address, section list and byte size. + /// + /// Initialize and resolve the address with the supplied virtual + /// address \a file_addr, and byte size \a byte_size. + /// + /// @param[in] file_addr + /// A virtual address. + /// + /// @param[in] byte_size + /// The size in bytes of the address range. + /// + /// @param[in] section_list + /// A list of sections, one of which may contain the \a vaddr. + //------------------------------------------------------------------ + AddressRange (lldb::addr_t file_addr, lldb::addr_t byte_size, const SectionList *section_list = NULL); + + //------------------------------------------------------------------ + /// Construct with a Address object address and byte size. + /// + /// Initialize by copying the section offset address in \a so_addr, + /// and setting the byte size to \a byte_size. + /// + /// @param[in] so_addr + /// A section offset address object. + /// + /// @param[in] byte_size + /// The size in bytes of the address range. + //------------------------------------------------------------------ + AddressRange (const Address& so_addr, lldb::addr_t byte_size); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //------------------------------------------------------------------ + ~AddressRange (); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the section to an invalid value (NULL), an invalid offset + /// (LLDB_INVALID_ADDRESS) and a zero byte size. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Check if a section offset address is contained in this range. + /// + /// @param[in] so_addr + /// A section offset address object reference. + /// + /// @return + /// Returns \b true if \a so_addr is contained in this range, + /// \b false otherwise. + //------------------------------------------------------------------ +// bool +// Contains (const Address &so_addr) const; + + //------------------------------------------------------------------ + /// Check if a section offset address is contained in this range. + /// + /// @param[in] so_addr_ptr + /// A section offset address object pointer. + /// + /// @return + /// Returns \b true if \a so_addr is contained in this range, + /// \b false otherwise. + //------------------------------------------------------------------ +// bool +// Contains (const Address *so_addr_ptr) const; + + //------------------------------------------------------------------ + /// Check if a section offset \a so_addr when represented as a file + /// address is contained within this object's file address range. + /// + /// @param[in] so_addr + /// A section offset address object reference. + /// + /// @return + /// Returns \b true if both \a this and \a so_addr have + /// resolvable file address values and \a so_addr is contained + /// in the address range, \b false otherwise. + //------------------------------------------------------------------ + bool + ContainsFileAddress (const Address &so_addr) const; + + //------------------------------------------------------------------ + /// Check if the resolved file address \a file_addr is contained + /// within this object's file address range. + /// + /// @param[in] so_addr + /// A section offset address object reference. + /// + /// @return + /// Returns \b true if both \a this has a resolvable file + /// address value and \a so_addr is contained in the address + /// range, \b false otherwise. + //------------------------------------------------------------------ + bool + ContainsFileAddress (lldb::addr_t file_addr) const; + + //------------------------------------------------------------------ + /// Check if a section offset \a so_addr when represented as a load + /// address is contained within this object's load address range. + /// + /// @param[in] so_addr + /// A section offset address object reference. + /// + /// @return + /// Returns \b true if both \a this and \a so_addr have + /// resolvable load address values and \a so_addr is contained + /// in the address range, \b false otherwise. + //------------------------------------------------------------------ + bool + ContainsLoadAddress (const Address &so_addr, Process *process) const; + + //------------------------------------------------------------------ + /// Check if the resolved load address \a load_addr is contained + /// within this object's load address range. + /// + /// @param[in] so_addr + /// A section offset address object reference. + /// + /// @return + /// Returns \b true if both \a this has a resolvable load + /// address value and \a so_addr is contained in the address + /// range, \b false otherwise. + //------------------------------------------------------------------ + bool + ContainsLoadAddress (lldb::addr_t load_addr, Process *process) const; + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. There are many ways to display a section + /// offset based address range, and \a style lets the user choose + /// how the base address gets displayed. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] style + /// The display style for the address. + /// + /// @return + /// Returns \b true if the address was able to be displayed. + /// File and load addresses may be unresolved and it may not be + /// possible to display a valid value, \b false will be returned + /// in such cases. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + bool + Dump (Stream *s, Process *process, Address::DumpStyle style, Address::DumpStyle fallback_style = Address::DumpStyleInvalid) const; + + //------------------------------------------------------------------ + /// Dump a debug description of this object to a Stream. + /// + /// Dump a debug description of the contents of this object to the + /// supplied stream \a s. + /// + /// The debug description contains verbose internal state such + /// and pointer values, reference counts, etc. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + DumpDebug (Stream *s) const; + + //------------------------------------------------------------------ + /// Get accessor for the base address of the range. + /// + /// @return + /// A reference to the base address object. + //------------------------------------------------------------------ + Address & + GetBaseAddress(); + + //------------------------------------------------------------------ + /// Get const accessor for the base address of the range. + /// + /// @return + /// A const reference to the base address object. + //------------------------------------------------------------------ + const Address & + GetBaseAddress() const; + + //------------------------------------------------------------------ + /// Get accessor for the byte size of this range. + /// + /// @return + /// The size in bytes of this address range. + //------------------------------------------------------------------ + lldb::addr_t + GetByteSize () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Set accessor for the byte size of this range. + /// + /// @param[in] byte_size + /// The new size in bytes of this address range. + //------------------------------------------------------------------ + void + SetByteSize (lldb::addr_t byte_size); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Address m_base_addr; ///< The section offset base address of this range. + lldb::addr_t m_byte_size; ///< The size in bytes of this address range. +}; + +//bool operator== (const AddressRange& lhs, const AddressRange& rhs); + +} // namespace lldb_private + +#endif // liblldb_AddressRange_h_ diff --git a/lldb/include/lldb/Core/AddressResolver.h b/lldb/include/lldb/Core/AddressResolver.h new file mode 100644 index 00000000000..3690e7267f7 --- /dev/null +++ b/lldb/include/lldb/Core/AddressResolver.h @@ -0,0 +1,90 @@ +//===-- AddressResolver.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_AddressResolver_h_ +#define liblldb_AddressResolver_h_ + +#include <vector> + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/ConstString.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class AddressResolver AddressResolver.h "lldb/Core/AddressResolver.h" +/// @brief This class works with SearchFilter to resolve function names and +/// source file locations to their concrete addresses. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// The AddressResolver is a Searcher. In that protocol, +/// the SearchFilter asks the question "At what depth of the symbol context +/// descent do you want your callback to get called?" of the filter. The resolver +/// answers this question (in the GetDepth method) and provides the resolution callback. +//---------------------------------------------------------------------- + +class AddressResolver : + public Searcher +{ +public: + + typedef enum + { + Exact, + Regexp, + Glob + } MatchType; + + + AddressResolver (); + + virtual + ~AddressResolver (); + + virtual void + ResolveAddress (SearchFilter &filter); + + virtual void + ResolveAddressInModules (SearchFilter &filter, + ModuleList &modules); + + virtual void + GetDescription (Stream *s) = 0; + + std::vector<AddressRange> & + GetAddressRanges (); + + size_t + GetNumberOfAddresses (); + + AddressRange & + GetAddressRangeAtIndex (size_t idx); + +protected: + + std::vector<AddressRange> m_address_ranges; + +private: + DISALLOW_COPY_AND_ASSIGN(AddressResolver); +}; + +} // namespace lldb_private + +#endif // liblldb_AddressResolver_h_ diff --git a/lldb/include/lldb/Core/AddressResolverFileLine.h b/lldb/include/lldb/Core/AddressResolverFileLine.h new file mode 100644 index 00000000000..ddeb0e0301d --- /dev/null +++ b/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -0,0 +1,59 @@ +//===-- AddressResolverFileLine.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_AddressResolverFileLine_h_ +#define liblldb_AddressResolverFileLine_h_ + +// Project includes +#include "lldb/Core/AddressResolver.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class AddressResolverFileLine AddressResolverFileLine.h "lldb/Core/AddressResolverFileLine.h" +/// @brief This class finds address for source file and line. Optionally, it will look for inlined +/// instances of the file and line specification. +//---------------------------------------------------------------------- + +class AddressResolverFileLine : + public AddressResolver +{ +public: + + AddressResolverFileLine (const FileSpec &resolver, + uint32_t line_no, + bool check_inlines); + + virtual + ~AddressResolverFileLine (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing); + + virtual Searcher::Depth + GetDepth (); + + virtual void + GetDescription (Stream *s); + +protected: + FileSpec m_file_spec; // This is the file spec we are looking for. + uint32_t m_line_number; // This is the line number that we are looking for. + bool m_inlines; // This determines whether the resolver looks for inlined functions or not. + +private: + DISALLOW_COPY_AND_ASSIGN(AddressResolverFileLine); +}; + +} // namespace lldb_private + +#endif // liblldb_AddressResolverFileLine_h_ diff --git a/lldb/include/lldb/Core/AddressResolverName.h b/lldb/include/lldb/Core/AddressResolverName.h new file mode 100644 index 00000000000..4ab352939ea --- /dev/null +++ b/lldb/include/lldb/Core/AddressResolverName.h @@ -0,0 +1,67 @@ +//===-- AddressResolverName.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_AddressResolverName_h_ +#define liblldb_AddressResolverName_h_ + +// Project includes + +#include "lldb/Core/AddressResolver.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class AddressResolverName AddressResolverName.h "lldb/Core/AddressResolverName.h" +/// @brief This class finds addresses for a given function name, either by exact match +/// or by regular expression. +//---------------------------------------------------------------------- + +class AddressResolverName: + public AddressResolver +{ +public: + + AddressResolverName (const char *func_name, + AddressResolver::MatchType type = Exact); + + // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. + AddressResolverName (RegularExpression &func_regex); + + AddressResolverName (const char *class_name, + const char *method, + AddressResolver::MatchType type); + + virtual + ~AddressResolverName (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing); + + virtual Searcher::Depth + GetDepth (); + + virtual void + GetDescription (Stream *s); + +protected: + ConstString m_func_name; + ConstString m_class_name; // FIXME: Not used yet. The idea would be to stop on methods of this class. + RegularExpression m_regex; + AddressResolver::MatchType m_match_type; + +private: + DISALLOW_COPY_AND_ASSIGN(AddressResolverName); +}; + +} // namespace lldb_private + +#endif // liblldb_AddressResolverName_h_ diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h new file mode 100644 index 00000000000..71b63f6b5b7 --- /dev/null +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -0,0 +1,326 @@ +//===-- ArchSpec.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ArchSpec_h_ +#define liblldb_ArchSpec_h_ + +#if defined(__cplusplus) + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ArchSpec ArchSpec.h "lldb/Core/ArchSpec.h" +/// @brief An architecture specification class. +/// +/// A class designed to be created from a cpu type and subtype, or a +/// string representation. Keeping all of the conversions of strings +/// to architecture enumeration values confined to this class allows +/// new architecture support to be added easily. +//---------------------------------------------------------------------- +class ArchSpec +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Default constructor that initializes the object with invalid + /// cpu type and subtype values. + //------------------------------------------------------------------ + ArchSpec (); + + //------------------------------------------------------------------ + /// Constructor with cpu type and subtype. + /// + /// Constructor that initializes the object with supplied cpu and + /// subtypes. + //------------------------------------------------------------------ + ArchSpec (uint32_t cpu, uint32_t sub); + + //------------------------------------------------------------------ + /// Construct with architecture name. + /// + /// Constructor that initializes the object with supplied + /// architecture name. There are also predefined values in + /// Defines.h: + /// @li \c LLDB_ARCH_DEFAULT + /// The arch the current system defaults to when a program is + /// launched without any extra attributes or settings. + /// + /// @li \c LLDB_ARCH_DEFAULT_32BIT + /// The 32 bit arch the current system defaults to (if any) + /// + /// @li \c LLDB_ARCH_DEFAULT_32BIT + /// The 64 bit arch the current system defaults to (if any) + //------------------------------------------------------------------ + ArchSpec (const char *arch_name); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //------------------------------------------------------------------ + virtual + ~ArchSpec (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// @param[in] rhs another ArchSpec object to copy. + /// + /// @return a const reference to this object + //------------------------------------------------------------------ + const ArchSpec& + operator= (const ArchSpec& rhs); + + //------------------------------------------------------------------ + /// Get a string representation of the contained architecture. + /// + /// Gets a C string representation of the current architecture. + /// If the returned string is a valid architecture name, the string + /// came from a constant string values that do not need to be freed. + /// If the returned string uses the "N.M" format, the string comes + /// from a static buffer that should be copied. + /// + /// @return a NULL terminated C string that does not need to be + /// freed. + //------------------------------------------------------------------ + const char * + AsCString () const; + + //------------------------------------------------------------------ + /// Returns a string representation of the supplied architecture. + /// + /// Class function to get a C string representation given a CPU type + /// and subtype. + /// + /// @param[in] cpu The cpu type of the architecture. + /// @param[in] subtype The cpu subtype of the architecture. + /// + /// @return a NULL terminated C string that does not need to be + /// freed. + //------------------------------------------------------------------ + static const char * + AsCString (uint32_t cpu, uint32_t subtype); + + //------------------------------------------------------------------ + /// Clears the object state. + /// + /// Clears the object state back to a default invalid state. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Returns the size in bytes of an address of the current + /// architecture. + /// + /// @return The byte size of an address of the current architecture. + //------------------------------------------------------------------ + uint32_t + GetAddressByteSize () const; + + //------------------------------------------------------------------ + /// CPU subtype get accessor. + /// + /// @return The current value of the CPU subtype. + //------------------------------------------------------------------ + uint32_t + GetCPUSubtype () const; + + //------------------------------------------------------------------ + /// CPU type get accessor. + /// + /// @return The current value of the CPU type. + //------------------------------------------------------------------ + uint32_t + GetCPUType () const; + + //------------------------------------------------------------------ + /// Feature flags get accessor. + /// + /// @return The current value of the CPU feature flags. + //------------------------------------------------------------------ + uint32_t + GetFeatureFlags () const; + + //------------------------------------------------------------------ + /// Get register names of the current architecture. + /// + /// Get register names of the current architecture given + /// a register number, and a flavor for that register number. + /// There are many different register numbering schemes used + /// on a host: + /// @li \c eRegisterKindGCC - gcc compiler register numbering + /// @li \c eRegisterKindDWARF - DWARF register numbering + /// + /// @param[in] reg_num The register number to decode. + /// @param[in] flavor The flavor of the \a reg_num. + /// + /// @return the name of the register as a NULL terminated C string, + /// or /c NULL if the \a reg_num is invalid for \a flavor. + /// String values that are returned do not need to be freed. + //------------------------------------------------------------------ + const char * + GetRegisterName (uint32_t reg_num, uint32_t flavor) const; + + //------------------------------------------------------------------ + /// Get register names for a specified architecture. + /// + /// Get register names of the specified architecture given + /// a register number, and a flavor for that register number. + /// There are many different register numbering schemes used + /// on a host: + /// + /// @li compiler register numbers (@see eRegisterKindGCC) + /// @li DWARF register numbers (@see eRegisterKindDWARF) + /// + /// @param[in] cpu The cpu type of the architecture specific + /// register + /// @param[in] subtype The cpu subtype of the architecture specific + /// register + /// @param[in] reg_num The register number to decode. + /// @param[in] flavor The flavor of the \a reg_num. + /// + /// @return the name of the register as a NULL terminated C string, + /// or /c NULL if the \a reg_num is invalid for \a flavor. + /// String values that are returned do not need to be freed. + //------------------------------------------------------------------ + static const char * + GetRegisterName (uint32_t cpu, uint32_t subtype, uint32_t reg_num, uint32_t flavor); + + //------------------------------------------------------------------ + /// Test if the contained architecture is valid. + /// + /// @return true if the current architecture is valid, false + /// otherwise. + //------------------------------------------------------------------ + bool + IsValid () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t + MemorySize() const; + + //------------------------------------------------------------------ + /// Change the CPU type and subtype given an architecture name. + /// + /// The architecture name supplied can also by one of the generic + /// system default values: + /// @li \c LLDB_ARCH_DEFAULT - The arch the current system defaults + /// to when a program is launched without any extra + /// attributes or settings. + /// @li \c LLDB_ARCH_DEFAULT_32BIT - The default host architecture + /// for 32 bit (if any). + /// @li \c LLDB_ARCH_DEFAULT_64BIT - The default host architecture + /// for 64 bit (if any). + /// + /// @param[in] arch_name The name of an architecture. + /// + /// @return true if \a arch_name was successfully transformed into + /// a valid cpu type and subtype. + //------------------------------------------------------------------ + bool + SetArch (const char *arch_name); + + bool + SetArchFromTargetTriple (const char *arch_name); + //------------------------------------------------------------------ + /// Change the CPU type and subtype given new values of the cpu + /// type and subtype. + /// + /// @param[in] cpu The new CPU type + /// @param[in] subtype The new CPU subtype + //------------------------------------------------------------------ + void + SetArch (uint32_t cpu, uint32_t subtype); + + //------------------------------------------------------------------ + /// Change the CPU subtype given a new value of the CPU subtype. + /// + /// @param[in] subtype The new CPU subtype. + //------------------------------------------------------------------ + void + SetCPUSubtype (uint32_t subtype); + + //------------------------------------------------------------------ + /// Change the CPU type given a new value of the CPU type. + /// + /// @param[in] cpu The new CPU type. + //------------------------------------------------------------------ + void + SetCPUType (uint32_t cpu); + + //------------------------------------------------------------------ + /// Returns the default endianness of the architecture. + /// + /// @return The endian enumeration for the default endianness of + /// the architecture. + //------------------------------------------------------------------ + lldb::ByteOrder + GetDefaultEndian () const; +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + uint32_t m_cpu; ///< The cpu type of the architecture + uint32_t m_sub; ///< The cpu subtype of the architecture +}; + + +//------------------------------------------------------------------ +/// @fn bool operator== (const ArchSpec& lhs, const ArchSpec& rhs) +/// @brief Equal to operator. +/// +/// Tests two ArchSpec objects to see if they are equal. +/// +/// @param[in] lhs The Left Hand Side ArchSpec object to compare. +/// @param[in] rhs The Left Hand Side ArchSpec object to compare. +/// +/// @return true if \a lhs is equal to \a rhs +//------------------------------------------------------------------ +bool operator==(const ArchSpec& lhs, const ArchSpec& rhs); + +//------------------------------------------------------------------ +/// @fn bool operator!= (const ArchSpec& lhs, const ArchSpec& rhs) +/// @brief Not equal to operator. +/// +/// Tests two ArchSpec objects to see if they are not equal. +/// +/// @param[in] lhs The Left Hand Side ArchSpec object to compare. +/// @param[in] rhs The Left Hand Side ArchSpec object to compare. +/// +/// @return true if \a lhs is not equal to \a rhs +//------------------------------------------------------------------ +bool operator!=(const ArchSpec& lhs, const ArchSpec& rhs); + +//------------------------------------------------------------------ +/// @fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs) +/// @brief Less than operator. +/// +/// Tests two ArchSpec objects to see if \a lhs is less than \a +/// rhs. +/// +/// @param[in] lhs The Left Hand Side ArchSpec object to compare. +/// @param[in] rhs The Left Hand Side ArchSpec object to compare. +/// +/// @return true if \a lhs is less than \a rhs +//------------------------------------------------------------------ +bool operator< (const ArchSpec& lhs, const ArchSpec& rhs); + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef liblldb_ArchSpec_h_ diff --git a/lldb/include/lldb/Core/Args.h b/lldb/include/lldb/Core/Args.h new file mode 100644 index 00000000000..79cb7599def --- /dev/null +++ b/lldb/include/lldb/Core/Args.h @@ -0,0 +1,368 @@ +//===-- Args.h --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Command_h_ +#define liblldb_Command_h_ + +// C Includes +#include <getopt.h> + +// C++ Includes +#include <list> +#include <string> +#include <vector> +#include <utility> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Error.h" +#include "lldb/lldb-types.h" + +namespace lldb_private { + +typedef std::pair<std::string, std::string> OptionArgPair; +typedef std::vector<OptionArgPair> OptionArgVector; +typedef lldb::SharedPtr<OptionArgVector>::Type OptionArgVectorSP; + +struct OptionArgElement +{ + OptionArgElement (int defs_index, int pos, int arg_pos) : + opt_defs_index(defs_index), + opt_pos (pos), + opt_arg_pos (arg_pos) + { + } + + int opt_defs_index; + int opt_pos; + int opt_arg_pos; +}; + +typedef std::vector<OptionArgElement> OptionElementVector; + +//---------------------------------------------------------------------- +/// @class Args Args.h "lldb/Core/Args.h" +/// @brief A command line argument class. +/// +/// The Args class is designed to be fed a command line. The +/// command line is copied into an internal buffer and then split up +/// into arguments. Arguments are space delimited if there are no quotes +/// (single, double, or backtick quotes) surrounding the argument. Spaces +/// can be escaped using a \ character to avoid having to surround an +/// argument that contains a space with quotes. +//---------------------------------------------------------------------- +class Args +{ +public: + + //------------------------------------------------------------------ + /// Construct with an option command string. + /// + /// @param[in] command + /// A NULL terminated command that will be copied and split up + /// into arguments. + /// + /// @see Args::SetCommandString(const char *) + //------------------------------------------------------------------ + Args (const char *command = NULL); + + Args (const char *command, size_t len); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Args(); + + //------------------------------------------------------------------ + /// Dump all arguments to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump all arguments in the argument + /// vector. + //------------------------------------------------------------------ + void + Dump (Stream *s); + + //------------------------------------------------------------------ + /// Sets the command string contained by this object. + /// + /// The command string will be copied and split up into arguments + /// that can be accessed via the accessor functions. + /// + /// @param[in] command + /// A NULL terminated command that will be copied and split up + /// into arguments. + /// + /// @see Args::GetArgumentCount() const + /// @see Args::GetArgumentAtIndex (size_t) const + /// @see Args::GetArgumentVector () + /// @see Args::Shift () + /// @see Args::Unshift (const char *) + //------------------------------------------------------------------ + void + SetCommandString (const char *command); + + void + SetCommandString (const char *command, size_t len); + + bool + GetCommandString (std::string &command); + + //------------------------------------------------------------------ + /// Gets the number of arguments left in this command object. + /// + /// @return + /// The number or arguments in this object. + //------------------------------------------------------------------ + size_t + GetArgumentCount () const; + + //------------------------------------------------------------------ + /// Gets the NULL terminated C string argument pointer for the + /// argument at index \a idx. + /// + /// @return + /// The NULL terminated C string argument pointer if \a idx is a + /// valid argument index, NULL otherwise. + //------------------------------------------------------------------ + const char * + GetArgumentAtIndex (size_t idx) const; + + char + GetArgumentQuoteCharAtIndex (size_t idx) const; + + //------------------------------------------------------------------ + /// Gets the argument vector. + /// + /// The value returned by this function can be used by any function + /// that takes and vector. The return value is just like \a argv + /// in the standard C entry point function: + /// \code + /// int main (int argc, const char **argv); + /// \endcode + /// + /// @return + /// An array of NULL terminated C string argument pointers that + /// also has a terminating NULL C string pointer + //------------------------------------------------------------------ + char ** + GetArgumentVector (); + + //------------------------------------------------------------------ + /// Gets the argument vector. + /// + /// The value returned by this function can be used by any function + /// that takes and vector. The return value is just like \a argv + /// in the standard C entry point function: + /// \code + /// int main (int argc, const char **argv); + /// \endcode + /// + /// @return + /// An array of NULL terminate C string argument pointers that + /// also has a terminating NULL C string pointer + //------------------------------------------------------------------ + const char ** + GetConstArgumentVector () const; + + + //------------------------------------------------------------------ + /// Appends a new argument to the end of the list argument list. + /// + /// @param[in] arg_cstr + /// The new argument as a NULL terminated C string. + /// + /// @param[in] quote_char + /// If the argument was originally quoted, put in the quote char here. + /// + /// @return + /// The NULL terminated C string of the copy of \a arg_cstr. + //------------------------------------------------------------------ + const char * + AppendArgument (const char *arg_cstr, char quote_char = '\0'); + + void + AppendArguments (const Args &rhs); + //------------------------------------------------------------------ + /// Insert the argument value at index \a idx to \a arg_cstr. + /// + /// @param[in] idx + /// The index of where to insert the argument. + /// + /// @param[in] arg_cstr + /// The new argument as a NULL terminated C string. + /// + /// @param[in] quote_char + /// If the argument was originally quoted, put in the quote char here. + /// + /// @return + /// The NULL terminated C string of the copy of \a arg_cstr. + //------------------------------------------------------------------ + const char * + InsertArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char = '\0'); + + //------------------------------------------------------------------ + /// Replaces the argument value at index \a idx to \a arg_cstr + /// if \a idx is a valid argument index. + /// + /// @param[in] idx + /// The index of the argument that will have its value replaced. + /// + /// @param[in] arg_cstr + /// The new argument as a NULL terminated C string. + /// + /// @param[in] quote_char + /// If the argument was originally quoted, put in the quote char here. + /// + /// @return + /// The NULL terminated C string of the copy of \a arg_cstr if + /// \a idx was a valid index, NULL otherwise. + //------------------------------------------------------------------ + const char * + ReplaceArgumentAtIndex (size_t idx, const char *arg_cstr, char quote_char = '\0'); + + //------------------------------------------------------------------ + /// Deletes the argument value at index + /// if \a idx is a valid argument index. + /// + /// @param[in] idx + /// The index of the argument that will have its value replaced. + /// + //------------------------------------------------------------------ + void + DeleteArgumentAtIndex (size_t idx); + + //------------------------------------------------------------------ + /// Sets the argument vector value, optionally copying all + /// arguments into an internal buffer. + /// + /// Sets the arguments to match those found in \a argv. All argument + /// strings will be copied into an internal buffers. + // + // FIXME: Handle the quote character somehow. + //------------------------------------------------------------------ + void + SetArguments (int argc, const char **argv); + + //------------------------------------------------------------------ + /// Shifts the first argument C string value of the array off the + /// argument array. + /// + /// The string value will be freed, so a copy of the string should + /// be made by calling Args::GetArgumentAtIndex (size_t) const + /// first and copying the returned value before calling + /// Args::Shift(). + /// + /// @see Args::GetArgumentAtIndex (size_t) const + //------------------------------------------------------------------ + void + Shift (); + + //------------------------------------------------------------------ + /// Inserts a class owned copy of \a arg_cstr at the beginning of + /// the argument vector. + /// + /// A copy \a arg_cstr will be made. + /// + /// @param[in] arg_cstr + /// The argument to push on the front the the argument stack. + /// + /// @param[in] quote_char + /// If the argument was originally quoted, put in the quote char here. + /// + /// @return + /// A pointer to the copy of \a arg_cstr that was made. + //------------------------------------------------------------------ + const char * + Unshift (const char *arg_cstr, char quote_char = '\0'); + + //------------------------------------------------------------------ + /// Parse the arguments in the contained arguments. + /// + /// The arguments that are consumed by the argument parsing process + /// will be removed from the argument vector. The arguements that + /// get processed start at the second argument. The first argument + /// is assumed to be the command and will not be touched. + /// + /// @see class Options + //------------------------------------------------------------------ + Error + ParseOptions (Options &options); + + // The following works almost identically to ParseOptions, except that no option is required to have arguments, + // and it builds up the option_arg_vector as it parses the options. + + void + ParseAliasOptions (Options &options, CommandReturnObject &result, OptionArgVector *option_arg_vector); + + void + ParseArgsForCompletion (Options &options, OptionElementVector &option_element_vector); + + //------------------------------------------------------------------ + // Clear the arguments. + // + // For re-setting or blanking out the list of arguments. + //------------------------------------------------------------------ + void + Clear (); + + static int32_t + StringToSInt32 (const char *s, int32_t fail_value = 0, int base = 0, bool *success_ptr = NULL); + + static uint32_t + StringToUInt32 (const char *s, uint32_t fail_value = 0, int base = 0, bool *success_ptr = NULL); + + static int64_t + StringToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr = NULL); + + static uint64_t + StringToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = NULL); + + static lldb::addr_t + StringToAddress (const char *s, lldb::addr_t fail_value = LLDB_INVALID_ADDRESS, bool *success_ptr = NULL); + + static bool + StringToBoolean (const char *s, bool fail_value, bool *success_ptr); + + static int32_t + StringToOptionEnum (const char *s, lldb::OptionEnumValueElement *enum_values, int32_t fail_value, bool *success_ptr); + + static lldb::ScriptLanguage + StringToScriptLanguage (const char *s, lldb::ScriptLanguage fail_value, bool *success_ptr); + + static Error + StringToFormat (const char *s, lldb::Format &format); + + // This one isn't really relevant to Arguments per se, but we're using the Args as a + // general strings container, so... + void + LongestCommonPrefix (std::string &common_prefix); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from Args can see and modify these + //------------------------------------------------------------------ + typedef std::list<std::string> arg_sstr_collection; + typedef std::vector<const char *> arg_cstr_collection; + typedef std::vector<char> arg_quote_char_collection; + arg_sstr_collection m_args; + arg_cstr_collection m_argv; ///< The current argument vector. + arg_quote_char_collection m_args_quote_char; + + void + UpdateArgsAfterOptionParsing (); + + void + UpdateArgvFromArgs (); +}; + +} // namespace lldb_private + +#endif // liblldb_Command_h_ diff --git a/lldb/include/lldb/Core/Baton.h b/lldb/include/lldb/Core/Baton.h new file mode 100644 index 00000000000..7b9bd87d8d0 --- /dev/null +++ b/lldb/include/lldb/Core/Baton.h @@ -0,0 +1,62 @@ +//===-- Baton.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Baton_h_ +#define lldb_Baton_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-include.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Baton Baton.h "lldb/Core/Baton.h" +/// @brief A class designed to wrap callback batons so they can cleanup +/// any acquired resources +/// +/// This class is designed to be used by any objects that have a +/// callback function that takes a baton where the baton might need to +/// free/delete/close itself. +/// +/// The default behavior is to not free anything. Subclasses can +/// free any needed resources in their destructors. +//---------------------------------------------------------------------- +class Baton +{ +public: + explicit Baton(void *p) : + m_data (p) + { + } + + virtual + ~Baton() + { + // The default destructor for a baton does NOT attempt to clean up + // anything in m_baton + } + + virtual void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + + void *m_data; // Leave baton public for easy access + +private: + //------------------------------------------------------------------ + // For Baton only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Baton); +}; + +} // namespace lldb_private + +#endif // lldb_Baton_h_ diff --git a/lldb/include/lldb/Core/Broadcaster.h b/lldb/include/lldb/Core/Broadcaster.h new file mode 100644 index 00000000000..c010417335d --- /dev/null +++ b/lldb/include/lldb/Core/Broadcaster.h @@ -0,0 +1,194 @@ +//===-- Broadcaster.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Broadcaster_h_ +#define liblldb_Broadcaster_h_ + +// C Includes +// C++ Includes +#include <string> +#include <vector> + + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +//#include "lldb/Core/Flags.h" +#include "lldb/Core/Listener.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" +/// @brief An event broadcasting class. +/// +/// The Broadcaster class is designed to be subclassed by objects that +/// wish to vend events in a multi-threaded environment. Broadcaster +/// objects can each vend 32 events. Each event is represented by a bit +/// in a 32 bit value and these bits can be set: +/// @see Broadcaster::SetEventBits(uint32_t) +/// or cleared: +/// @see Broadcaster::ResetEventBits(uint32_t) +/// When an event gets set the Broadcaster object will notify the +/// Listener object that is listening for the event (if there is one). +/// +/// Subclasses should provide broadcast bit definitions for any events +/// they vend, typically using an enumeration: +/// \code +/// class Foo : public Broadcaster +/// { +/// public: +/// //---------------------------------------------------------- +/// // Broadcaster event bits definitions. +/// //---------------------------------------------------------- +/// enum +/// { +/// eBroadcastBitStateChanged = (1 << 0), +/// eBroadcastBitInterrupt = (1 << 1), +/// eBroadcastBitSTDOUT = (1 << 2), +/// eBroadcastBitSTDERR = (1 << 3) +/// }; +/// \endcode +//---------------------------------------------------------------------- +class Broadcaster +{ +public: + //------------------------------------------------------------------ + /// Construct with a broadcaster with a name. + /// + /// @param[in] name + /// A NULL terminated C string that contains the name of the + /// broadcaster object. + //------------------------------------------------------------------ + Broadcaster (const char *name); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class gets subclassed. + //------------------------------------------------------------------ + virtual + ~Broadcaster(); + + //------------------------------------------------------------------ + /// Broadcast an event which has no associated data. + /// + /// @param[in] event_type + /// The element from the enum defining this broadcaster's events + /// that is being broadcast. + /// + /// @param[in] event_data + /// User event data that will be owned by the lldb::Event that + /// is created internally. + /// + /// @param[in] unique + /// If true, then only add an event of this type if there isn't + /// one already in the queue. + /// + //------------------------------------------------------------------ + void + BroadcastEvent (lldb::EventSP &event_sp); + + void + BroadcastEventIfUnique (lldb::EventSP &event_sp); + + void + BroadcastEvent (uint32_t event_type, EventData *event_data = NULL); + + void + BroadcastEventIfUnique (uint32_t event_type, EventData *event_data = NULL); + + virtual void + AddInitialEventsToListener (Listener *listener, uint32_t requested_events); + + //------------------------------------------------------------------ + /// Listen for any events specified by \a event_mask. + /// + /// Only one listener can listen to each event bit in a given + /// Broadcaster. Once a listener has acquired an event bit, no + /// other broadcaster will have access to it until it is + /// relinquished by the first listener that gets it. The actual + /// event bits that get acquired by \a listener may be different + /// from what is requested in \a event_mask, and to track this the + /// actual event bits that are acquired get returned. + /// + /// @param[in] listener + /// The Listener object that wants to monitor the events that + /// get broadcast by this object. + /// + /// @param[in] event_mask + /// A bit mask that indicates which events the listener is + /// asking to monitor. + /// + /// @return + /// The actual event bits that were acquired by \a listener. + //------------------------------------------------------------------ + uint32_t + AddListener (Listener* listener, uint32_t event_mask); + + //------------------------------------------------------------------ + /// Get the NULL terminated C string name of this Broadcaster + /// object. + /// + /// @return + /// The NULL terminated C string name of this Broadcaster. + //------------------------------------------------------------------ + const ConstString & + GetBroadcasterName (); + + bool + EventTypeHasListeners (uint32_t event_type); + + //------------------------------------------------------------------ + /// Removes a Listener from this broadcasters list and frees the + /// event bits specified by \a event_mask that were previously + /// acquired by \a listener (assuming \a listener was listening to + /// this object) for other listener objects to use. + /// + /// @param[in] listener + /// A Listener object that previously called AddListener. + /// + /// @param[in] event_mask + /// The event bits \a listener wishes to relinquish. + /// + /// @return + /// \b True if the listener was listening to this broadcaster + /// and was removed, \b false otherwise. + /// + /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) + //------------------------------------------------------------------ + bool + RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX); + + +protected: + + void + PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); + + //------------------------------------------------------------------ + // Classes that inherit from Broadcaster can see and modify these + //------------------------------------------------------------------ + typedef std::vector< std::pair<Listener*,uint32_t> > collection; + // Prefix the name of our member variables with "m_broadcaster_" + // since this is a class that gets subclassed. + const ConstString m_broadcaster_name; ///< The name of this broadcaster object. + collection m_broadcaster_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. + Mutex m_broadcaster_listeners_mutex; ///< A mutex that protects \a m_broadcaster_listeners. + +private: + //------------------------------------------------------------------ + // For Broadcaster only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Broadcaster); +}; + +} // namespace lldb_private + +#endif // liblldb_Broadcaster_h_ diff --git a/lldb/include/lldb/Core/ClangForward.h b/lldb/include/lldb/Core/ClangForward.h new file mode 100644 index 00000000000..3f4a2aee832 --- /dev/null +++ b/lldb/include/lldb/Core/ClangForward.h @@ -0,0 +1,103 @@ +//===-- ClangForward.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangForward_h_ +#define liblldb_ClangForward_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#if defined(__cplusplus) + +namespace clang +{ + namespace Builtin + { + class Context; + } + + class ASTContext; + class AddrLabelExpr; + class BinaryOperator; + class CodeGenerator; + class CompilerInstance; + class CXXBaseSpecifier; + class CXXBoolLiteralExpr; + class CXXFunctionalCastExpr; + class CXXNamedCastExpr; + class CXXRecordDecl; + class CXXThisExpr; + class CharacterLiteral; + class CompoundAssignOperator; + class Decl; + class DeclaratorDecl; + class DeclContext; + class DeclRefExpr; + class DeclStmt; + class Diagnostic; + class EnumDecl; + class Expr; + class ExtVectorElementExpr; + class FieldDecl; + class FloatingLiteral; + class FunctionDecl; + class GotoStmt; + class IdentifierTable; + class IntegerLiteral; + class LabelStmt; + class LangOptions; + class MemberExpr; + class NamedDecl; + class NamespaceDecl; + class NonTypeTemplateParmDecl; + class ObjCEncodeExpr; + class ObjCImplicitSetterGetterRefExpr; + class ObjCInterfaceDecl; + class ObjCIvarRefExpr; + class ObjCMessageExpr; + class ObjCMethodDecl; + class ObjCPropertyRefExpr; + class ObjCProtocolDecl; + class ObjCProtocolExpr; + class ObjCSelectorExpr; + class ObjCSuperExpr; + class ParenExpr; + class ParmVarDecl; + class PredefinedExpr; + class QualType; + class QualifiedNameType; + class RecordDecl; + class SelectorTable; + class SizeOfAlignOfExpr; + class SourceLocation; + class SourceManager; + class Stmt; + class StmtIteratorBase; + class StringLiteral; + class TagDecl; + class TargetInfo; + class TargetOptions; + class TemplateArgument; + class TemplateDecl; + class TemplateTemplateParmDecl; + class TemplateTypeParmDecl; + class TextDiagnosticBuffer; + class Type; + class TypedefDecl; + class TypesCompatibleExpr; + class UnaryOperator; + class ValueDecl; + class VarDecl; + struct PrintingPolicy; +} + +#endif // #if defined(__cplusplus) +#endif // liblldb_ClangForward_h_ diff --git a/lldb/include/lldb/Core/Communication.h b/lldb/include/lldb/Core/Communication.h new file mode 100644 index 00000000000..dc8bfba4d92 --- /dev/null +++ b/lldb/include/lldb/Core/Communication.h @@ -0,0 +1,401 @@ +//===-- Communication.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Communication_h_ +#define liblldb_Communication_h_ + +// C Includes +// C++ Includes +#include <string> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Error.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Host/Predicate.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Communication Communication.h "lldb/Core/Communication.h" +/// @brief An abstract communications class. +/// +/// Communication is an class that handles data communication +/// between two data sources. It uses a Connection class to do the +/// real communication. This approach has a couple of advantages: it +/// allows a single instance of this class to be used even though its +/// connection can change. Connections could negotiate for different +/// connections based on abilities like starting with Bluetooth and +/// negotiating up to WiFi if available. It also allows this class to be +/// subclassed by any interfaces that don't want to give bytes but want +/// to validate and give out packets. This can be done by overriding: +/// +/// AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast); +/// +/// Communication inherits from Broadcaster which means it can be +/// used in conjunction with Listener to wait for multiple broadcaster +/// objects and multiple events from each of those objects. +/// Communication defines a set of pre-defined event bits (see +/// enumerations definitions that start with "eBroadcastBit" below). +/// +/// There are two modes in which communications can occur: +/// @li single-threaded +/// @li multi-threaded +/// +/// In single-threaded mode, all reads and writes happen synchronously +/// on the calling thread. +/// +/// In multi-threaded mode, a read thread is spawned that continually +/// reads data and caches any received bytes. To start the read thread +/// clients call: +/// +/// bool Communication::StartReadThread (Error *); +/// +/// If true is returned a read thead has been spawned that will +/// continually execute a call to the pure virtual DoRead function: +/// +/// size_t Communication::ReadFromConnection (void *, size_t, uint32_t); +/// +/// When bytes are received the data gets cached in \a m_bytes and this +/// class will broadcast a \b eBroadcastBitReadThreadGotBytes event. +/// Clients that want packet based communication should override +/// AppendBytesToCache. The subclasses can choose to call the +/// built in AppendBytesToCache with the \a broadcast parameter set to +/// false. This will cause the \b eBroadcastBitReadThreadGotBytes event +/// not get broadcast, and then the subclass can post a \b +/// eBroadcastBitPacketAvailable event when a full packet of data has +/// been received. +/// +/// If the connection is disconnected a \b eBroadcastBitDisconnected +/// event gets broadcast. If the read thread exits a \b +/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients +/// can also post a \b eBroadcastBitReadThreadShouldExit event to this +/// object which will cause the read thread to exit. +//---------------------------------------------------------------------- +class Communication : public Broadcaster +{ +public: + enum { + eBroadcastBitDisconnected = (1 << 0), ///< Sent when the communications connection is lost. + eBroadcastBitReadThreadGotBytes = (1 << 1), ///< Sent by the read thread when bytes become available. + eBroadcastBitReadThreadDidExit = (1 << 2), ///< Sent by the read thread when it exits to inform clients. + eBroadcastBitReadThreadShouldExit = (1 << 3), ///< Sent by clients that need to cancel the read thread. + eBroadcastBitPacketAvailable = (1 << 4), ///< Sent when data received makes a complete packet. + kLoUserBroadcastBit = (1 << 16),///< Subclasses can used bits 31:16 for any needed events. + kHiUserBroadcastBit = (1 << 31), + eAllEventBits = 0xffffffff + }; + + typedef void (*ReadThreadBytesReceived) (void *baton, const void *src, size_t src_len); + + + //------------------------------------------------------------------ + /// Construct the Communication object with the specified name for + /// the Broadcaster that this object inherits from. + /// + /// @param[in] broadcaster_name + /// The name of the broadcaster object. This name should be as + /// complete as possible to uniquely identify this object. The + /// broadcaster name can be updated after the connect function + /// is called. + //------------------------------------------------------------------ + Communication(const char * broadcaster_name); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class gets subclassed. + //------------------------------------------------------------------ + virtual + ~Communication(); + + void + Clear (); + + //------------------------------------------------------------------ + /// Poll for bytes available if the communications supports it. + /// + /// @param[in] timeout_usec + /// A timeout value in micro-seconds, UINT32_MAX for infinite + /// wait. + /// + /// @return + /// \b True if the bytes are, or became available within the + /// timeout period, \b false otherwise. + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus + BytesAvailable (uint32_t timeout_usec, Error *error_ptr); + + //------------------------------------------------------------------ + /// Connect using the current connection by passing \a url to its + /// connect function. + /// string. + /// + /// @param[in] url + /// A string that contains all information needed by the + /// subclass to connect to another client. + /// + /// @return + /// \b True if the connect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Error& Communication::GetError (); + /// @see bool Connection::Connect (const char *url); + //------------------------------------------------------------------ + lldb::ConnectionStatus + Connect (const char *url, Error *error_ptr); + + //------------------------------------------------------------------ + /// Disconnect the communications connection if one is currently + /// connected. + /// + /// @return + /// \b True if the disconnect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Error& Communication::GetError (); + /// @see bool Connection::Disconnect (); + //------------------------------------------------------------------ + lldb::ConnectionStatus + Disconnect (Error *error_ptr = NULL); + + //------------------------------------------------------------------ + /// Check if the connection is valid. + /// + /// @return + /// \b True if this object is currently connected, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + IsConnected () const; + + bool + HasConnection () const; + //------------------------------------------------------------------ + /// Read bytes from the current connection. + /// + /// If no read thread is running, this function call the + /// connection's Connection::BytesAvailable(uint32_t) method to + /// wait for available data, and then call the + /// Connection::Read(void *, size_t) function to get any available + /// bytes if Connection::BytesAvailable(uint32_t) returned true. + /// + /// If a read thread has been started, this function will check for + /// any cached bytes that have already been read and return any + /// currently available bytes. If no bytes are cached, it will wait + /// for the bytes to become available by listening for the \a + /// eBroadcastBitReadThreadGotBytes event. If this function consumes + /// all of the bytes in the cache, it will reset the + /// \a eBroadcastBitReadThreadGotBytes event bit. + /// + /// @param[in] dst + /// A destination buffer that must be at least \a dst_len bytes + /// long. + /// + /// @param[in] dst_len + /// The number of bytes to attempt to read, and also the max + /// number of bytes that can be placed into \a dst. + /// + /// @param[in] timeout_usec + /// A timeout value in micro-seconds. + /// + /// @return + /// The number of bytes actually read. + /// + /// @see bool Connection::BytesAvailable (uint32_t); + /// @see size_t Connection::Read (void *, size_t); + //------------------------------------------------------------------ + size_t + Read (void *dst, + size_t dst_len, + uint32_t timeout_usec, + lldb::ConnectionStatus &status, + Error *error_ptr); + + //------------------------------------------------------------------ + /// The actual write function that attempts to write to the + /// communications protocol. + /// + /// Subclasses must override this function. + /// + /// @param[in] src + /// A source buffer that must be at least \a src_len bytes + /// long. + /// + /// @param[in] src_len + /// The number of bytes to attempt to write, and also the + /// number of bytes are currently available in \a src. + /// + /// @return + /// The number of bytes actually Written. + //------------------------------------------------------------------ + size_t + Write (const void *src, + size_t src_len, + lldb::ConnectionStatus &status, + Error *error_ptr); + + //------------------------------------------------------------------ + /// Sets the connection that it to be used by this class. + /// + /// By making a communication class that uses different connections + /// it allows a single communication interface to negotiate and + /// change its connection without any interruption to the client. + /// It also allows the Communication class to be subclassed for + /// packet based communication. + /// + /// @param[in] connection + /// A connection that this class will own and destroy. + /// + /// @see + /// class Connection + //------------------------------------------------------------------ + void + SetConnection (Connection *connection); + + //------------------------------------------------------------------ + /// Starts a read thread whose sole purpose it to read bytes from + /// the current connection. This function will call connection's + /// read function: + /// + /// size_t Connection::Read (void *, size_t); + /// + /// When bytes are read and cached, this function will call: + /// + /// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast); + /// + /// Subclasses should override this function if they wish to override + /// the default action of caching the bytes and broadcasting a \b + /// eBroadcastBitReadThreadGotBytes event. + /// + /// @return + /// \b True if the read thread was successfully started, \b + /// false otherwise. + /// + /// @see size_t Connection::Read (void *, size_t); + /// @see void Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast); + //------------------------------------------------------------------ + virtual bool + StartReadThread (Error *error_ptr = NULL); + + //------------------------------------------------------------------ + /// Stops the read thread by cancelling it. + /// + /// @return + /// \b True if the read thread was successfully canceled, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool + StopReadThread (Error *error_ptr = NULL); + + //------------------------------------------------------------------ + /// Checks if there is a currently running read thread. + /// + /// @return + /// \b True if the read thread is running, \b false otherwise. + //------------------------------------------------------------------ + bool + ReadThreadIsRunning (); + + //------------------------------------------------------------------ + /// The static read thread function. This function will call + /// the "DoRead" function continuously and wait for data to become + /// avaialble. When data is received it will append the available + /// data to the internal cache and broadcast a + /// \b eBroadcastBitReadThreadGotBytes event. + /// + /// @param[in] comm_ptr + /// A pointer to an instance of this class. + /// + /// @return + /// \b NULL. + /// + /// @see void Communication::ReadThreadGotBytes (const uint8_t *, size_t); + //------------------------------------------------------------------ + static lldb::thread_result_t + ReadThread (lldb::thread_arg_t comm_ptr); + + void + SetReadThreadBytesReceivedCallback (ReadThreadBytesReceived callback, + void *callback_baton); + +private: + //------------------------------------------------------------------ + // For Communication only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Communication); + +protected: + std::auto_ptr<Connection> m_connection_ap; ///< The connection that is current in use by this communications class. + lldb::thread_t m_read_thread; ///< The read thread handle in case we need to cancel the thread. + bool m_read_thread_enabled; + std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. + Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. + ReadThreadBytesReceived m_callback; + void *m_callback_baton; + + size_t + ReadFromConnection (void *dst, + size_t dst_len, + lldb::ConnectionStatus &status, + Error *error_ptr); + //------------------------------------------------------------------ + /// Append new bytes that get read from the read thread into the + /// internal object byte cache. This will cause a \b + /// eBroadcastBitReadThreadGotBytes event to be broadcast if \a + /// broadcast is true. + /// + /// Subclasses can override this function in order to inspect the + /// received data and check if a packet is available. + /// + /// Subclasses can also still call this function from the + /// overridden method to allow the caching to correctly happen and + /// suppress the broadcasting of the \a eBroadcastBitReadThreadGotBytes + /// event by setting \a broadcast to false. + /// + /// @param[in] src + /// A source buffer that must be at least \a src_len bytes + /// long. + /// + /// @param[in] src_len + /// The number of bytes to append to the cache. + //------------------------------------------------------------------ + virtual void + AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast); + + //------------------------------------------------------------------ + /// Get any available bytes from our data cache. If this call + /// empties the data cache, the \b eBroadcastBitReadThreadGotBytes event + /// will be reset to signify no more bytes are available. + /// + /// @param[in] dst + /// A destination buffer that must be at least \a dst_len bytes + /// long. + /// + /// @param[in] dst_len + /// The number of bytes to attempt to read from the cache, + /// and also the max number of bytes that can be placed into + /// \a dst. + /// + /// @return + /// The number of bytes extracted from the data cache. + //------------------------------------------------------------------ + size_t + GetCachedBytes (void *dst, size_t dst_len); +}; + +} // namespace lldb_private + +#endif // liblldb_Communication_h_ diff --git a/lldb/include/lldb/Core/Connection.h b/lldb/include/lldb/Core/Connection.h new file mode 100644 index 00000000000..ca16930e8d0 --- /dev/null +++ b/lldb/include/lldb/Core/Connection.h @@ -0,0 +1,176 @@ +//===-- Connection.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Connection_h_ +#define liblldb_Connection_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Connection Connection.h "lldb/Core/Connection.h" +/// @brief A communication connection class. +/// +/// A class that implements that actual communication functions for +/// connecting/disconnecting, reading/writing, and waiting for bytes +/// to become available from a two way communication connection. +/// +/// This class is designed to only do very simple communication +/// functions. Instances can be instantiated and given to a +/// Communication class to perform communications where clients can +/// listen for broadcasts, and perform other higher level communications. +//---------------------------------------------------------------------- +class Connection +{ +public: + //------------------------------------------------------------------ + /// Default constructor + //------------------------------------------------------------------ + Connection (); + + //------------------------------------------------------------------ + /// Virtual destructor since this class gets subclassed and handed + /// to a Communication object. + //------------------------------------------------------------------ + virtual + ~Connection (); + + //------------------------------------------------------------------ + /// Poll for bytes available if the communications supports it. + /// + /// @param[in] timeout_usec + /// A timeout value in micro-seconds. + /// + /// @param[out] error + /// A reference to an error object that should be given an + /// approriate error value if this method returns false. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// \b True if the bytes are, or became available within the + /// timeout period, \b false otherwise. + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus + BytesAvailable (uint32_t timeout_usec, Error *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Connect using the connect string \a url. + /// + /// @param[in] url + /// A string that contains all information needed by the + /// subclass to connect to another client. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// approriate error value if this method returns false. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// \b True if the connect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Error& Communication::GetError (); + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus + Connect (const char *url, Error *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Disconnect the communications connection if one is currently + /// connected. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// approriate error value if this method returns false. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// \b True if the disconnect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Error& Communication::GetError (); + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus + Disconnect (Error *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Check if the connection is valid. + /// + /// @return + /// \b True if this object is currently connected, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual bool + IsConnected () const = 0; + + //------------------------------------------------------------------ + /// The read function that attempts to read from the connection. + /// + /// @param[in] dst + /// A destination buffer that must be at least \a dst_len bytes + /// long. + /// + /// @param[in] dst_len + /// The number of bytes to attempt to read, and also the max + /// number of bytes that can be placed into \a dst. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// approriate error value if this method returns zero. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// The number of bytes actually read. + /// + /// @see size_t Communication::Read (void *, size_t, uint32_t); + //------------------------------------------------------------------ + virtual size_t + Read (void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr) = 0; + + //------------------------------------------------------------------ + /// The actual write function that attempts to write to the + /// communications protocol. + /// + /// Subclasses must override this function. + /// + /// @param[in] src + /// A source buffer that must be at least \a src_len bytes + /// long. + /// + /// @param[in] src_len + /// The number of bytes to attempt to write, and also the + /// number of bytes are currently available in \a src. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// approriate error value if this method returns zero. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// The number of bytes actually Written. + //------------------------------------------------------------------ + virtual size_t + Write (const void *buffer, size_t length, lldb::ConnectionStatus &status, Error *error_ptr) = 0; + +private: + //------------------------------------------------------------------ + // For Connection only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Connection); +}; + +} // namespace lldb_private + +#endif // liblldb_Connection_h_ diff --git a/lldb/include/lldb/Core/ConnectionFileDescriptor.h b/lldb/include/lldb/Core/ConnectionFileDescriptor.h new file mode 100644 index 00000000000..53a3997eab7 --- /dev/null +++ b/lldb/include/lldb/Core/ConnectionFileDescriptor.h @@ -0,0 +1,74 @@ +//===-- ConnectionFileDescriptor.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ConnectionFileDescriptor_h_ +#define liblldb_ConnectionFileDescriptor_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Connection.h" + +namespace lldb_private { + +class ConnectionFileDescriptor : + public Connection +{ +public: + + ConnectionFileDescriptor (); + + ConnectionFileDescriptor (int fd, bool owns_fd); + + virtual + ~ConnectionFileDescriptor (); + + virtual bool + IsConnected () const; + + virtual lldb::ConnectionStatus + BytesAvailable (uint32_t timeout_usec, Error *error_ptr); + + virtual lldb::ConnectionStatus + Connect (const char *s, Error *error_ptr); + + virtual lldb::ConnectionStatus + Disconnect (Error *error_ptr); + + virtual size_t + Read (void *dst, size_t dst_len, lldb::ConnectionStatus &status, Error *error_ptr); + + virtual size_t + Write (const void *src, size_t src_len, lldb::ConnectionStatus &status, Error *error_ptr); + +protected: + lldb::ConnectionStatus + SocketListen (uint16_t listen_port_num, Error *error_ptr); + + lldb::ConnectionStatus + SocketConnect (const char *host_and_port, Error *error_ptr); + + lldb::ConnectionStatus + Close (int& fd, Error *error); + + int m_fd; // Socket we use to communicate once conn established + bool m_is_socket; + bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. + + static int + SetSocketOption(int fd, int level, int option_name, int option_value); + +private: + DISALLOW_COPY_AND_ASSIGN (ConnectionFileDescriptor); +}; + +} // namespace lldb_private + +#endif // liblldb_ConnectionFileDescriptor_h_ diff --git a/lldb/include/lldb/Core/ConstString.h b/lldb/include/lldb/Core/ConstString.h new file mode 100644 index 00000000000..9d95b96945b --- /dev/null +++ b/lldb/include/lldb/Core/ConstString.h @@ -0,0 +1,396 @@ +//===-- ConstString.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ConstString_h_ +#define liblldb_ConstString_h_ +#if defined(__cplusplus) + +#include <assert.h> + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ConstString ConstString.h "lldb/Core/ConstString.h" +/// @brief A uniqued constant string class. +/// +/// Provides an efficient way to store strings as uniqued ref counted +/// strings. Since the strings are uniqued, finding strings that are +/// equal to one another is very fast (pointer compares). It also allows +/// for many common strings from many different sources to be shared to +/// keep the memory footprint low. +//---------------------------------------------------------------------- +class ConstString +{ +public: + //------------------------------------------------------------------ + /// Default constructor + /// + /// Initializes the string to an empty string. + //------------------------------------------------------------------ + ConstString (); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Copies the string value in \a rhs and retains an extra reference + /// to the string value in the string pool. + /// + /// @param[in] rhs + /// Another string object to copy. + //------------------------------------------------------------------ + ConstString (const ConstString& rhs); + + //------------------------------------------------------------------ + /// Construct with C String value + /// + /// Constructs this object with a C string by looking to see if the + /// C string already exists in the global string pool. If it does + /// exist, it retains an extra reference to the string in the string + /// pool. If it doesn't exist, it is added to the string pool with + /// a reference count of 1. + /// + /// @param[in] cstr + /// A NULL terminated C string to add to the string pool. + //------------------------------------------------------------------ + explicit ConstString (const char *cstr); + + //------------------------------------------------------------------ + /// Construct with C String value with max length + /// + /// Constructs this object with a C string with a length. If + /// \a max_cstr_len is greater than the actual length of the string, + /// the string length will be truncated. This allows substrings to + /// be created without the need to NULL terminate the string as it + /// is passed into this function. + /// + /// If the C string already exists in the global string pool, it + /// retains an extra reference to the string in the string + /// pool. If it doesn't exist, it is added to the string pool with + /// a reference count of 1. + /// + /// @param[in] cstr + /// A NULL terminated C string to add to the string pool. + /// + /// @param[in] max_cstr_len + /// The max length of \a cstr. If the string length of \a cstr + /// is less than \a max_cstr_len, then the string will be + /// truncated. If the string length of \a cstr is greater than + /// \a max_cstr_len, then only max_cstr_len bytes will be used + /// from \a cstr. + //------------------------------------------------------------------ + explicit ConstString (const char *cstr, size_t max_cstr_len); + + //------------------------------------------------------------------ + /// Destructor + /// + /// Decrements the reference count on the contained string, and if + /// the resulting reference count is zero, then the string is removed + /// from the global string pool. If the reference count is still + /// greater than zero, the string will remain in the string pool + /// until the last reference is released by other ConstString objects. + //------------------------------------------------------------------ + ~ConstString (); + + //---------------------------------------------------------------------- + /// C string equality function object for CStrings contains in the + /// same StringPool only. (binary predicate). + //---------------------------------------------------------------------- + struct StringIsEqual + { + //-------------------------------------------------------------- + /// C equality test. + /// + /// Two C strings are equal when they are contained in ConstString + /// objects when their pointer values are equal to each other. + /// + /// @return + /// Returns \b true if the C string in \a lhs is equal to + /// the C string value in \a rhs, \b false otherwise. + //-------------------------------------------------------------- + bool operator()(const char* lhs, const char* rhs) const + { + return lhs == rhs; + } + }; + + //------------------------------------------------------------------ + /// Convert to pointer operator. + /// + /// This allows code to check a ConstString object to see if it + /// contains a valid string using code such as: + /// + /// @code + /// ConstString str(...); + /// if (str) + /// { ... + /// @endcode + /// + /// @return + /// A pointer to this object if the string isn't empty, NULL + /// otherwise. + //------------------------------------------------------------------ + operator void*() const; + + + //------------------------------------------------------------------ + /// Assignment operator + /// + /// Assigns the string in this object with the value from \a rhs + /// and increments the reference count of that string. + /// + /// The previously contained string will be get its reference count + /// decremented and removed from the string pool if its reference + /// count reaches zero. + /// + /// @param[in] rhs + /// Another string object to copy into this object. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const ConstString& + operator = (const ConstString& rhs); + + //------------------------------------------------------------------ + /// Equal to operator + /// + /// Returns true if this string is equal to the string in \a rhs. + /// This operation is very fast as it results in a pointer + /// comparison since all strings are in a uniqued and reference + /// counted string pool. + /// + /// @param[in] rhs + /// Another string object to compare this object to. + /// + /// @return + /// @li \b true if this object is equal to \a rhs. + /// @li \b false if this object is not equal to \a rhs. + //------------------------------------------------------------------ + bool + operator == (const ConstString& rhs) const; + + //------------------------------------------------------------------ + /// Not equal to operator + /// + /// Returns true if this string is not equal to the string in \a rhs. + /// This operation is very fast as it results in a pointer + /// comparison since all strings are in a uniqued and reference + /// counted string pool. + /// + /// @param[in] rhs + /// Another string object to compare this object to. + /// + /// @return + /// @li \b true if this object is not equal to \a rhs. + /// @li \b false if this object is equal to \a rhs. + //------------------------------------------------------------------ + bool + operator != (const ConstString& rhs) const; + + bool + operator < (const ConstString& rhs) const; + + //------------------------------------------------------------------ + /// Get the string value as a C string. + /// + /// Get the value of the contained string as a NULL terminated C + /// string value. + /// + /// If \a value_if_empty is NULL, then NULL will be returned. + /// + /// @return + /// Returns \a value_if_empty if the string is empty, otherwise + /// the C string value contained in this object. + //------------------------------------------------------------------ + const char * + AsCString(const char *value_if_empty = NULL) const; + + + const char * + GetCString () const; + + size_t + GetLength () const; + //------------------------------------------------------------------ + /// Clear this object's state. + /// + /// Clear any contained string and reset the value to the an empty + /// string value. + /// + /// The previously contained string will be get its reference count + /// decremented and removed from the string pool if its reference + /// count reaches zero. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Compare two string objects. + /// + /// Compares the C string values contained in \a lhs and \a rhs and + /// returns an integer result. + /// + /// @param[in] lhs + /// The Left Hand Side const ConstString object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const ConstString object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int + Compare (const ConstString& lhs, const ConstString& rhs); + + //------------------------------------------------------------------ + /// Dump the object description to a stream. + /// + /// Dump the string value to the stream \a s. If the contained string + /// is empty, print \a value_if_empty to the stream instead. If + /// \a value_if_empty is NULL, then nothing will be dumped to the + /// stream. + /// + /// @param[in] s + /// The stream that will be used to dump the object description. + /// + /// @param[in] value_if_empty + /// The value to dump if the string is empty. If NULL, nothing + /// will be output to the stream. + //------------------------------------------------------------------ + void + Dump (Stream *s, const char *value_if_empty = NULL) const; + + //------------------------------------------------------------------ + /// Dump the object debug description to a stream. + /// + /// Dump the string value and the reference count to the stream \a + /// s. + /// + /// @param[in] s + /// The stream that will be used to dump the object description. + //------------------------------------------------------------------ + void + DumpDebug (Stream *s) const; + + //------------------------------------------------------------------ + /// Test for empty string. + /// + /// @return + /// @li \b true if the contained string is empty. + /// @li \b false if the contained string is not empty. + //------------------------------------------------------------------ + bool + IsEmpty () const; + + //------------------------------------------------------------------ + /// Set the C string value. + /// + /// Set the string value in the object by uniquing the \a cstr + /// string value in our global string pool. + /// + /// If the C string already exists in the global string pool, it + /// finds the current entry and retains an extra reference to the + /// string in the string pool. If it doesn't exist, it is added to + /// the string pool with a reference count of 1. + /// + /// @param[in] cstr + /// A NULL terminated C string to add to the string pool. + //------------------------------------------------------------------ + void + SetCString (const char *cstr); + + //------------------------------------------------------------------ + /// Set the C string value with length. + /// + /// Set the string value in the object by uniquing \a cstr_len bytes + /// starting at the \a cstr string value in our global string pool. + /// If trim is true, then \a cstr_len indicates a maximum length of + /// the CString and if the actual length of the string is less, then + /// it will be trimmed. If trim is false, then this allows strings + /// with NULL characters to be added to the string pool. + /// + /// If the C string already exists in the global string pool, it + /// retains an extra reference to the string in the string + /// pool. If it doesn't exist, it is added to the string pool with + /// a reference count of 1. + /// + /// @param[in] cstr + /// A NULL terminated C string to add to the string pool. + /// + /// @param[in] cstr_len + /// The absolute length of the C string if \a trim is false, + /// or the maximum length of the C string if \a trim is true. + /// + /// @param[in] trim + /// If \b true, trim \a cstr to it's actual length before adding + /// it to the string pool. If \b false then cstr_len is the + /// actual length of the C string to add. + //------------------------------------------------------------------ + void + SetCStringWithLength (const char *cstr, size_t cstr_len); + + //------------------------------------------------------------------ + /// Set the C string value with the minimum length between + /// \a fixed_cstr_len and the actual length of the C string. This + /// can be used for data structures that have a fixed length to + /// store a C string where the string might not be NULL terminated + /// if the string takes the entire buffer. + //------------------------------------------------------------------ + void + SetTrimmedCStringWithLength (const char *cstr, size_t fixed_cstr_len); + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Return the size in bytes that this object takes in memory. This + /// returns the size in bytes of this object, which does not include + /// any the shared string values it may refer to. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Get the size in bytes of the current global string pool. + /// + /// Reports the the size in bytes of all shared C string values, + /// containers and reference count values as a byte size for the + /// entire string pool. + /// + /// @return + /// The number of bytes that the global string pool occupies + /// in memory. + //------------------------------------------------------------------ + static size_t + StaticMemorySize (); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + const char *m_string; +}; + +//------------------------------------------------------------------ +/// Stream the string value \a str to the stream \a s +//------------------------------------------------------------------ +Stream& operator << (Stream& s, const ConstString& str); + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_ConstString_h_ diff --git a/lldb/include/lldb/Core/DataBuffer.h b/lldb/include/lldb/Core/DataBuffer.h new file mode 100644 index 00000000000..9acaea6cb5b --- /dev/null +++ b/lldb/include/lldb/Core/DataBuffer.h @@ -0,0 +1,94 @@ +//===-- DataBuffer.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DataBuffer_h_ +#define liblldb_DataBuffer_h_ +#if defined(__cplusplus) + +#include <stdint.h> +#include <string.h> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" +/// @brief A pure virtual protocol class for abstracted data buffers. +/// +/// DataBuffer is an abtract class that gets packaged into a shared pointer +/// that can use to implement various ways to store data (on the heap, +/// memory mapped, cached inferior memory). It gets used by DataExtractor +/// so many DataExtractor objects can share the same data and sub-ranges +/// of that shared data, and the last object that contains a reference +/// to the shared data will free it. +/// +/// Subclasses can implement as many different constructors or member +/// functions that allow data to be stored in the object's buffer prior +/// to handing the shared data to clients that use these buffers. +/// +/// All subclasses must override all of the pure virtual functions as +/// they are used by clients to access the data. Having a common +/// interface allows different ways of storing data, yet using it in +/// one common way. +/// +/// This class currently expects all data to be available without any +/// extra calls being made, but we can modify it to optionally get +/// data on demand with some extra function calls to load the data +/// before it gets accessed. +//---------------------------------------------------------------------- +class DataBuffer +{ +public: + //------------------------------------------------------------------ + /// Destructor + /// + /// The destructor is virtual as other classes will inherit from + /// this class and be downcast to the DataBuffer pure virtual + /// interface. The virtual destructor ensures that destructing the + /// base class will destruct the class that inherited from it + /// correctly. + //------------------------------------------------------------------ + virtual + ~DataBuffer() + { + } + + //------------------------------------------------------------------ + /// Get a pointer to the data. + /// + /// @return + /// A pointer to the bytes owned by this object, or NULL if the + /// object contains no bytes. + //------------------------------------------------------------------ + virtual uint8_t * + GetBytes () = 0; + + //------------------------------------------------------------------ + /// Get a const pointer to the data. + /// + /// @return + /// A const pointer to the bytes owned by this object, or NULL + /// if the object contains no bytes. + //------------------------------------------------------------------ + virtual const uint8_t * + GetBytes () const = 0; + + //------------------------------------------------------------------ + /// Get the number of bytes in the data buffer. + /// + /// @return + /// The number of bytes this object currently contains. + //------------------------------------------------------------------ + virtual size_t + GetByteSize() const = 0; +}; + +} // namespace lldb_private + +#endif /// #if defined(__cplusplus) +#endif /// lldb_DataBuffer_h_ diff --git a/lldb/include/lldb/Core/DataBufferHeap.h b/lldb/include/lldb/Core/DataBufferHeap.h new file mode 100644 index 00000000000..99fa2e57087 --- /dev/null +++ b/lldb/include/lldb/Core/DataBufferHeap.h @@ -0,0 +1,136 @@ +//===-- DataBufferHeap.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DataBufferHeap_h_ +#define liblldb_DataBufferHeap_h_ +#if defined(__cplusplus) + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/DataBuffer.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class DataBufferHeap DataBufferHeap.h "lldb/Core/DataBufferHeap.h" +/// @brief A subclass of DataBuffer that stores a data buffer on the heap. +/// +/// This class keeps its data in a heap based buffer that is owned by +/// the object. This class is best used to store chunks of data that +/// are created or read from sources that can't intelligently and lazily +/// fault new data pages in. Large amounts of data that comes from files +/// should probably use the DataBufferMemoryMap class. +//---------------------------------------------------------------------- +class DataBufferHeap : public DataBuffer +{ +public: + //------------------------------------------------------------------ + /// Default constructor + /// + /// Initializes the heap based buffer with no bytes. + //------------------------------------------------------------------ + DataBufferHeap (); + + //------------------------------------------------------------------ + /// Construct with size \a n and fill with \a ch. + /// + /// Initialize this class with \a n bytes and fills the buffer with + /// \a ch. + /// + /// @param[in] n + /// The number of bytes that heap based buffer should contain. + /// + /// @param[in] ch + /// The character to use when filling the buffer initially. + //------------------------------------------------------------------ + DataBufferHeap (size_t n, uint8_t ch); + + //------------------------------------------------------------------ + /// Construct by making a copy of \a src_len bytes from \a src. + /// + /// @param[in] src + /// A pointer to the data to copy. + /// + /// @param[in] src_len + /// The number of bytes in \a src to copy. + //------------------------------------------------------------------ + DataBufferHeap (const void *src, size_t src_len); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// Virtual destructor since this class inherits from a pure virtual + /// base class #DataBuffer. + //------------------------------------------------------------------ + virtual + ~DataBufferHeap(); + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetBytes() + //------------------------------------------------------------------ + virtual uint8_t * + GetBytes (); + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetBytes() const + //------------------------------------------------------------------ + virtual const uint8_t * + GetBytes () const; + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetByteSize() const + //------------------------------------------------------------------ + virtual size_t + GetByteSize () const; + + //------------------------------------------------------------------ + /// Set the number of bytes in the data buffer. + /// + /// Sets the number of bytes that this object should be able to + /// contain. This can be used prior to copying data into the buffer. + /// + /// @param[in] byte_size + /// The new size in bytes that this data buffer should attempt + /// to resize itself to. + /// + /// @return + /// The size in bytes after that this heap buffer was + /// successfully resized to. + //------------------------------------------------------------------ + size_t + SetByteSize (size_t byte_size); + + //------------------------------------------------------------------ + /// Makes a copy of the \a src_len bytes in \a src. + /// + /// Copies the data in \a src into an internal buffer. + /// + /// @param[in] src + /// A pointer to the data to copy. + /// + /// @param[in] src_len + /// The number of bytes in \a src to copy. + //------------------------------------------------------------------ + void + CopyData (const void *src, size_t src_len); + +private: + //------------------------------------------------------------------ + // This object uses a std::vector<uint8_t> to store its data. This + // takes care of free the data when the object is deleted. + //------------------------------------------------------------------ + typedef std::vector<uint8_t> buffer_t; ///< Buffer type + buffer_t m_data; ///< The heap based buffer where data is stored +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_DataBufferHeap_h_ diff --git a/lldb/include/lldb/Core/DataBufferMemoryMap.h b/lldb/include/lldb/Core/DataBufferMemoryMap.h new file mode 100644 index 00000000000..910601537eb --- /dev/null +++ b/lldb/include/lldb/Core/DataBufferMemoryMap.h @@ -0,0 +1,156 @@ +//===-- DataBufferMemoryMap.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DataBufferMemoryMap_h_ +#define liblldb_DataBufferMemoryMap_h_ +#if defined(__cplusplus) + + +#include "lldb/lldb-private.h" +#include "lldb/Core/DataBuffer.h" +#include "lldb/Core/Error.h" +#include <string> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class DataBufferMemoryMap DataBufferMemoryMap.h "lldb/Core/DataBufferMemoryMap.h" +/// @brief A subclass of DataBuffer that memory maps data. +/// +/// This class memory maps data and stores any needed data for the +/// memory mapping in its internal state. Memory map requests are not +/// required to have any alignment or size constraints, this class will +/// work around any host OS issues regarding such things. +/// +/// This class is designed to allow pages to be faulted in as needed and +/// works well data from large files that won't be accessed all at once. +//---------------------------------------------------------------------- +class DataBufferMemoryMap : public DataBuffer +{ +public: + //------------------------------------------------------------------ + /// Default Constructor + //------------------------------------------------------------------ + DataBufferMemoryMap (); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// Virtual destructor since this class inherits from a pure virtual + /// base class #DataBuffer. + //------------------------------------------------------------------ + virtual + ~DataBufferMemoryMap (); + + //------------------------------------------------------------------ + /// Reverts this object to an empty state by unmapping any memory + /// that is currently owned. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetBytes() + //------------------------------------------------------------------ + virtual uint8_t * + GetBytes (); + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetBytes() const + //------------------------------------------------------------------ + virtual const uint8_t * + GetBytes () const; + + //------------------------------------------------------------------ + /// @copydoc DataBuffer::GetByteSize() const + //------------------------------------------------------------------ + virtual size_t + GetByteSize () const; + + //------------------------------------------------------------------ + /// Error get accessor. + /// + /// @return + /// A const reference to Error object in case memory mapping + /// fails. + //------------------------------------------------------------------ + const Error & + GetError() const; + + //------------------------------------------------------------------ + /// Memory map all or part of a file. + /// + /// Memory map \a length bytes from \a file starting \a offset + /// bytes into the file. If \a length is set to \c SIZE_T_MAX, + /// then map as many bytes as possible. + /// + /// @param[in] file + /// The file specification from which to map data. + /// + /// @param[in] offset + /// The offset in bytes from the beginning of the file where + /// memory mapping should begin. + /// + /// @param[in] length + /// The size in bytes that should be mapped starting \a offset + /// bytes into the file. If \a length is \c SIZE_T_MAX, map + /// as many bytes as possible. + /// + /// @return + /// The number of bytes mapped starting from the \a offset. + //------------------------------------------------------------------ + size_t + MemoryMapFromFileSpec (const FileSpec* file, + off_t offset = 0, + size_t length = SIZE_T_MAX); + + //------------------------------------------------------------------ + /// Memory map all or part of a file. + /// + /// Memory map \a length bytes from an opened file descriptor \a fd + /// starting \a offset bytes into the file. If \a length is set to + /// \c SIZE_T_MAX, then map as many bytes as possible. + /// + /// @param[in] fd + /// The posix file descriptor for an already opened file + /// from which to map data. + /// + /// @param[in] offset + /// The offset in bytes from the beginning of the file where + /// memory mapping should begin. + /// + /// @param[in] length + /// The size in bytes that should be mapped starting \a offset + /// bytes into the file. If \a length is \c SIZE_T_MAX, map + /// as many bytes as possible. + /// + /// @return + /// The number of bytes mapped starting from the \a offset. + //------------------------------------------------------------------ + size_t + MemoryMapFromFileDescriptor (int fd, off_t offset = 0, size_t length = SIZE_T_MAX); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from DataBufferMemoryMap can see and modify these + //------------------------------------------------------------------ + uint8_t * m_mmap_addr; ///< The actual pointer that was returned from \c mmap() + size_t m_mmap_size; ///< The actual number of bytes that were mapped when \c mmap() was called + uint8_t *m_data; ///< The data the user requested somewhere within the memory mapped data. + size_t m_size; ///< The size of the data the user got when data was requested + Error m_error; ///< An error object that describes any errors that occurred during the memory mapping process + +private: + DISALLOW_COPY_AND_ASSIGN (DataBufferMemoryMap); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_DataBufferMemoryMap_h_ diff --git a/lldb/include/lldb/Core/DataExtractor.h b/lldb/include/lldb/Core/DataExtractor.h new file mode 100644 index 00000000000..b6ac6e93d08 --- /dev/null +++ b/lldb/include/lldb/Core/DataExtractor.h @@ -0,0 +1,1124 @@ +//===-- DataExtractor.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DataExtractor_h_ +#define liblldb_DataExtractor_h_ +#if defined (__cplusplus) + + +#include "lldb/lldb-private.h" +#include <limits.h> +#include <stdint.h> +#include <string.h> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class DataExtractor DataExtractor.h "lldb/Core/DataExtractor.h" +/// @brief An data extractor class. +/// +/// DataExtractor is a class that can extract data (swapping if needed) +/// from a data buffer. The data buffer can be caller owned, or can be +/// shared data that can be shared between multiple DataExtractor +/// instances. Multiple DataExtractor objects can share the same data, +/// yet extract values in different address sizes and byte order modes. +/// Each object can have a unique position in the shared data and extract +/// data from different offsets. +/// +/// @see DataBuffer +//---------------------------------------------------------------------- +class DataExtractor +{ +public: + //------------------------------------------------------------------ + /// @typedef DataExtractor::Type + /// @brief Type enumerations used in the dump routines. + /// @see DataExtractor::Dump() + /// @see DataExtractor::DumpRawHexBytes() + //------------------------------------------------------------------ + typedef enum + { + TypeUInt8, ///< Format output as unsigned 8 bit integers + TypeChar, ///< Format output as characters + TypeUInt16, ///< Format output as unsigned 16 bit integers + TypeUInt32, ///< Format output as unsigned 32 bit integers + TypeUInt64, ///< Format output as unsigned 64 bit integers + TypePointer, ///< Format output as pointers + TypeULEB128, ///< Format output as ULEB128 numbers + TypeSLEB128 ///< Format output as SLEB128 numbers + } Type; + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all members to a default empty state. + //------------------------------------------------------------------ + DataExtractor (); + + //------------------------------------------------------------------ + /// Construct with a buffer that is owned by the caller. + /// + /// This constructor allows us to use data that is owned by the + /// caller. The data must stay around as long as this object is + /// valid. + /// + /// @param[in] data + /// A pointer to caller owned data. + /// + /// @param[in] data_length + /// The length in bytes of \a data. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @param[in] addr_size + /// A new address byte size value. + //------------------------------------------------------------------ + DataExtractor (const void* data, uint32_t data_length, lldb::ByteOrder byte_order, uint8_t addr_size); + + //------------------------------------------------------------------ + /// Construct with shared data. + /// + /// Copies the data shared pointer which adds a reference to the + /// contained in \a data_sp. The shared data reference is reference + /// counted to ensure the data lives as long as anyone still has a + /// valid shared pointer to the data in \a data_sp. + /// + /// @param[in] data_sp + /// A shared pointer to data. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @param[in] addr_size + /// A new address byte size value. + //------------------------------------------------------------------ + DataExtractor (lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size); + + //------------------------------------------------------------------ + /// Construct with a subset of \a data. + /// + /// Initialize this object with a subset of the data bytes in \a + /// data. If \a data contains shared data, then a reference to the + /// shared data will be added to ensure the shared data stays around + /// as long as any objects have references to the shared data. The + /// byte order value and the address size settings are copied from \a + /// data. If \a offset is not a valid offset in \a data, then no + /// reference to the shared data will be added. If there are not + /// \a length bytes available in \a data starting at \a offset, + /// the length will be truncated to contain as many bytes as + /// possible. + /// + /// @param[in] data + /// Another DataExtractor object that contains data. + /// + /// @param[in] offset + /// The offset into \a data at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of data. + //------------------------------------------------------------------ + DataExtractor (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT32_MAX); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies all data, byte order and address size settings from \a rhs into + /// this object. If \a rhs contains shared data, a reference to that + /// shared data will be added. + /// + /// @param[in] rhs + /// Another DataExtractor object to copy. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const DataExtractor& + operator= (const DataExtractor& rhs); + + //------------------------------------------------------------------ + /// Destructor + /// + /// If this object contains a valid shared data reference, the + /// reference count on the data will be decremented, and if zero, + /// the data will be freed. + //------------------------------------------------------------------ + ~DataExtractor (); + + //------------------------------------------------------------------ + /// Clears the object state. + /// + /// Clears the object contents back to a default invalid state, and + /// release any references to shared data that this object may + /// contain. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Dumps the binary data as \a type objects to stream \a s (or to + /// Log() if \a s is NULL) starting \a offset bytes into the data + /// and stopping after dumping \a length bytes. The offset into the + /// data is displayed at the beginning of each line and can be + /// offset by base address \a base_addr. \a num_per_line objects + /// will be displayed on each line. + /// + /// @param[in] s + /// The stream to dump the output to. If NULL the output will + /// be dumped to Log(). + /// + /// @param[in] offset + /// The offset into the data at which to start dumping. + /// + /// @param[in] length + /// The number of bytes to dump. + /// + /// @param[in] base_addr + /// The base address that gets added to the offset displayed on + /// each line. + /// + /// @param[in] num_per_line + /// The number of \a type objects to display on each line. + /// + /// @param[in] type + /// The type of objects to use when dumping data from this + /// object. See DataExtractor::Type. + /// + /// @param[in] type_format + /// The optional format to use for the \a type objects. If this + /// is NULL, the default format for the \a type will be used. + /// + /// @return + /// The offset at which dumping ended. + //------------------------------------------------------------------ + uint32_t + PutToLog (Log *log, + uint32_t offset, + uint32_t length, + uint64_t base_addr, + uint32_t num_per_line, + Type type, + const char *type_format = NULL) const; + + //------------------------------------------------------------------ + /// Dumps \a item_count objects into the stream \a s. + /// + /// Dumps \a item_count objects using \a item_format, each of which + /// are \a item_byte_size bytes long starting at offset \a offset + /// bytes into the contained data, into the stream \a s. \a + /// num_per_line objects will be dumped on each line before a new + /// line will be output. If \a base_addr is a valid address, then + /// each new line of output will be prededed by the address value + /// plus appropriate offset, and a colon and space. Bitfield values + /// can be dumped by calling this function multiple times with the + /// same start offset, format and size, yet differing \a + /// item_bit_size and \a item_bit_offset values. + /// + /// @param[in] s + /// The stream to dump the output to. This value can not be NULL. + /// + /// @param[in] offset + /// The offset into the data at which to start dumping. + /// + /// @param[in] item_format + /// The format to use when dumping each item. + /// + /// @param[in] item_byte_size + /// The byte size of each item. + /// + /// @param[in] item_count + /// The number of items to dump. + /// + /// @param[in] num_per_line + /// The number of items to display on each line. + /// + /// @param[in] base_addr + /// The base address that gets added to the offset displayed on + /// each line if the value is valid. Is \a base_addr is + /// LLDB_INVALID_ADDRESS then no address values will be prepended + /// to any lines. + /// + /// @param[in] item_bit_size + /// If the value to display is a bitfield, this value should + /// be the number of bits that the bitfield item has within the + /// item's byte size value. This function will need to be called + /// multiple times with identical \a offset and \a item_byte_size + /// values in order to display multiple bitfield values that + /// exist within the same integer value. If the items being + /// displayed are not bitfields, this value should be zero. + /// + /// @param[in] item_bit_offset + /// If the value to display is a bitfield, this value should + /// be the offset in bits, or shift right amount, that the + /// bitfield item occupies within the item's byte size value. + /// This function will need to be called multiple times with + /// identical \a offset and \a item_byte_size values in order + /// to display multiple bitfield values that exist within the + /// same integer value. If the items being displayed are not + /// bitfields, this value should be zero. + /// + /// @return + /// The offset at which dumping ended. + //------------------------------------------------------------------ + uint32_t + Dump(Stream *s, + uint32_t offset, + lldb::Format item_format, + uint32_t item_byte_size, + uint32_t item_count, + uint32_t num_per_line, + uint64_t base_addr, + uint32_t item_bit_size, + uint32_t item_bit_offset) const; + + //------------------------------------------------------------------ + /// Dump a UUID value at \a offset. + /// + /// Dump a UUID starting at \a offset bytes into this object's data. + /// If the stream \a s is NULL, the output will be sent to Log(). + /// + /// @param[in] s + /// The stream to dump the output to. If NULL the output will + /// be dumped to Log(). + /// + /// @param[in] offset + /// The offset into the data at which to extract and dump a + /// UUID value. + //------------------------------------------------------------------ + void + DumpUUID (Stream *s, uint32_t offset) const; + + //------------------------------------------------------------------ + /// Extract an arbitrary number of bytes in the specified byte + /// order. + /// + /// Attemps to extract \a length bytes starting at \a offset bytes + /// into this data in the requested byte order (\a dst_byte_order) + /// and place the results in \a dst. \a dst must be at least \a + /// length bytes long. + /// + /// @param[in] offset + /// The offset in bytes into the contained data at which to + /// start extracting. + /// + /// @param[in] length + /// The number of bytes to extract. + /// + /// @param[in] dst_byte_order + /// A byte order of the data that we want when the value in + /// copied to \a dst. + /// + /// @param[out] dst + /// The buffer that will receive the extracted value if there + /// are enough bytes available in the current data. + /// + /// @return + /// The number of bytes that were extracted which will be \a + /// length when the value is successfully extracted, or zero + /// if there aren't enough bytes at the specified offset. + //------------------------------------------------------------------ + size_t + ExtractBytes (uint32_t offset, uint32_t length, lldb::ByteOrder dst_byte_order, void *dst) const; + + //------------------------------------------------------------------ + /// Extract an address from \a *offset_ptr. + /// + /// Extract a single address from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted address + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any address values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted address value. + //------------------------------------------------------------------ + uint64_t + GetAddress (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Get the current address size. + /// + /// Return the size in bytes of any address values this object will + /// extract. + /// + /// @return + /// The size in bytes of address values that will be extracted. + //------------------------------------------------------------------ + uint8_t + GetAddressByteSize () const; + + //------------------------------------------------------------------ + /// Get the number of bytes contained in this object. + /// + /// @return + /// The total number of bytes of data this object refers to. + //------------------------------------------------------------------ + size_t + GetByteSize () const; + + //------------------------------------------------------------------ + /// Extract a C string from \a *offset_ptr. + /// + /// Returns a pointer to a C String from the data at the offset + /// pointed to by \a offset_ptr. A variable length NULL terminated C + /// string will be extracted and the \a offset_ptr will be + /// updated with the offset of the byte that follows the NULL + /// terminator byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// A pointer to the C string value in the data. If the offset + /// pointed to by \a offset_ptr is out of bounds, or if the + /// offset plus the length of the C string is out of bounds, + /// NULL will be returned. + //------------------------------------------------------------------ + const char * + GetCStr (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a length bytes from \a *offset_ptr. + /// + /// Returns a pointer to a bytes in this object's data at the offset + /// pointed to by \a offset_ptr. If \a length is zero or too large, + /// then the offset pointed to by \a offset_ptr will not be updated + /// and NULL will be returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] length + /// The optional length of a string to extract. If the value is + /// zero, a NULL terminated C string will be extracted. + /// + /// @return + /// A pointer to the bytes in this object's data if the offset + /// and length are valid, or NULL otherwise. + //------------------------------------------------------------------ + const void* + GetData (uint32_t *offset_ptr, uint32_t length) const; + + //------------------------------------------------------------------ + /// Get the data end pointer. + /// + /// @return + /// Returns a pointer to the next byte contained in this + /// object's data, or NULL of there is no data in this object. + //------------------------------------------------------------------ + const uint8_t * + GetDataEnd () const; + + //------------------------------------------------------------------ + /// Get the shared data offset. + /// + /// Get the offset of the first byte of data in the shared data (if + /// any). + /// + /// @return + /// If this object contains shared data, this function returns + /// the offset in bytes into that shared data, zero otherwise. + //------------------------------------------------------------------ + size_t + GetSharedDataOffset () const; + + //------------------------------------------------------------------ + /// Get a the data start pointer. + /// + /// @return + /// Returns a pointer to the first byte contained in this + /// object's data, or NULL of there is no data in this object. + //------------------------------------------------------------------ + const uint8_t * + GetDataStart () const; + + + //------------------------------------------------------------------ + /// Extract a float from \a *offset_ptr. + /// + /// Extract a single float value. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The integer value that was extracted, or zero on failure. + //------------------------------------------------------------------ + float + GetFloat (uint32_t *offset_ptr) const; + + double + GetDouble (uint32_t *offset_ptr) const; + + long double + GetLongDouble (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract a GNU encoded pointer value from \a *offset_ptr. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] eh_ptr_enc + /// The GNU pointer encoding type. + /// + /// @param[in] pc_rel_addr + /// The PC relative address to use when the encoding is + /// \c DW_GNU_EH_PE_pcrel. + /// + /// @param[in] text_addr + /// The text (code) relative address to use when the encoding is + /// \c DW_GNU_EH_PE_textrel. + /// + /// @param[in] data_addr + /// The data relative address to use when the encoding is + /// \c DW_GNU_EH_PE_datarel. + /// + /// @return + /// The extracted GNU encoded pointer value. + //------------------------------------------------------------------ + uint64_t + GetGNUEHPointer (uint32_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, lldb::addr_t data_addr); + + //------------------------------------------------------------------ + /// Extract an integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single integer value and update the offset pointed to + /// by \a offset_ptr. The size of the extracted integer is specified + /// by the \a byte_size argument. \a byte_size should have a value + /// >= 1 and <= 4 since the return value is only 32 bits wide. Any + /// \a byte_size values less than 1 or greater than 4 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The integer value that was extracted, or zero on failure. + //------------------------------------------------------------------ + uint32_t + GetMaxU32 (uint32_t *offset_ptr, uint32_t byte_size) const; + + //------------------------------------------------------------------ + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to eight since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The unsigned integer value that was extracted, or zero on + /// failure. + //------------------------------------------------------------------ + uint64_t + GetMaxU64 (uint32_t *offset_ptr, uint32_t byte_size) const; + + //------------------------------------------------------------------ + /// Extract an signed integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The sign extended signed integer value that was extracted, + /// or zero on failure. + //------------------------------------------------------------------ + int64_t + GetMaxS64 (uint32_t *offset_ptr, uint32_t size) const; + + //------------------------------------------------------------------ + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr, then extract the bitfield from this value if + /// \a bitfield_bit_size is non-zero. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to 8 since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @param[in] bitfield_bit_size + /// The size in bits of the bitfield value to extract, or zero + /// to just extract the entire integer value. + /// + /// @param[in] bitfield_bit_offset + /// The bit offset of the bitfield value in the extracted + /// integer (the number of bits to shift the integer to the + /// right). + /// + /// @return + /// The unsigned bitfield integer value that was extracted, or + /// zero on failure. + //------------------------------------------------------------------ + uint64_t + GetMaxU64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const; + + //------------------------------------------------------------------ + /// Extract an signed integer of size \a byte_size from \a + /// *offset_ptr, then extract and signe extend the bitfield from + /// this value if \a bitfield_bit_size is non-zero. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in bytes of the integer to extract. + /// + /// @param[in] bitfield_bit_size + /// The size in bits of the bitfield value to extract, or zero + /// to just extract the entire integer value. + /// + /// @param[in] bitfield_bit_offset + /// The bit offset of the bitfield value in the extracted + /// integer (the number of bits to shift the integer to the + /// right). + /// + /// @return + /// The signed bitfield integer value that was extracted, or + /// zero on failure. + //------------------------------------------------------------------ + int64_t + GetMaxS64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const; + + //------------------------------------------------------------------ + /// Extract an pointer from \a *offset_ptr. + /// + /// Extract a single pointer from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted pointer + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any pointer values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted pointer value as a 64 integer. + //------------------------------------------------------------------ + uint64_t + GetPointer (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Get the current byte order value. + /// + /// @return + /// The current byte order value from this object's internal + /// state. + //------------------------------------------------------------------ + lldb::ByteOrder + GetByteOrder() const; + + //------------------------------------------------------------------ + /// Extract a uint8_t value from \a *offset_ptr. + /// + /// Extract a single uint8_t from the binary data at the offset + /// pointed to by \a offset_ptr, and advance the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint8_t value. + //------------------------------------------------------------------ + uint8_t + GetU8 ( uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint8_t values from \a *offset_ptr. + /// + /// Extract \a count uint8_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint8_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint8_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + //------------------------------------------------------------------ + void * + GetU8 ( uint32_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint16_t value from \a *offset_ptr. + /// + /// Extract a single uint16_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint16_t value. + //------------------------------------------------------------------ + uint16_t + GetU16 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint16_t values from \a *offset_ptr. + /// + /// Extract \a count uint16_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint16_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint16_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + //------------------------------------------------------------------ + void * + GetU16 (uint32_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint32_t value from \a *offset_ptr. + /// + /// Extract a single uint32_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint32_t value. + //------------------------------------------------------------------ + uint32_t + GetU32 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint32_t values from \a *offset_ptr. + /// + /// Extract \a count uint32_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint32_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint32_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + //------------------------------------------------------------------ + void * + GetU32 (uint32_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint64_t value from \a *offset_ptr. + /// + /// Extract a single uint64_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint64_t value. + //------------------------------------------------------------------ + uint64_t + GetU64 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract \a count uint64_t values from \a *offset_ptr. + /// + /// Extract \a count uint64_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint64_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint64_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + //------------------------------------------------------------------ + void * + GetU64 ( uint32_t *offset_ptr, void *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a signed LEB128 value from \a *offset_ptr. + /// + /// Extracts an signed LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted signed integer value. + //------------------------------------------------------------------ + int64_t + GetSLEB128 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Extract a unsigned LEB128 value from \a *offset_ptr. + /// + /// Extracts an unsigned LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted unsigned integer value. + //------------------------------------------------------------------ + uint64_t + GetULEB128 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Peek at a C string at \a offset. + /// + /// Peeks at a string in the contained data. No verification is done + /// to make sure the entire string lies within the bounds of this + /// object's data, only \a offset is verified to be a valid offset. + /// + /// @param[in] offset + /// An offset into the data. + /// + /// @return + /// A non-NULL C string pointer if \a offset is a valid offset, + /// NULL otherwise. + //------------------------------------------------------------------ + const char * + PeekCStr (uint32_t offset) const; + + //------------------------------------------------------------------ + /// Peek at a bytes at \a offset. + /// + /// Returns a pointer to \a length bytes at \a offset as long as + /// there are \a length bytes available starting at \a offset. + /// + /// @return + /// A non-NULL data pointer if \a offset is a valid offset and + /// there are \a length bytes available at that offset, NULL + /// otherwise. + //------------------------------------------------------------------ + const uint8_t* + PeekData (uint32_t offset, uint32_t length) const; + + //------------------------------------------------------------------ + /// Set the address byte size. + /// + /// Set the size in bytes that will be used when extracting any + /// address and pointer values from data contained in this object. + /// + /// @param[in] addr_size + /// The size in bytes to use when extracting addresses. + //------------------------------------------------------------------ + void + SetAddressByteSize (uint8_t addr_size); + + //------------------------------------------------------------------ + /// Set data with a buffer that is caller owned. + /// + /// Use data that is owned by the caller when extracting values. + /// The data must stay around as long as this object, or any object + /// that copies a subset of this object's data, is valid. If \a + /// bytes is NULL, or \a length is zero, this object will contain + /// no data. + /// + /// @param[in] bytes + /// A pointer to caller owned data. + /// + /// @param[in] length + /// The length in bytes of \a bytes. + /// + /// @param[in] byte_order + /// A byte order of the data that we are extracting from. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + uint32_t + SetData (const void *bytes, uint32_t length, lldb::ByteOrder byte_order); + + //------------------------------------------------------------------ + /// Adopt a subset of \a data. + /// + /// Set this object's data to be a subset of the data bytes in \a + /// data. If \a data contains shared data, then a reference to the + /// shared data will be added to ensure the shared data stays around + /// as long as any objects have references to the shared data. The + /// byte order and the address size settings are copied from \a + /// data. If \a offset is not a valid offset in \a data, then no + /// reference to the shared data will be added. If there are not + /// \a length bytes available in \a data starting at \a offset, + /// the length will be truncated to contains as many bytes as + /// possible. + /// + /// @param[in] data + /// Another DataExtractor object that contains data. + /// + /// @param[in] offset + /// The offset into \a data at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of \a data. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + uint32_t + SetData (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT_MAX); + + //------------------------------------------------------------------ + /// Adopt a subset of shared data in \a data_sp. + /// + /// Copies the data shared pointer which adds a reference to the + /// contained in \a data_sp. The shared data reference is reference + /// counted to ensure the data lives as long as anyone still has a + /// valid shared pointer to the data in \a data_sp. The byte order + /// and address byte size settings remain the same. If + /// \a offset is not a valid offset in \a data_sp, then no reference + /// to the shared data will be added. If there are not \a length + /// bytes available in \a data starting at \a offset, the length + /// will be truncated to contains as many bytes as possible. + /// + /// @param[in] data_sp + /// A shared pointer to data. + /// + /// @param[in] offset + /// The offset into \a data_sp at which the subset starts. + /// + /// @param[in] length + /// The length in bytes of the subset of \a data_sp. + /// + /// @return + /// The number of bytes that this object now contains. + //------------------------------------------------------------------ + uint32_t + SetData (lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT_MAX); + + //------------------------------------------------------------------ + /// Set the byte_order value. + /// + /// Sets the byte order of the data to extract. Extracted values + /// will be swapped if necessary when decoding. + /// + /// @param[in] byte_order + /// The byte order value to use when extracting data. + //------------------------------------------------------------------ + void + SetByteOrder (lldb::ByteOrder byte_order); + + //------------------------------------------------------------------ + /// Skip an LEB128 number at \a *offset_ptr. + /// + /// Skips a LEB128 number (signed or unsigned) from this object's + /// data starting at the offset pointed to by \a offset_ptr. The + /// offset pointed to by \a offset_ptr will be updated with the + /// offset of the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + // The number of bytes consumed during the extraction. + //------------------------------------------------------------------ + uint32_t + Skip_LEB128 (uint32_t *offset_ptr) const; + + //------------------------------------------------------------------ + /// Test the validity of \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset into the data in this + /// object, \b false otherwise. + //------------------------------------------------------------------ + bool + ValidOffset (uint32_t offset) const; + + //------------------------------------------------------------------ + /// Test the availability of \a length bytes of data from \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset and there are \a + /// length bytes available at that offset, \b false otherwise. + //------------------------------------------------------------------ + bool + ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const; + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + const uint8_t * m_start; ///< A pointer to the first byte of data. + const uint8_t * m_end; ///< A pointer to the byte that is past the end of the data. + lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from. + uint8_t m_addr_size; ///< The address size to use when extracting pointers or addresses + mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances +}; + +} // namespace lldb_private + +#endif // #if defined (__cplusplus) +#endif // #ifndef liblldb_DataExtractor_h_ diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h new file mode 100644 index 00000000000..c5ae8842362 --- /dev/null +++ b/lldb/include/lldb/Core/Debugger.h @@ -0,0 +1,170 @@ +//===-- Debugger.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Debugger_h_ +#define liblldb_Debugger_h_ +#if defined(__cplusplus) + + +#include <stdint.h> +#include <unistd.h> + +#include <stack> + +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Core/Communication.h" +#include "lldb/Core/Listener.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/SourceManager.h" +#include "lldb/Target/TargetList.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Debugger Debugger.h "lldb/Core/Debugger.h" +/// @brief A class to manage flag bits. +/// +/// Provides a global root objects for the debugger core. +//---------------------------------------------------------------------- +class Debugger +{ +public: + + static void + Initialize (); + + static void + Terminate (); + + static Debugger & + GetSharedInstance (); + + ~Debugger (); + + bool + GetAsyncExecution (); + + void + SetAsyncExecution (bool async); + + void + SetInputFileHandle (FILE *fh, bool tranfer_ownership); + + void + SetOutputFileHandle (FILE *fh, bool tranfer_ownership); + + void + SetErrorFileHandle (FILE *fh, bool tranfer_ownership); + + FILE * + GetInputFileHandle (); + + FILE * + GetOutputFileHandle (); + + FILE * + GetErrorFileHandle (); + + Stream& + GetOutputStream () + { + return m_output_file; + } + + Stream& + GetErrorStream () + { + return m_error_file; + } + + CommandInterpreter & + GetCommandInterpreter (); + + Listener & + GetListener (); + + SourceManager & + GetSourceManager (); + + lldb::TargetSP + GetCurrentTarget (); + + ExecutionContext + GetCurrentExecutionContext(); + //------------------------------------------------------------------ + /// Get accessor for the target list. + /// + /// The target list is part of the global debugger object. This + /// the single debugger shared instance to control where targets + /// get created and to allow for tracking and searching for targets + /// based on certain criteria. + /// + /// @return + /// A global shared target list. + //------------------------------------------------------------------ + TargetList& + GetTargetList (); + + void + DispatchInput (const char *bytes, size_t bytes_len); + + void + WriteToDefaultReader (const char *bytes, size_t bytes_len); + + void + PushInputReader (const lldb::InputReaderSP& reader_sp); + + bool + PopInputReader (const lldb::InputReaderSP& reader_sp); + +protected: + + static void + DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len); + + void + ActivateInputReader (const lldb::InputReaderSP &reader_sp); + + bool + CheckIfTopInputReaderIsDone (); + + void + DisconnectInput(); + + bool m_async_execution; + Communication m_input_comm; + StreamFile m_input_file; + StreamFile m_output_file; + StreamFile m_error_file; + TargetList m_target_list; + Listener m_listener; + SourceManager m_source_manager; + CommandInterpreter m_command_interpreter; + + std::stack<lldb::InputReaderSP> m_input_readers; + std::string m_input_reader_data; + + typedef std::tr1::shared_ptr<Debugger> DebuggerSP; + + static DebuggerSP & + GetDebuggerSP(); + + static int g_shared_debugger_refcount; + static bool g_in_terminate; + +private: + Debugger (); // Access the single global instance of this class using Debugger::GetSharedInstance(); + + DISALLOW_COPY_AND_ASSIGN (Debugger); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Debugger_h_ diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h new file mode 100644 index 00000000000..33d7d561dec --- /dev/null +++ b/lldb/include/lldb/Core/Disassembler.h @@ -0,0 +1,138 @@ +//===-- Disassembler.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Disassembler_h_ +#define liblldb_Disassembler_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +class ExecutionContext; + +class Disassembler : + public PluginInterface +{ +public: + class Instruction + { + public: + typedef lldb::SharedPtr<Instruction>::Type shared_ptr; + + Instruction(); + + virtual + ~Instruction(); + + virtual size_t + GetByteSize() const = 0; + + virtual void + Dump (Stream *s, lldb::addr_t base_address, DataExtractor *bytes, uint32_t bytes_offset, const lldb_private::ExecutionContext exe_ctx, bool raw) = 0; + + virtual bool + DoesBranch () const = 0; + + virtual size_t + Extract (const DataExtractor& data, uint32_t data_offset) = 0; + }; + + + class InstructionList + { + public: + InstructionList(); + ~InstructionList(); + + size_t + GetSize() const; + + Instruction * + GetInstructionAtIndex (uint32_t idx); + + const Instruction * + GetInstructionAtIndex (uint32_t idx) const; + + void + Clear(); + + void + AppendInstruction (Instruction::shared_ptr &inst_sp); + + private: + typedef std::vector<Instruction::shared_ptr> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + collection m_instructions; + }; + + + static Disassembler* + FindPlugin (const ArchSpec &arch); + + static bool + Disassemble (const ArchSpec &arch, + const ExecutionContext &exe_ctx, + uint32_t mixed_context_lines, + Stream &strm); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Disassembler(const ArchSpec &arch); + virtual ~Disassembler(); + + typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data); + + size_t + ParseInstructions (const ExecutionContext *exe_ctx, + lldb::AddressType addr_type, + lldb::addr_t addr, + size_t byte_size, + DataExtractor& data); + + virtual size_t + ParseInstructions (const DataExtractor& data, + uint32_t data_offset, + uint32_t num_instructions, + lldb::addr_t base_addr) = 0; + + InstructionList & + GetInstructionList (); + + const InstructionList & + GetInstructionList () const; + +protected: + //------------------------------------------------------------------ + // Classes that inherit from Disassembler can see and modify these + //------------------------------------------------------------------ + const ArchSpec m_arch; + InstructionList m_instruction_list; + lldb::addr_t m_base_addr; + +private: + //------------------------------------------------------------------ + // For Disassembler only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Disassembler); +}; + +} // namespace lldb_private + +#endif // liblldb_Disassembler_h_ diff --git a/lldb/include/lldb/Core/Error.h b/lldb/include/lldb/Core/Error.h new file mode 100644 index 00000000000..d4b8bab2383 --- /dev/null +++ b/lldb/include/lldb/Core/Error.h @@ -0,0 +1,291 @@ +//===-- Error.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef __DCError_h__ +#define __DCError_h__ +#if defined(__cplusplus) + +#include <mach/mach.h> +#include <stdint.h> +#include <stdio.h> +#include <string> + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class Log; + +//---------------------------------------------------------------------- +/// @class Error Error.h "lldb/Core/Error.h" +/// @brief An error handling class. +/// +/// This class is designed to be able to hold any error code that can be +/// encountered on a given platform. The errors are stored as a value +/// of type Error::ValueType. This value should be large enough to hold +/// any and all errors that the class supports. Each error has an +/// associated type that is of type lldb::ErrorType. New types +/// can be added to support new error types, and architecture specific +/// types can be enabled. In the future we may wish to switch to a +/// registration mechanism where new error types can be registered at +/// runtime instead of a hard coded scheme. +/// +/// All errors in this class also know how to generate a string +/// representation of themselves for printing results and error codes. +/// The string value will be fetched on demand and its string value will +/// be cached until the error is cleared of the value of the error +/// changes. +//---------------------------------------------------------------------- +class Error +{ +public: + //------------------------------------------------------------------ + /// Every error value that this object can contain needs to be able + /// to fit into ValueType. + //------------------------------------------------------------------ + typedef uint32_t ValueType; + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize the error object with a generic success value. + /// + /// @param[in] err + /// An error code. + /// + /// @param[in] type + /// The type for \a err. + //------------------------------------------------------------------ + explicit + Error (ValueType err = 0, lldb::ErrorType type = lldb::eErrorTypeGeneric); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// @param[in] err + /// An error code. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const Error& + operator = (const Error& rhs); + + + //------------------------------------------------------------------ + /// Assignment operator from a kern_return_t. + /// + /// Sets the type to \c MachKernel and the error code to \a err. + /// + /// @param[in] err + /// A mach error code. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const Error& + operator = (kern_return_t err); + + ~Error(); + + //------------------------------------------------------------------ + /// Get the error string associated with the current error. + // + /// Gets the error value as a NULL terminated C string. The error + /// string will be fetched and cached on demand. The error string + /// will be retrieved from a callback that is appropriate for the + /// type of the error and will be cached until the error value is + /// changed or cleared. + /// + /// @return + /// The error as a NULL terminated C string value if the error + /// is valid and is able to be converted to a string value, + /// NULL otherwise. + //------------------------------------------------------------------ + const char * + AsCString (const char *default_error_str = "unknown error") const; + + //------------------------------------------------------------------ + /// Clear the object state. + /// + /// Reverts the state of this object to contain a generic success + /// value and frees any cached error string value. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Test for error condition. + /// + /// @return + /// \b true if this object contains an error, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + Fail () const; + + //------------------------------------------------------------------ + /// Access the error value. + /// + /// @return + /// The error value. + //------------------------------------------------------------------ + ValueType + GetError () const; + + //------------------------------------------------------------------ + /// Access the error type. + /// + /// @return + /// The error type enumeration value. + //------------------------------------------------------------------ + lldb::ErrorType + GetType () const; + + //------------------------------------------------------------------ + /// Log an error to Log(). + /// + /// Log the error given a formatted string \a format. If the this + /// object contains an error code, update the error string to + /// contain the prefix "error: ", followed by the formatted string, + /// followed by the error value and any string that describes the + /// error value. This allows more context to be given to an error + /// string that remains cached in this object. Logging always occurs + /// even when the error code contains a non-error value. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Variable arguments that are needed for the printf style + /// format string \a format. + //------------------------------------------------------------------ + void + PutToLog (Log *log, const char *format, ...); + + //------------------------------------------------------------------ + /// Log an error to Log() if the error value is an error. + /// + /// Log the error given a formatted string \a format only if the + /// error value in this object describes an error condition. If the + /// this object contains an error, update the error string to + /// contain the prefix "error: " followed by the formatted string, + /// followed by the error value and any string that describes the + /// error value. This allows more context to be given to an error + /// string that remains cached in this object. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Variable arguments that are needed for the printf style + /// format string \a format. + //------------------------------------------------------------------ + void + LogIfError (Log *log, const char *format, ...); + + //------------------------------------------------------------------ + /// Set accessor from a kern_return_t. + /// + /// Set accesssor for the error value to \a err and the error type + /// to \c MachKernel. + /// + /// @param[in] err + /// A mach error code. + //------------------------------------------------------------------ + void + SetError (kern_return_t err); + + //------------------------------------------------------------------ + /// Set accesssor with an error value and type. + /// + /// Set accesssor for the error value to \a err and the error type + /// to \a type. + /// + /// @param[in] err + /// A mach error code. + /// + /// @param[in] type + /// The type for \a err. + //------------------------------------------------------------------ + void + SetError (ValueType err, lldb::ErrorType type); + + //------------------------------------------------------------------ + /// Set the current error to errno. + /// + /// Update the error value to be \c errno and update the type to + /// be \c Error::POSIX. + //------------------------------------------------------------------ + void + SetErrorToErrno (); + + //------------------------------------------------------------------ + /// Set the current error to a generic error. + /// + /// Update the error value to be \c LLDB_GENERIC_ERROR and update the + /// type to be \c Error::Generic. + //------------------------------------------------------------------ + void + SetErrorToGenericError (); + + //------------------------------------------------------------------ + /// Set the current error string to \a err_str. + /// + /// Set accessor for the error string value for a generic errors, + /// or to supply additional details above and beyond the standard + /// error strings that the standard type callbacks typically + /// provide. This allows custom strings to be supplied as an + /// error explanation. The error string value will remain until the + /// error value is cleared or a new error value/type is assigned. + /// + /// @param err_str + /// The new custom error string to copy and cache. + //------------------------------------------------------------------ + void + SetErrorString (const char *err_str); + + //------------------------------------------------------------------ + /// Set the current error string to a formatted error string. + /// + /// @param format + /// A printf style format string + //------------------------------------------------------------------ + int + SetErrorStringWithFormat (const char *format, ...); + + int + SetErrorStringWithVarArg (const char *format, va_list args); + + //------------------------------------------------------------------ + /// Test for success condition. + /// + /// Returns true if the error code in this object is considered a + /// successful return value. + /// + /// @return + /// \b true if this object contains an value that describes + /// success (non-erro), \b false otherwise. + //------------------------------------------------------------------ + bool + Success () const; + +protected: + //------------------------------------------------------------------ + /// Member variables + //------------------------------------------------------------------ + ValueType m_code; ///< Error code as an integer value. + lldb::ErrorType m_type; ///< The type of the above error code. + mutable std::string m_string; ///< A string representation of the error code. +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef __DCError_h__ diff --git a/lldb/include/lldb/Core/Event.h b/lldb/include/lldb/Core/Event.h new file mode 100644 index 00000000000..66c5fbd7afa --- /dev/null +++ b/lldb/include/lldb/Core/Event.h @@ -0,0 +1,180 @@ +//===-- Event.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Event_h_ +#define liblldb_Event_h_ + +// C Includes +// C++ Includes +#include <list> +#include <string> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Host/Predicate.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// lldb::EventData +//---------------------------------------------------------------------- +class EventData +{ + friend class Event; + +public: + EventData (); + + virtual + ~EventData(); + + virtual const ConstString & + GetFlavor () const = 0; + + virtual void + Dump (Stream *s) const; + +private: + virtual void + DoOnRemoval (Event *event_ptr) + { + } + + DISALLOW_COPY_AND_ASSIGN (EventData); + +}; + +//---------------------------------------------------------------------- +// lldb::EventDataBytes +//---------------------------------------------------------------------- +class EventDataBytes : public EventData +{ +public: + //------------------------------------------------------------------ + // Constructors + //------------------------------------------------------------------ + EventDataBytes (); + + EventDataBytes (const char *cstr); + + EventDataBytes (const void *src, size_t src_len); + + virtual + ~EventDataBytes(); + + //------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------ + virtual const ConstString & + GetFlavor () const; + + virtual void + Dump (Stream *s) const; + + const void * + GetBytes() const; + + size_t + GetByteSize() const; + + void + SetBytes (const void *src, size_t src_len); + + void + SetBytesFromCString (const char *cstr); + + //------------------------------------------------------------------ + // Static functions + //------------------------------------------------------------------ + static const EventDataBytes * + GetEventDataFromEvent (const Event *event_ptr); + + static const void * + GetBytesFromEvent (const Event *event_ptr); + + static size_t + GetByteSizeFromEvent (const Event *event_ptr); + + static const ConstString & + GetFlavorString (); + +private: + std::string m_bytes; + + DISALLOW_COPY_AND_ASSIGN (EventDataBytes); + +}; + +//---------------------------------------------------------------------- +// lldb::Event +//---------------------------------------------------------------------- +class Event +{ + friend class Broadcaster; + friend class Listener; + friend class EventData; + +public: + + Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data = NULL); + + Event (uint32_t event_type, EventData *data = NULL); + + ~Event (); + + void + Dump (Stream *s) const; + + EventData * + GetData (); + + const EventData * + GetData () const; + + uint32_t + GetType () const; + + Broadcaster * + GetBroadcaster () const; + + bool + BroadcasterIs (Broadcaster *broadcaster); + + void + Clear(); + + +private: + // This is only called by Listener when it pops an event off the queue for + // the listener. It calls the Event Data's DoOnRemoval() method, which is + // virtual and can be overridden by the specific data classes. + + void + DoOnRemoval (); + + // Called by Broadcaster::BroadcastEvent prior to letting all the listeners + // know about it update the contained broadcaster so that events can be + // popped off one queue and re-broadcast to others. + void + SetBroadcaster (Broadcaster *broadcaster); + + Broadcaster * m_broadcaster; // The broadcaster that sent this event + uint32_t m_type; // The bit describing this event + std::auto_ptr<EventData> m_data_ap; // User specific data for this event + + + DISALLOW_COPY_AND_ASSIGN (Event); + Event(); // Disallow default constructor +}; + +} // namespace lldb_private + +#endif // liblldb_Event_h_ diff --git a/lldb/include/lldb/Core/FileSpec.h b/lldb/include/lldb/Core/FileSpec.h new file mode 100644 index 00000000000..4aa17826c2b --- /dev/null +++ b/lldb/include/lldb/Core/FileSpec.h @@ -0,0 +1,440 @@ +//===-- FileSpec.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_FileSpec_h_ +#define liblldb_FileSpec_h_ +#if defined(__cplusplus) + +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/STLUtils.h" +#include "lldb/Host/TimeValue.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class FileSpec FileSpec.h "lldb/Core/FileSpec.h" +/// @brief A file utility class. +/// +/// A file specification class that divides paths up into a directory +/// and filename. These string values of the paths are put into uniqued +/// string pools for fast comparisons and efficient memory usage. +//---------------------------------------------------------------------- +class FileSpec +{ +public: + typedef enum FileType + { + eFileTypeInvalid = -1, + eFileTypeUknown = 0, + eFileTypeDirectory, + eFileTypePipe, + eFileTypeRegular, + eFileTypeSocket, + eFileTypeSymbolicLink, + }; + + FileSpec(); + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Takes an optional full path to a file. If \a path is valid, + /// this function will call FileSpec::SetFile (\a path). + /// + /// @param[in] path + /// The full or partial path to a file. + /// + /// @see FileSpec::SetFile () + //------------------------------------------------------------------ + explicit FileSpec (const char *path); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Makes a copy of the uniqued directory and filename strings from + /// \a rhs. + /// + /// @param[in] rhs + /// A const FileSpec object reference to copy. + //------------------------------------------------------------------ + FileSpec (const FileSpec& rhs); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Makes a copy of the uniqued directory and filename strings from + /// \a rhs if it is not NULL. + /// + /// @param[in] rhs + /// A const FileSpec object pointer to copy if non-NULL. + //------------------------------------------------------------------ + FileSpec (const FileSpec* rhs); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //------------------------------------------------------------------ + virtual + ~FileSpec (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Makes a copy of the uniqued directory and filename strings from + /// \a rhs. + /// + /// @param[in] rhs + /// A const FileSpec object reference to assign to this object. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const FileSpec& + operator= (const FileSpec& rhs); + + //------------------------------------------------------------------ + /// Equal to operator + /// + /// Tests if this object is equal to \a rhs. + /// + /// @param[in] rhs + /// A const FileSpec object reference to compare this object + /// to. + /// + /// @return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + operator== (const FileSpec& rhs) const; + + //------------------------------------------------------------------ + /// Not equal to operator + /// + /// Tests if this object is not equal to \a rhs. + /// + /// @param[in] rhs + /// A const FileSpec object reference to compare this object + /// to. + /// + /// @return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + operator!= (const FileSpec& rhs) const; + + //------------------------------------------------------------------ + /// Less than to operator + /// + /// Tests if this object is less than \a rhs. + /// + /// @param[in] rhs + /// A const FileSpec object reference to compare this object + /// to. + /// + /// @return + /// \b true if this object is less than \a rhs, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + operator< (const FileSpec& rhs) const; + + //------------------------------------------------------------------ + /// Convert to pointer operator. + /// + /// This allows code to check a FileSpec object to see if it + /// contains anything valid using code such as: + /// + /// @code + /// FileSpec file_spec(...); + /// if (file_spec) + /// { ... + /// @endcode + /// + /// @return + /// A pointer to this object if either the directory or filename + /// is valid, NULL otherwise. + //------------------------------------------------------------------ + operator + void* () const; + + //------------------------------------------------------------------ + /// Logical NOT operator. + /// + /// This allows code to check a FileSpec object to see if it is + /// invalid using code such as: + /// + /// @code + /// FileSpec file_spec(...); + /// if (!file_spec) + /// { ... + /// @endcode + /// + /// @return + /// Returns \b true if the object has an empty directory and + /// filename, \b false otherwise. + //------------------------------------------------------------------ + bool + operator! () const; + + //------------------------------------------------------------------ + /// Clears the object state. + /// + /// Clear this object by releasing both the directory and filename + /// string values and reverting them to empty strings. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Compare two FileSpec objects. + /// + /// If \a full is true, then both the directory and the filename + /// must match. If \a full is false, then the directory names for + /// \a lhs and \a rhs are only compared if they are both not empty. + /// This allows a FileSpec object to only contain a filename + /// and it can match FileSpec objects that have matching + /// filenames with different paths. + /// + /// @param[in] lhs + /// A const reference to the Left Hand Side object to compare. + /// + /// @param[in] rhs + /// A const reference to the Right Hand Side object to compare. + /// + /// @param[in] full + /// If true, then both the directory and filenames will have to + /// match for a compare to return zero (equal to). If false + /// and either directory from \a lhs or \a rhs is empty, then + /// only the filename will be compared, else a full comparison + /// is done. + /// + /// @return + /// @li -1 if \a lhs is less than \a rhs + /// @li 0 if \a lhs is equal to \a rhs + /// @li 1 if \a lhs is greater than \a rhs + //------------------------------------------------------------------ + static int + Compare (const FileSpec& lhs, const FileSpec& rhs, bool full); + + static bool + Equal (const FileSpec& a, const FileSpec& b, bool full); + + //------------------------------------------------------------------ + /// Dump this object to a Stream. + /// + /// Dump the object to the supplied stream \a s. If the object + /// contains a valid directory name, it will be displayed followed + /// by a directory delimiter, and the filename. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Existence test. + /// + /// @return + /// \b true if the file exists on disk, \b false otherwise. + //------------------------------------------------------------------ + bool + Exists () const; + + uint64_t + GetByteSize() const; + + //------------------------------------------------------------------ + /// Directory string get accessor. + /// + /// @return + /// A reference to the directory string object. + //------------------------------------------------------------------ + ConstString & + GetDirectory (); + + //------------------------------------------------------------------ + /// Directory string const get accessor. + /// + /// @return + /// A const reference to the directory string object. + //------------------------------------------------------------------ + const ConstString & + GetDirectory () const; + + //------------------------------------------------------------------ + /// Filename string get accessor. + /// + /// @return + /// A reference to the filename string object. + //------------------------------------------------------------------ + ConstString & + GetFilename (); + + //------------------------------------------------------------------ + /// Filename string const get accessor. + /// + /// @return + /// A const reference to the filename string object. + //------------------------------------------------------------------ + const ConstString & + GetFilename () const; + + TimeValue + GetModificationTime () const; + + //------------------------------------------------------------------ + /// Extract the full path to the file. + /// + /// Extract the directory and path into a fixed buffer. This is + /// needed as the directory and path are stored in separate string + /// values. + /// + /// @param[out] path + /// The buffer in which to place the extracted full path. + /// + /// @param[in] max_path_length + /// The maximum length or \a path. + /// + /// @return + /// \b true if the extracted fullpath fits into \a path, \b + /// false otherwise. + //------------------------------------------------------------------ + bool + GetPath (char *path, size_t max_path_length) const; + + FileType + GetFileType () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Return the size in bytes that this object takes in memory. This + /// returns the size in bytes of this object, not any shared string + /// values it may refer to. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Memory map part of, or the entire contents of, a file. + /// + /// Returns a shared pointer to a data buffer that contains all or + /// part of the contents of a file. The data is memory mapped and + /// will lazily page in data from the file as memory is accessed. + /// The data that is mappped will start \a offset bytes into the + /// file, and \a length bytes will be mapped. If \a length is + /// greater than the number of bytes available in the file starting + /// at \a offset, the number of bytes will be appropriately + /// truncated. The final number of bytes that get mapped can be + /// verified using the DataBuffer::GetByteSize() function on the return + /// shared data pointer object contents. + /// + /// @param[in] offset + /// The offset in bytes from the beginning of the file where + /// memory mapping should begin. + /// + /// @param[in] length + /// The size in bytes that should be mapped starting \a offset + /// bytes into the file. If \a length is \c SIZE_T_MAX, map + /// as many bytes as possible. + /// + /// @return + /// A shared pointer to the memeory mapped data. This shared + /// pointer can contain a NULL DataBuffer pointer, so the contained + /// pointer must be checked prior to using it. + //------------------------------------------------------------------ + lldb::DataBufferSP + MemoryMapFileContents (off_t offset = 0, size_t length = SIZE_T_MAX) const; + + //------------------------------------------------------------------ + /// Read part of, or the entire contents of, a file into a heap based data buffer. + /// + /// Returns a shared pointer to a data buffer that contains all or + /// part of the contents of a file. The data copies into a heap based + /// buffer that lives in the DataBuffer shared pointer object returned. + /// The data that is cached will start \a offset bytes into the + /// file, and \a length bytes will be mapped. If \a length is + /// greater than the number of bytes available in the file starting + /// at \a offset, the number of bytes will be appropriately + /// truncated. The final number of bytes that get mapped can be + /// verified using the DataBuffer::GetByteSize() function. + /// + /// @param[in] offset + /// The offset in bytes from the beginning of the file where + /// memory mapping should begin. + /// + /// @param[in] length + /// The size in bytes that should be mapped starting \a offset + /// bytes into the file. If \a length is \c SIZE_T_MAX, map + /// as many bytes as possible. + /// + /// @return + /// A shared pointer to the memeory mapped data. This shared + /// pointer can contain a NULL DataBuffer pointer, so the contained + /// pointer must be checked prior to using it. + //------------------------------------------------------------------ + lldb::DataBufferSP + ReadFileContents (off_t offset = 0, size_t length = SIZE_T_MAX) const; + + //------------------------------------------------------------------ + /// Change the file specificed with a new path. + /// + /// Update the contents of this object with a new path. The path will + /// be split up into a directory and filename and stored as uniqued + /// string values for quick comparison and efficient memory usage. + /// + /// @param[in] path + /// A full, partial, or relative path to a file. + //------------------------------------------------------------------ + void + SetFile (const char *path); + + //------------------------------------------------------------------ + /// Read the file into an array of strings, one per line. + /// + /// Opens and reads the file in this object into an array of strings, + /// one string per line of the file. Returns a boolean indicating + /// success or failure. + /// + /// @param[out] lines + /// The string array into which to read the file. + //------------------------------------------------------------------ + bool + ReadFileLines (STLStringArray &lines); + + static int + Resolve (const char *src_path, char *dst_path, size_t dst_len); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + ConstString m_directory; ///< The uniqued directory path + ConstString m_filename; ///< The uniqued filename path +}; + +//---------------------------------------------------------------------- +/// Dump a FileSpec object to a stream +//---------------------------------------------------------------------- +Stream& operator << (Stream& s, const FileSpec& f); + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_FileSpec_h_ diff --git a/lldb/include/lldb/Core/FileSpecList.h b/lldb/include/lldb/Core/FileSpecList.h new file mode 100644 index 00000000000..c573bf847bc --- /dev/null +++ b/lldb/include/lldb/Core/FileSpecList.h @@ -0,0 +1,196 @@ +//===-- FileSpecList.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_FileSpecList_h_ +#define liblldb_FileSpecList_h_ +#if defined(__cplusplus) + +#include "lldb/lldb-private.h" +#include "lldb/Core/FileSpec.h" +#include <vector> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class FileSpecList FileSpecList.h "lldb/Core/FileSpecList.h" +/// @brief A file collection class. +/// +/// A class that contains a mutable list of FileSpec objects. +//---------------------------------------------------------------------- +class FileSpecList +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize this object with an empty file list. + //------------------------------------------------------------------ + FileSpecList (); + + //------------------------------------------------------------------ + /// Copy constructor. + /// + /// Initialize this object with a copy of the file list from \a rhs. + /// + /// @param[in] rhs + /// A const reference to another file list object. + //------------------------------------------------------------------ + FileSpecList (const FileSpecList &rhs); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~FileSpecList (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Replace the file list in this object with the file list from + /// \a rhs. + /// + /// @param[in] rhs + /// A file list object to copy. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const FileSpecList& + operator= (const FileSpecList &rhs); + + //------------------------------------------------------------------ + /// Append a FileSpec object to the list. + /// + /// Appends \a file to the end of the file list. + /// + /// @param[in] file + /// A new file to append to this file list. + //------------------------------------------------------------------ + void + Append (const FileSpec &file); + + //------------------------------------------------------------------ + /// Append a FileSpec object if unique. + /// + /// Appends \a file to the end of the file list if it doesn't + /// already exist in the file list. + /// + /// @param[in] file + /// A new file to append to this file list. + /// + /// @return + /// \b true if the file was appended, \b false otherwise. + //------------------------------------------------------------------ + bool + AppendIfUnique (const FileSpec &file); + + //------------------------------------------------------------------ + /// Clears the file list. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Dumps the file list to the supplied stream pointer "s". + /// + /// @param[in] s + /// The stream that will be used to dump the object description. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Find a file index. + /// + /// Find the index of the file in the file spec list that matches + /// \a file starting \a idx entries into the file spec list. + /// + /// @param[in] idx + /// An index into the file list. + /// + /// @param[in] file + /// The file specification to search for. + /// + /// @return + /// The index of the file that matches \a file if it is found, + /// else UINT32_MAX is returned. + //------------------------------------------------------------------ + uint32_t + FindFileIndex (uint32_t idx, const FileSpec &file) const; + + //------------------------------------------------------------------ + /// Get file at index. + /// + /// Gets a file from the file list. If \a idx is not a valid index, + /// an empty FileSpec object will be returned. The file objects + /// that are returned can be tested using + /// FileSpec::operator void*(). + /// + /// @param[in] idx + /// An index into the file list. + /// + /// @return + /// A copy of the FileSpec object at index \a idx. If \a idx + /// is out of range, then an empty FileSpec object will be + /// returned. + //------------------------------------------------------------------ + const FileSpec & + GetFileSpecAtIndex (uint32_t idx) const; + + //------------------------------------------------------------------ + /// Get file specification pointer at index. + /// + /// Gets a file from the file list. The file objects that are + /// returned can be tested using FileSpec::operator void*(). + /// + /// @param[in] idx + /// An index into the file list. + /// + /// @return + /// A pointer to a contained FileSpec object at index \a idx. + /// If \a idx is out of range, then an NULL is returned. + //------------------------------------------------------------------ + const FileSpec * + GetFileSpecPointerAtIndex (uint32_t idx) const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Return the size in bytes that this object takes in memory. This + /// returns the size in bytes of this object, not any shared string + /// values it may refer to. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Get the number of files in the file list. + /// + /// @return + /// The number of files in the file spec list. + //------------------------------------------------------------------ + uint32_t + GetSize () const; + + static size_t GetFilesMatchingPartialPath (const char *path, bool dir_okay, FileSpecList &matches); + +protected: + typedef std::vector<FileSpec> collection; ///< The collection type for the file list. + collection m_files; ///< A collection of FileSpec objects. +}; + +} // namespace lldb_private + + +#endif // #if defined(__cplusplus) +#endif // liblldb_FileSpecList_h_ diff --git a/lldb/include/lldb/Core/Flags.h b/lldb/include/lldb/Core/Flags.h new file mode 100644 index 00000000000..92452f3dfd0 --- /dev/null +++ b/lldb/include/lldb/Core/Flags.h @@ -0,0 +1,153 @@ +//===-- Flags.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Flags_h_ +#define liblldb_Flags_h_ +#if defined(__cplusplus) + + +#include <stdint.h> +#include <unistd.h> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Flags Flags.h "lldb/Core/Flags.h" +/// @brief A class to manage flag bits. +/// +/// The Flags class does bits. +//---------------------------------------------------------------------- +class Flags +{ +public: + //---------------------------------------------------------------------- + /// The value type for flag bits is a 32 bit unsigned integer type. + //---------------------------------------------------------------------- + typedef uint32_t ValueType; + + //---------------------------------------------------------------------- + /// Construct with initial flag bit values. + /// + /// Constructs this object with \a bits as the initial value for all + /// of the flag bits. + /// + /// @param[in] bits + /// The initial value for all flag bits. + //---------------------------------------------------------------------- + Flags (ValueType bits = 0); + + //---------------------------------------------------------------------- + /// Copy constructor. + /// + /// Construct and copy the flag bits from \a rhs. + /// + /// @param[in] rhs + /// A const Flags object reference to copy. + //---------------------------------------------------------------------- + Flags (const Flags& rhs); + + //---------------------------------------------------------------------- + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //---------------------------------------------------------------------- + virtual + ~Flags (); + + //---------------------------------------------------------------------- + /// Get accessor for all flag bits. + /// + /// @return + /// Returns all of the flag bits as a Flags::ValueType. + //---------------------------------------------------------------------- + ValueType + GetAllFlagBits () const; + + size_t + GetBitSize() const; + + //---------------------------------------------------------------------- + /// Set accessor for all flag bits. + /// + /// @param[in] bits + /// The bits with which to replace all of the current flag bits. + //---------------------------------------------------------------------- + void + SetAllFlagBits (ValueType bits); + + //---------------------------------------------------------------------- + /// Clear one or more flag bits. + /// + /// @param[in] bits + /// A bitfield containing one or more flag bits. + /// + /// @return + /// The new flag bits after clearing all bits from \a bits. + //---------------------------------------------------------------------- + ValueType + Clear (ValueType bits); + + //---------------------------------------------------------------------- + /// Set one or more flag bits. + /// + /// @param[in] bits + /// A bitfield containing one or more flag bits. + /// + /// @return + /// The new flag bits after setting all bits from \a bits. + //---------------------------------------------------------------------- + ValueType + Set (ValueType bits); + + //---------------------------------------------------------------------- + /// Test one or more flag bits. + /// + /// @return + /// \b true if \b any flag bits in \a bits are set, \b false + /// otherwise. + //---------------------------------------------------------------------- + bool + IsSet (ValueType bits) const; + + //---------------------------------------------------------------------- + /// Test one or more flag bits. + /// + /// @return + /// \b true if \b all flag bits in \a bits are clear, \b false + /// otherwise. + //---------------------------------------------------------------------- + bool + IsClear (ValueType bits) const; + + //---------------------------------------------------------------------- + /// Get the number of zero bits in \a m_flags. + /// + /// @return + /// The number of bits that are set to 0 in the current flags. + //---------------------------------------------------------------------- + size_t + ClearCount () const; + + //---------------------------------------------------------------------- + /// Get the number of one bits in \a m_flags. + /// + /// @return + /// The number of bits that are set to 1 in the current flags. + //---------------------------------------------------------------------- + size_t + SetCount () const; + +protected: + ValueType m_flags; ///< The flag bits. +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Flags_h_ diff --git a/lldb/include/lldb/Core/IOStreamMacros.h b/lldb/include/lldb/Core/IOStreamMacros.h new file mode 100644 index 00000000000..cc4eeb0e050 --- /dev/null +++ b/lldb/include/lldb/Core/IOStreamMacros.h @@ -0,0 +1,38 @@ +//===-- IOStreamMacros.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_IOStreamMacros_h_ +#define liblldb_IOStreamMacros_h_ +#if defined(__cplusplus) + +#include <iomanip> + +#define RAW_HEXBASE std::setfill('0') << std::hex << std::right +#define HEXBASE '0' << 'x' << RAW_HEXBASE +#define RAWHEX8(x) RAW_HEXBASE << std::setw(2) << ((uint32_t)(x)) +#define RAWHEX16 RAW_HEXBASE << std::setw(4) +#define RAWHEX32 RAW_HEXBASE << std::setw(8) +#define RAWHEX64 RAW_HEXBASE << std::setw(16) +#define HEX8(x) HEXBASE << std::setw(2) << ((uint32_t)(x)) +#define HEX16 HEXBASE << std::setw(4) +#define HEX32 HEXBASE << std::setw(8) +#define HEX64 HEXBASE << std::setw(16) +#define RAW_HEX(x) RAW_HEXBASE << std::setw(sizeof(x)*2) << (x) +#define HEX(x) HEXBASE << std::setw(sizeof(x)*2) << (x) +#define HEX_SIZE(x, sz) HEXBASE << std::setw((sz)) << (x) +#define STRING_WIDTH(w) std::setfill(' ') << std::setw(w) +#define LEFT_STRING_WIDTH(s, w) std::left << std::setfill(' ') << std::setw(w) << (s) << std::right +#define DECIMAL std::dec << std::setfill(' ') +#define DECIMAL_WIDTH(w) DECIMAL << std::setw(w) +//#define FLOAT(n, d) std::setfill(' ') << std::setw((n)+(d)+1) << std::setprecision(d) << std::showpoint << std::fixed +#define INDENT_WITH_SPACES(iword_idx) std::setfill(' ') << std::setw((iword_idx)) << "" +#define INDENT_WITH_TABS(iword_idx) std::setfill('\t') << std::setw((iword_idx)) << "" + +#endif // #if defined(__cplusplus) +#endif // liblldb_IOStreamMacros_h_ diff --git a/lldb/include/lldb/Core/InputReader.h b/lldb/include/lldb/Core/InputReader.h new file mode 100644 index 00000000000..2d876240c1d --- /dev/null +++ b/lldb/include/lldb/Core/InputReader.h @@ -0,0 +1,114 @@ +//===-- InputReader.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_InputReader_h_ +#define liblldb_InputReader_h_ + +#include <termios.h> + +#include "lldb/lldb-include.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/Core/Debugger.h" + + +namespace lldb_private { + +class InputReader +{ +public: + + typedef size_t (*Callback) (void *baton, + InputReader *reader, + lldb::InputReaderAction notification, + const char *bytes, + size_t bytes_len); + + InputReader (); + + virtual + ~InputReader (); + + virtual Error + Initialize (Callback callback, + void *baton, + lldb::InputReaderGranularity token_size, + const char *end_token, + const char *prompt, + bool echo); + + bool + IsDone () const + { + return m_done; + } + + void + SetIsDone (bool b) + { + m_done = b; + } + + lldb::InputReaderGranularity + GetGranularity () const + { + return m_granularity; + } + + bool + GetEcho () const + { + return m_echo; + } + + // Subclasses _can_ override this function to get input as it comes in + // without any granularity + virtual size_t + HandleRawBytes (const char *bytes, size_t bytes_len); + + FILE * + GetInputFileHandle (); + + FILE * + GetOutputFileHandle (); + + bool + IsActive () const + { + return m_active; + } + + const char * + GetPrompt () const; + + void + RefreshPrompt(); + +protected: + friend class Debugger; + + void + Notify (lldb::InputReaderAction notification); + + Callback m_callback; + void *m_callback_baton; + std::string m_end_token; + std::string m_prompt; + lldb::InputReaderGranularity m_granularity; + bool m_done; + bool m_echo; + bool m_active; + +private: + DISALLOW_COPY_AND_ASSIGN (InputReader); + +}; + +} // namespace lldb_private + +#endif // #ifndef liblldb_InputReader_h_ diff --git a/lldb/include/lldb/Core/Language.h b/lldb/include/lldb/Core/Language.h new file mode 100644 index 00000000000..f086cae3726 --- /dev/null +++ b/lldb/include/lldb/Core/Language.h @@ -0,0 +1,149 @@ +//===-- Language.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Language_h_ +#define liblldb_Language_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Language Language.h "lldb/Core/Language.h" +/// @brief Encapsulates the programming language for an lldb object. +/// +/// Languages are represented by an enumeration value. +/// +/// The enumeration values used when describing the programming language +/// are the same values as the latest DWARF specification. +//---------------------------------------------------------------------- +class Language +{ +public: + + //------------------------------------------------------------------ + /// Programming language type. + /// + /// These enumerations use the same language enumerations as the + /// DWARF specification for ease of use and consistency. + //------------------------------------------------------------------ + typedef enum + { + Unknown = 0x0000, ///< Unknown or invalid language value. + C89 = 0x0001, ///< ISO C:1989. + C = 0x0002, ///< Non-standardized C, such as K&R. + Ada83 = 0x0003, ///< ISO Ada:1983. + C_plus_plus = 0x0004, ///< ISO C++:1998. + Cobol74 = 0x0005, ///< ISO Cobol:1974. + Cobol85 = 0x0006, ///< ISO Cobol:1985. + Fortran77 = 0x0007, ///< ISO Fortran 77. + Fortran90 = 0x0008, ///< ISO Fortran 90. + Pascal83 = 0x0009, ///< ISO Pascal:1983. + Modula2 = 0x000a, ///< ISO Modula-2:1996. + Java = 0x000b, ///< Java. + C99 = 0x000c, ///< ISO C:1999. + Ada95 = 0x000d, ///< ISO Ada:1995. + Fortran95 = 0x000e, ///< ISO Fortran 95. + PLI = 0x000f, ///< ANSI PL/I:1976. + ObjC = 0x0010, ///< Objective-C. + ObjC_plus_plus = 0x0011, ///< Objective-C++. + UPC = 0x0012, ///< Unified Parallel C. + D = 0x0013, ///< D. + Python = 0x0014, ///< Python. + } Type; + + //------------------------------------------------------------------ + /// Construct with optional language enumeration. + //------------------------------------------------------------------ + Language(Language::Type language = Unknown); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //------------------------------------------------------------------ + virtual + ~Language(); + + //------------------------------------------------------------------ + /// Get the language value as a NULL termianted C string. + /// + /// @return + /// The C string representation of the language. The returned + /// string does not need to be freed as it comes from constant + /// strings. NULL can be returned when the language is set to + /// a value that doesn't match of of the Language::Type + /// enumerations. + //------------------------------------------------------------------ + const char * + AsCString (lldb::DescriptionLevel level = lldb::eDescriptionLevelBrief) const; + + void + Clear(); + + void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + + //------------------------------------------------------------------ + /// Dump the language value to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the language description. + //------------------------------------------------------------------ + void + Dump(Stream *s) const; + + //------------------------------------------------------------------ + /// Get accessor for the language. + /// + /// @return + /// The enumeration value that describes the programming + /// language that an object is associated with. + //------------------------------------------------------------------ + Language::Type + GetLanguage() const; + + //------------------------------------------------------------------ + /// Set accessor for the language. + /// + /// @param[in] language + /// The new enumeration value that describes the programming + /// language that an object is associated with. + //------------------------------------------------------------------ + void + SetLanguage(Language::Type language); + + //------------------------------------------------------------------ + /// Set accessor for the language. + /// + /// @param[in] language_cstr + /// The language name as a C string. + //------------------------------------------------------------------ + bool + SetLanguageFromCString(const char *language_cstr); + + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Language::Type m_language; ///< The programming language enumeration value. + ///< The enumeration values are the same as the + ///< latest DWARF specification. +}; + +//-------------------------------------------------------------- +/// Stream the language enumeration as a string object to a +/// Stream. +//-------------------------------------------------------------- +Stream& operator << (Stream& s, const Language& language); + +} // namespace lldb_private + +#endif // liblldb_Language_h_ diff --git a/lldb/include/lldb/Core/Listener.h b/lldb/include/lldb/Core/Listener.h new file mode 100644 index 00000000000..a47e1012239 --- /dev/null +++ b/lldb/include/lldb/Core/Listener.h @@ -0,0 +1,173 @@ +//===-- Listener.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Select_h_ +#define liblldb_Select_h_ + +// C Includes +// C++ Includes +#include <list> +#include <map> +#include <set> +#include <string> + + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Host/Predicate.h" +#include "lldb/Core/Event.h" + +namespace lldb_private { + +class Listener +{ +public: + typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton); + + friend class Broadcaster; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Listener (const char *name); + + ~Listener (); + + void + AddEvent (lldb::EventSP &event); + + void + Clear (); + + uint32_t + StartListeningForEvents (Broadcaster* broadcaster, + uint32_t event_mask); + + uint32_t + StartListeningForEvents (Broadcaster* broadcaster, + uint32_t event_mask, + HandleBroadcastCallback callback, + void *callback_user_data); + + bool + StopListeningForEvents (Broadcaster* broadcaster, + uint32_t event_mask); + + // Returns true if an event was recieved, false if we timed out. + bool + WaitForEvent (const TimeValue *timeout, + lldb::EventSP &event_sp); + + bool + WaitForEventForBroadcaster (const TimeValue *timeout, + Broadcaster *broadcaster, + lldb::EventSP &event_sp); + + bool + WaitForEventForBroadcasterWithType (const TimeValue *timeout, + Broadcaster *broadcaster, + uint32_t event_type_mask, + lldb::EventSP &event_sp); + + Event * + PeekAtNextEvent (); + + Event * + PeekAtNextEventForBroadcaster (Broadcaster *broadcaster); + + Event * + PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, + uint32_t event_type_mask); + + bool + GetNextEvent (lldb::EventSP &event_sp); + + bool + GetNextEventForBroadcaster (Broadcaster *broadcaster, + lldb::EventSP &event_sp); + + bool + GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, + uint32_t event_type_mask, + lldb::EventSP &event_sp); + + size_t + HandleBroadcastEvent (lldb::EventSP &event_sp); + +protected: + + //------------------------------------------------------------------ + // Classes that inherit from Listener can see and modify these + //------------------------------------------------------------------ + struct BroadcasterInfo + { + BroadcasterInfo(uint32_t mask, HandleBroadcastCallback cb = NULL, void *ud = NULL) : + event_mask (mask), + callback (cb), + callback_user_data (ud) + { + } + + uint32_t event_mask; + HandleBroadcastCallback callback; + void *callback_user_data; + }; + + typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection; + typedef std::list<lldb::EventSP> event_collection; + + bool + FindNextEventInternal (Broadcaster *broadcaster, // NULL for any broadcaster + const ConstString *sources, // NULL for any event + uint32_t num_sources, + uint32_t event_type_mask, + lldb::EventSP &event_sp, + bool remove); + + bool + GetNextEventInternal (Broadcaster *broadcaster, // NULL for any broadcaster + const ConstString *sources, // NULL for any event + uint32_t num_sources, + uint32_t event_type_mask, + lldb::EventSP &event_sp); + + bool + WaitForEventsInternal (const TimeValue *timeout, + Broadcaster *broadcaster, // NULL for any broadcaster + const ConstString *sources, // NULL for any event + uint32_t num_sources, + uint32_t event_type_mask, + lldb::EventSP &event_sp); + + std::string m_name; + broadcaster_collection m_broadcasters; + Mutex m_broadcasters_mutex; // Protects m_broadcasters + event_collection m_events; + Mutex m_events_mutex; // Protects m_broadcasters and m_events + Predicate<bool> m_cond_wait; + + void + BroadcasterWillDestruct (Broadcaster *); +private: + +// broadcaster_collection::iterator +// FindBroadcasterWithMask (Broadcaster *broadcaster, +// uint32_t event_mask, +// bool exact); + + //------------------------------------------------------------------ + // For Listener only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Listener); +}; + +} // namespace lldb_private + +#endif // liblldb_Select_h_ diff --git a/lldb/include/lldb/Core/Log.h b/lldb/include/lldb/Core/Log.h new file mode 100644 index 00000000000..78017bb167e --- /dev/null +++ b/lldb/include/lldb/Core/Log.h @@ -0,0 +1,243 @@ +//===-- Log.h ---------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Log_h_ +#define liblldb_Log_h_ + +// C Includes +#include <stdbool.h> +#include <stdint.h> +#include <signal.h> +#include <stdio.h> +#include <sys/syslimits.h> +#include <unistd.h> + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/PluginInterface.h" + +//---------------------------------------------------------------------- +// Logging types +//---------------------------------------------------------------------- +#define LLDB_LOG_FLAG_STDOUT (1u << 0) +#define LLDB_LOG_FLAG_STDERR (1u << 1) +#define LLDB_LOG_FLAG_FATAL (1u << 2) +#define LLDB_LOG_FLAG_ERROR (1u << 3) +#define LLDB_LOG_FLAG_WARNING (1u << 4) +#define LLDB_LOG_FLAG_DEBUG (1u << 5) +#define LLDB_LOG_FLAG_VERBOSE (1u << 6) + +//---------------------------------------------------------------------- +// Logging Options +//---------------------------------------------------------------------- +#define LLDB_LOG_OPTION_THREADSAFE (1u << 0) +#define LLDB_LOG_OPTION_VERBOSE (1u << 1) +#define LLDB_LOG_OPTION_DEBUG (1u << 2) +#define LLDB_LOG_OPTION_PREPEND_SEQUENCE (1u << 3) +#define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4) +#define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5) +#define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6) + +//---------------------------------------------------------------------- +// Logging Functions +//---------------------------------------------------------------------- +namespace lldb_private { + +class Log +{ +public: + + //------------------------------------------------------------------ + // Callback definitions for abstracted plug-in log access. + //------------------------------------------------------------------ + typedef void (*DisableCallback) (); + typedef Log* (*EnableCallback) (lldb::StreamSP &log_stream_sp, + uint32_t log_options, + Args &args, + Stream *feedback_strm); + typedef void (*ListCategoriesCallback) (Stream *strm); + + typedef struct Callbacks + { + DisableCallback disable; + EnableCallback enable; + ListCategoriesCallback list_categories; + }; + + //------------------------------------------------------------------ + // Static accessors for logging channels + //------------------------------------------------------------------ + static void + RegisterLogChannel (const char *channel, + const Log::Callbacks &log_callbacks); + + static bool + UnregisterLogChannel (const char *channel); + + static bool + GetLogChannelCallbacks (const char *channel, + Log::Callbacks &log_callbacks); + + + static void + EnableAllLogChannels (lldb::StreamSP &log_stream_sp, + uint32_t log_options, + Args &args, + Stream *feedback_strm); + + static void + DisableAllLogChannels (); + + static void + ListAllLogChannels (Stream *strm); + + //------------------------------------------------------------------ + // Static accessors to STDOUT logging facilities. + //------------------------------------------------------------------ + static void + STDOUT (const char *format, ...); + + static lldb::StreamSP + GetStreamForSTDOUT (); + + static void + SetStreamForSTDOUT (lldb::StreamSP &stream_sp); + + //------------------------------------------------------------------ + // Static accessors to STDERR logging facilities. + //------------------------------------------------------------------ + static void + STDERR (const char *format, ...); + + static lldb::StreamSP + GetStreamForSTDERR (); + + static void + SetStreamForSTDERR (lldb::StreamSP &stream_sp); + + //------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------ + Log (); + + Log (lldb::StreamSP &stream_sp); + + ~Log (); + + void + PutCString (const char *cstr); + + void + Printf (const char *format, ...); + + void + VAPrintf (const char *format, va_list args); + + void + PrintfWithFlags( uint32_t flags, const char *format, ...); + + void + LogIf (uint32_t mask, const char *fmt, ...); + + void + Debug (const char *fmt, ...); + + void + DebugVerbose (const char *fmt, ...); + + void + Error (const char *fmt, ...); + + void + FatalError (int err, const char *fmt, ...); + + void + Verbose (const char *fmt, ...); + + void + Warning (const char *fmt, ...); + + void + WarningVerbose (const char *fmt, ...); + + Flags & + GetOptions(); + + const Flags & + GetOptions() const; + + Flags & + GetMask(); + + const Flags & + GetMask() const; + + bool + GetVerbose() const; + + bool + GetDebug() const; + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + lldb::StreamSP m_stream_sp; + Flags m_options; + Flags m_mask_bits; + + void + PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args); + +private: + DISALLOW_COPY_AND_ASSIGN (Log); +}; + + +class LogChannel : public PluginInterface +{ +public: + LogChannel (); + + virtual + ~LogChannel (); + + static const char * + GetPluginSuffix (); + + static lldb::LogChannelSP + FindPlugin (const char *plugin_name); + + virtual void + Disable () = 0; + + virtual bool + Enable (lldb::StreamSP &log_stream_sp, + uint32_t log_options, + Stream *feedback_strm, // Feedback stream for argument errors etc + const Args &categories) = 0;// The categories to enable within this logging stream, if empty, enable default set + + virtual void + ListCategories (Stream *strm) = 0; + +protected: + lldb::LogSP m_log_sp; + +private: + DISALLOW_COPY_AND_ASSIGN (LogChannel); +}; + + +} // namespace lldb_private + +#endif // liblldb_Log_H_ diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h new file mode 100644 index 00000000000..bf99022651a --- /dev/null +++ b/lldb/include/lldb/Core/Mangled.h @@ -0,0 +1,485 @@ +//===-- Mangled.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Mangled_h_ +#define liblldb_Mangled_h_ +#if defined(__cplusplus) + + +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include <vector> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Mangled Mangled.h "lldb/Core/Mangled.h" +/// @brief A class that handles mangled names. +/// +/// Designed to handle mangled names. The demangled version of any names +/// will be computed when the demangled name is accessed through the +/// Demangled() acccessor. This class can also tokenize the demangled +/// version of the name for powerful searches. Functions and symbols +/// could make instances of this class for their mangled names. Uniqued +/// string pools are used for the mangled, demangled, and token string +/// values to allow for faster comparisons and for efficient memory use. +//---------------------------------------------------------------------- +class Mangled +{ +public: + + //------------------------------------------------------------------ + /// Token type enumerations. + //------------------------------------------------------------------ + enum TokenType + { + eInvalid, ///< Invalid token value (unitialized value) + eNameSpace, ///< The token is a namespace name. + eMethodName, ///< The token is a global or class method name + eType, ///< The token is a language type + eTemplate, ///< The token is a template class + eTemplateBeg, ///< The token that indicates the start of a template parameters + eTemplateEnd, ///< The token that indicates the end of a template parameters + eParamsBeg, ///< The start of a method's parameters (the open parenthesis) + eParamsEnd, ///< The end of a method's parameters (the open parenthesis) + eQualifier, ///< A language qualifier + eError, ///< The token failed to parse + }; + + //------------------------------------------------------------------ + /// Mangled::Token structure + /// + /// As demangled names get tokenized, they get broken up into chunks + /// that have type enumerations (TokenType) and string values. Some of + /// the tokens are scopes (eTemplateBeg, eTemplateEnd, eParamsBeg, + /// eParamsEnd) that can indicate depth and searches can take + /// advantage of these to match using wildcards. + /// + /// For example the mangled string: + /// + /// "_ZNSbIhSt11char_traitsIhESaIhEE5eraseEmm" + /// + /// Demangles to: + /// + /// "std::basic_string<unsigned char, std::char_traits<unsigned char>, std::allocator<unsigned char> >::erase(unsigned long, unsigned long)" + /// + /// And tokenizes to: + /// @li eNameSpace ("std") + /// @li eTemplate ("basic_string") + /// @li eTemplateBeg () + /// @li eType ("unsigned char") + /// @li eNameSpace ("std") + /// @li eTemplate ("char_traits") + /// @li eTemplateBeg () + /// @li eType ("unsigned char") + /// @li eTemplateEnd () + /// @li eNameSpace ("std") + /// @li eTemplate ("allocator") + /// @li eTemplateBeg () + /// @li eType ("unsigned char" + /// @li eTemplateEnd () + /// @li eTemplateEnd () + /// @li eMethodName ("erase") + /// @li eParamsBeg () + /// @li eType ("unsigned long") + /// @li eType ("unsigned long") + /// @li eParamsEnd () + ///------------------------------------------------------------------ + struct Token + { + //-------------------------------------------------------------- + /// Default constructor. + /// + /// Constructs this objet with an invalid token type and an + /// empty string. + //-------------------------------------------------------------- + Token(); + + //-------------------------------------------------------------- + /// Equal to operator. + /// + /// Tests if this object is equal to \a rhs. + /// + /// @param[in] rhs + /// A const Mangled::Token object reference to compare + /// this object to. + /// + /// @return + /// \b true if this object is equal to \a rhs, \b false + /// otherwise. + //-------------------------------------------------------------- + bool + operator== (const Token& rhs) const; + + //-------------------------------------------------------------- + /// Dump a description of this object to a Stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //-------------------------------------------------------------- + void + Dump (Stream *s) const; + + //-------------------------------------------------------------- + /// Test if this token is a wildcard token. + /// + /// @return + /// Returns \b true if this token is a wildcard, \b false + /// otherwise. + //-------------------------------------------------------------- + bool + IsWildcard() const; + + //-------------------------------------------------------------- + /// Members + //-------------------------------------------------------------- + TokenType type; ///< The type of the token (Mangled::TokenType) + ConstString value; ///< The ConstString value associated with this token + }; + + //------------------------------------------------------------------ + /// A collection of tokens. + /// + /// This class can be instantiated with a demangled names that can + /// be used as a query using the + /// Mangled::TokenList::MatchesQuery(const TokenList&) const + /// function. + //------------------------------------------------------------------ + class TokenList + { + public: + //-------------------------------------------------------------- + /// Construct with a demangled name. + /// + /// If demangled is valid the token list will parse up the + /// demangled string it is given, else the object will + /// initialize an empty token list. + //-------------------------------------------------------------- + TokenList (const char *demangled = NULL); + + //-------------------------------------------------------------- + /// Destructor + //-------------------------------------------------------------- + ~TokenList (); + + //-------------------------------------------------------------- + /// Clear the token list. + //-------------------------------------------------------------- + void + Clear (); + + //-------------------------------------------------------------- + /// Dump a description of this object to a Stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //-------------------------------------------------------------- + void + Dump (Stream *s) const; + + //-------------------------------------------------------------- + /// Find a token by Mangled::TokenType. + /// + /// Find the first token in the list that has \a token_type as + /// its type. + //-------------------------------------------------------------- + const Token* + Find (TokenType token_type) const; + + //-------------------------------------------------------------- + /// Get a token by index. + /// + /// @return + /// The token at index \a idx, or NULL if the index is out + /// of range. + //-------------------------------------------------------------- + const Token* + GetTokenAtIndex (uint32_t idx) const; + + //-------------------------------------------------------------- + /// Given a token list, see if it matches this object's tokens. + /// \a token_list can contain wild card values to enable powerful + /// matching. Matching the std::string::erase(*) example that was + /// tokenized above we could use a token list such as: + /// + /// token name + /// ----------- ---------------------------------------- + /// eNameSpace "std" + /// eTemplate "basic_string" + /// eTemplateBeg + /// eInvalid "*" + /// eTemplateEnd + /// eMethodName "erase" + /// eParamsBeg + /// eInvalid "*" + /// eParamsEnd + /// + /// @return + /// Returns \b true if it \a token_list matches this + /// object's tokens, \b false otherwise. + //-------------------------------------------------------------- + bool + MatchesQuery (const TokenList& token_list) const; + + //-------------------------------------------------------------- + /// Parses \a demangled into tokens. + /// + /// This allows complex comparisons to be done on demangled names. Comparisons can + /// include wildcards at the namespace, method name, template, + /// and template and parameter type levels. + /// + /// Example queries include: + /// "std::basic_string<*>" // Find all std::basic_string variants + /// "std::basic_string<*>::erase(*)" // Find all std::basic_string::erase variants with any number of parameters + /// "*::clear()" // Find all functions with a method name of + /// // "clear" that are in any namespace that + /// // have no parameters + /// "::printf" // Find the printf function in the global namespace + /// "printf" // Ditto + /// "foo::*(int)" // Find all functions in the class or namespace "foo" that take a single integer argument + /// + /// @return + /// The number of tokens that were decoded, or zero if + /// decoding fails. + //-------------------------------------------------------------- + size_t + Parse (const char *demangled); + + //-------------------------------------------------------------- + /// Get the number of tokens in the list. + /// + /// @return + /// The number of tokens in the token list. + //-------------------------------------------------------------- + size_t + Size () const; + + protected: + //-------------------------------------------------------------- + // Member variables. + //-------------------------------------------------------------- + typedef std::vector<Token> collection; ///< The collection type for a list of Token objects. + collection m_tokens; ///< The token list. + private: + DISALLOW_COPY_AND_ASSIGN (TokenList); + }; + + //---------------------------------------------------------------------- + /// Default constructor. + /// + /// Initialize with both mangled and demangled names empty. + //---------------------------------------------------------------------- + Mangled (); + + //---------------------------------------------------------------------- + /// Construct with name. + /// + /// Constructor with an optional string and a boolean indicating if it is + /// the mangled version. + /// + /// @param[in] name + /// The name to copy into this object. + /// + /// @param[in] is_mangled + /// If \b true then \a name is a mangled name, if \b false then + /// \a name is demangled. + //---------------------------------------------------------------------- + explicit + Mangled (const char *name, bool is_mangled); + + //---------------------------------------------------------------------- + /// Destructor + /// + /// Releases its ref counts on the mangled and demangled strings that + /// live in the global string pool. + //---------------------------------------------------------------------- + ~Mangled (); + + //---------------------------------------------------------------------- + /// Convert to pointer operator. + /// + /// This allows code to check a Mangled object to see if it contains + /// a valid mangled name using code such as: + /// + /// @code + /// Mangled mangled(...); + /// if (mangled) + /// { ... + /// @endcode + /// + /// @return + /// A pointer to this object if either the mangled or unmangled + /// name is set, NULL otherwise. + //---------------------------------------------------------------------- + operator + void*() const; + + //---------------------------------------------------------------------- + /// Logical NOT operator. + /// + /// This allows code to check a Mangled object to see if it contains + /// an empty mangled name using code such as: + /// + /// @code + /// Mangled mangled(...); + /// if (!mangled) + /// { ... + /// @endcode + /// + /// @return + /// Returns \b true if the object has an empty mangled and + /// unmangled name, \b false otherwise. + //---------------------------------------------------------------------- + bool + operator!() const; + + //---------------------------------------------------------------------- + /// Clear the mangled and demangled values. + //---------------------------------------------------------------------- + void + Clear (); + + //---------------------------------------------------------------------- + /// Compare the mangled string values + /// + /// Compares the Mangled::GetName() string in \a lhs and \a rhs. + /// + /// @param[in] lhs + /// A const reference to the Left Hand Side object to compare. + /// + /// @param[in] rhs + /// A const reference to the Right Hand Side object to compare. + /// + /// @return + /// @li -1 if \a lhs is less than \a rhs + /// @li 0 if \a lhs is equal to \a rhs + /// @li 1 if \a lhs is greater than \a rhs + //---------------------------------------------------------------------- + static int + Compare (const Mangled& lhs, const Mangled& rhs); + + //---------------------------------------------------------------------- + /// Dump a description of this object to a Stream \a s. + /// + /// Dump a Mangled object to stream \a s. We don't force our + /// demangled name to be computed currently (we don't use the accessor). + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //---------------------------------------------------------------------- + void + Dump (Stream *s) const; + + //---------------------------------------------------------------------- + /// Dump a debug description of this object to a Stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //---------------------------------------------------------------------- + void + DumpDebug (Stream *s) const; + + //---------------------------------------------------------------------- + /// Demangled name get accessor. + /// + /// @return + /// A const reference to the demangled name string object. + //---------------------------------------------------------------------- + const ConstString& + GetDemangledName () const; + + //---------------------------------------------------------------------- + /// Mangled name get accessor. + /// + /// @return + /// A reference to the mangled name string object. + //---------------------------------------------------------------------- + ConstString& + GetMangledName (); + + //---------------------------------------------------------------------- + /// Mangled name get accessor. + /// + /// @return + /// A const reference to the mangled name string object. + //---------------------------------------------------------------------- + const ConstString& + GetMangledName () const; + + //---------------------------------------------------------------------- + /// Best name get accessor. + /// + /// @return + /// A const reference to the the mangled name string object if this + /// object has a valid mangled name, else a const reference to the + /// demangled name is returned. + //---------------------------------------------------------------------- + const ConstString& + GetName () const; + + //---------------------------------------------------------------------- + /// Generate the tokens from the demangled name. + /// + /// @param[out] tokens + /// A token list that will get filled in with the demangled tokens. + /// + /// @return + /// The number of tokens that were parsed and stored in \a tokens. + //---------------------------------------------------------------------- + size_t + GetTokens (Mangled::TokenList &tokens) const; + + //---------------------------------------------------------------------- + /// Get the memory cost of this object. + /// + /// Return the size in bytes that this object takes in memory. This + /// returns the size in bytes of this object, not any shared string + /// values it may refer to. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// + /// @see ConstString::StaticMemorySize () + //---------------------------------------------------------------------- + size_t + MemorySize () const; + + //---------------------------------------------------------------------- + /// Set the string value in this object. + /// + /// If \a is_mangled is \b true, then the mangled named is set to \a + /// name, else the demangled name is set to \a name. + /// + /// @param[in] name + /// The name to copy into this object. + /// + /// @param[in] is_mangled + /// If \b true then \a name is a mangled name, if \b false then + /// \a name is demangled. + //---------------------------------------------------------------------- + void + SetValue (const char *name, bool is_mangled); + +private: + //---------------------------------------------------------------------- + /// Mangled member variables. + //---------------------------------------------------------------------- + ConstString m_mangled; ///< The mangled version of the name + mutable ConstString m_demangled; ///< Mutable so we can get it on demand with a const version of this object +}; + + +Stream& operator << (Stream& s, const Mangled& obj); +Stream& operator << (Stream& s, const Mangled::TokenList& obj); +Stream& operator << (Stream& s, const Mangled::Token& obj); + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Mangled_h_ diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h new file mode 100644 index 00000000000..d985ae9495f --- /dev/null +++ b/lldb/include/lldb/Core/Module.h @@ -0,0 +1,597 @@ +//===-- Module.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Module_h_ +#define liblldb_Module_h_ + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/UUID.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Host/TimeValue.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/TypeList.h" + +//---------------------------------------------------------------------- +/// @class Module Module.h "lldb/Core/Module.h" +/// @brief A class that describes an executable image and its associated +/// object and symbol files. +/// +/// The module is designed to be able to select a single slice of an +/// executable image as it would appear on disk and during program +/// execution. +/// +/// Modules control when and if information is parsed according to which +/// accessors are called. For example the object file (ObjectFile) +/// representation will only be parsed if the object file is requested +/// using the Module::GetObjectFile() is called. The debug symbols +/// will only be parsed if the symbol vendor (SymbolVendor) is +/// requested using the Module::GetSymbolVendor() is called. +/// +/// The module will parse more detailed information as more queries are +/// made. +//---------------------------------------------------------------------- +namespace lldb_private { + +class Module : + public SymbolContextScope +{ +public: + friend class ModuleList; + + enum + { + flagsSearchedForObjParser = (1 << 0), + flagsSearchedForSymVendor = (1 << 1), + flagsParsedUUID = (1 << 2) + }; + + //------------------------------------------------------------------ + /// Construct with file specification and architecture. + /// + /// Clients that wish to share modules with other targets should + /// use ModuleList::GetSharedModule(). + /// + /// @param[in] file_spec + /// The file specification for the on disk repesentation of + /// this executable image. + /// + /// @param[in] arch + /// The architecture to set as the current architecture in + /// this module. + /// + /// @param[in] object_name + /// The name of an object in a module used to extract a module + /// within a module (.a files and modules that contain multiple + /// architectures). + /// + /// @param[in] object_offset + /// The offset within an existing module used to extract a + /// module within a module (.a files and modules that contain + /// multiple architectures). + //------------------------------------------------------------------ + Module (const FileSpec& file_spec, + const ArchSpec& arch, + const ConstString *object_name = NULL, + off_t object_offset = 0); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Module (); + + //------------------------------------------------------------------ + /// If you have an instance of Module, get its corresponding shared + /// pointer if it has one in the shared module list. + //------------------------------------------------------------------ + lldb::ModuleSP + GetSP (); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext (SymbolContext* sc); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. The dumped content will be only what has + /// been loaded or parsed up to this point at which this function + /// is called, so this is a good way to see what has been parsed + /// in a module. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext (Stream *s); + + //------------------------------------------------------------------ + /// Find a symbol in the object files symbol table. + /// + /// @param[in] name + /// The name of the symbol that we are looking for. + /// + /// @param[in] symbol_type + /// If set to eSymbolTypeAny, find a symbol of any type that + /// has a name that matches \a name. If set to any other valid + /// SymbolType enumeration value, then search only for + /// symbols that match \a symbol_type. + /// + /// @return + /// Returns a valid symbol pointer if a symbol was found, + /// NULL otherwise. + //------------------------------------------------------------------ + const Symbol * + FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type = lldb::eSymbolTypeAny); + + size_t + FindSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, SymbolContextList &sc_list); + + size_t + FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, SymbolContextList &sc_list); + + //------------------------------------------------------------------ + /// Find functions by name. + /// + /// @param[in] name + /// The name of the function we are looking for. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[out] sc_list + /// A symbol context list that gets filled in with all of the + /// matches. + /// + /// @return + /// The number of matches added to \a sc_list. + //------------------------------------------------------------------ + uint32_t + FindFunctions (const ConstString &name, bool append, SymbolContextList& sc_list); + + //------------------------------------------------------------------ + /// Find functions by name. + /// + /// @param[in] regex + /// A regular expression to use when matching the name. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[out] sc_list + /// A symbol context list that gets filled in with all of the + /// matches. + /// + /// @return + /// The number of matches added to \a sc_list. + //------------------------------------------------------------------ + uint32_t + FindFunctions (const RegularExpression& regex, bool append, SymbolContextList& sc_list); + + //------------------------------------------------------------------ + /// Find global and static variables by name. + /// + /// @param[in] name + /// The name of the global or static variable we are looking + /// for. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] variable_list + /// A list of variables that gets the matches appended to (if + /// \a append it \b true), or replace (if \a append is \b false). + /// + /// @return + /// The number of matches added to \a variable_list. + //------------------------------------------------------------------ + uint32_t + FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variable_list); + + //------------------------------------------------------------------ + /// Find global and static variables by regular exression. + /// + /// @param[in] regex + /// A regular expression to use when matching the name. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] variable_list + /// A list of variables that gets the matches appended to (if + /// \a append it \b true), or replace (if \a append is \b false). + /// + /// @return + /// The number of matches added to \a variable_list. + //------------------------------------------------------------------ + uint32_t + FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variable_list); + + //------------------------------------------------------------------ + /// Find types by name. + /// + /// @param[in] sc + /// A symbol context that scopes where to extract a type list + /// from. + /// + /// @param[in] name + /// The name of the type we are looking for. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] encoding + /// Limit the search to specific types, or get all types if + /// set to Type::invalid. + /// + /// @param[in] udt_name + /// If the encoding is a user defined type, specify the name + /// of the user defined type ("struct", "union", "class", etc). + /// + /// @param[out] type_list + /// A type list gets populated with any matches. + /// + /// @return + /// The number of matches added to \a type_list. + //------------------------------------------------------------------ +// uint32_t +// FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& type_list); + + //------------------------------------------------------------------ + /// Find types by name. + /// + /// @param[in] sc + /// A symbol context that scopes where to extract a type list + /// from. + /// + /// @param[in] regex + /// A regular expression to use when matching the name. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] encoding + /// Limit the search to specific types, or get all types if + /// set to Type::invalid. + /// + /// @param[in] udt_name + /// If the encoding is a user defined type, specify the name + /// of the user defined type ("struct", "union", "class", etc). + /// + /// @param[out] type_list + /// A type list gets populated with any matches. + /// + /// @return + /// The number of matches added to \a type_list. + //------------------------------------------------------------------ +// uint32_t +// FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& type_list); + + //------------------------------------------------------------------ + /// Get const accessor for the module architecture. + /// + /// @return + /// A const reference to the architecture object. + //------------------------------------------------------------------ + const ArchSpec& + GetArchitecture () const; + + //------------------------------------------------------------------ + /// Get const accessor for the module file specification. + /// + /// @return + /// A const reference to the file specification object. + //------------------------------------------------------------------ + const FileSpec & + GetFileSpec () const; + + + const TimeValue & + GetModificationTime () const; + + //------------------------------------------------------------------ + /// Get the number of compile units for this module. + /// + /// @return + /// The number of compile units that the symbol vendor plug-in + /// finds. + //------------------------------------------------------------------ + uint32_t + GetNumCompileUnits(); + + lldb::CompUnitSP + GetCompileUnitAtIndex (uint32_t); + + const ConstString & + GetObjectName() const; + + off_t + GetObjectOffset() const; + + //------------------------------------------------------------------ + /// Get the object file representation for the current architecture. + /// + /// If the object file has not been located or parsed yet, this + /// function will find the best ObjectFile plug-in that can parse + /// Module::m_file. + /// + /// @return + /// If Module::m_file does not exist, or no plug-in was found + /// that can parse the file, or the object file doesn't contain + /// the current architecture in Module::m_arch, NULL will be + /// returned, else a valid object file interface will be + /// returned. The returned pointer is owned by this object and + /// remains valid as long as the object is around. + //------------------------------------------------------------------ + ObjectFile * + GetObjectFile (); + + //------------------------------------------------------------------ + /// Get the symbol vendor interface for the current architecture. + /// + /// If the symbol vendor file has not been located yet, this + /// function will find the best SymbolVendor plug-in that can + /// use the current object file. + /// + /// @return + /// If this module does not have a valid object file, or no + /// plug-in can be found that can use the object file, NULL will + /// be returned, else a valid symbol vendor plug-in interface + /// will be returned. The returned pointer is owned by this + /// object and remains valid as long as the object is around. + //------------------------------------------------------------------ + SymbolVendor* + GetSymbolVendor(bool can_create = true); + + //------------------------------------------------------------------ + /// Get accessor the type list for this module. + /// + /// @return + /// A valid type list pointer, or NULL if there is no valid + /// symbol vendor for this module. + //------------------------------------------------------------------ + TypeList* + GetTypeList (); + + //------------------------------------------------------------------ + /// Get a pointer to the UUID value contained in this object. + /// + /// If the executable image file doesn't not have a UUID value built + /// into the file format, an MD5 checksum of the entire file, or + /// slice of the file for the current architecture should be used. + /// + /// @return + /// A const pointer to the internal copy of the UUID value in + /// this module if this module has a valid UUID value, NULL + /// otherwise. + //------------------------------------------------------------------ + const UUID & + GetUUID (); + + //------------------------------------------------------------------ + /// A debugging function that will cause everything in a module to + /// be parsed. + /// + /// All compile units will be pasred, along with all globals and + /// static variables and all functions for those compile units. + /// All types, scopes, local variables, static variables, global + /// variables, and line tables will be parsed. This can be used + /// prior to dumping a module to see a complete list of the + /// resuling debug information that gets parsed, or as a debug + /// function to ensure that the module can consume all of the + /// debug data the symbol vendor provides. + //------------------------------------------------------------------ + void + ParseAllDebugSymbols(); + + bool + ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr); + + uint32_t + ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc); + + //------------------------------------------------------------------ + /// Resolve items in the symbol context for a given file and line. + /// + /// Tries to resolve \a file_path and \a line to a list of matching + /// symbol contexts. + /// + /// The line table entries contains addresses that can be used to + /// further resolve the values in each match: the function, block, + /// symbol. Care should be taken to minimize the amount of + /// information that is requested to only what is needed -- + /// typically the module, compile unit, line table and line table + /// entry are sufficient. + /// + /// @param[in] file_path + /// A path to a source file to match. If \a file_path does not + /// specify a directory, then this query will match all files + /// whose base filename matches. If \a file_path does specify + /// a directory, the fullpath to the file must match. + /// + /// @param[in] line + /// The source line to match, or zero if just the compile unit + /// should be resolved. + /// + /// @param[in] check_inlines + /// Check for inline file and line number matches. This option + /// should be used sparingly as it will cause all line tables + /// for every compile unit to be parsed and searched for + /// matching inline file entries. + /// + /// @param[in] resolve_scope + /// The scope that should be resolved (see + /// SymbolContext::Scope). + /// + /// @param[out] sc_list + /// A symbol context list that gets matching symbols contexts + /// appended to. + /// + /// @return + /// The number of matches that were added to \a sc_list. + /// + /// @see SymbolContext::Scope + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextForFilePath (const char *file_path, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list); + + //------------------------------------------------------------------ + /// Resolve items in the symbol context for a given file and line. + /// + /// Tries to resolve \a file_spec and \a line to a list of matching + /// symbol contexts. + /// + /// The line table entries contains addresses that can be used to + /// further resolve the values in each match: the function, block, + /// symbol. Care should be taken to minimize the amount of + /// information that is requested to only what is needed -- + /// typically the module, compile unit, line table and line table + /// entry are sufficient. + /// + /// @param[in] file_spec + /// A file spec to a source file to match. If \a file_path does + /// not specify a directory, then this query will match all + /// files whose base filename matches. If \a file_path does + /// specify a directory, the fullpath to the file must match. + /// + /// @param[in] line + /// The source line to match, or zero if just the compile unit + /// should be resolved. + /// + /// @param[in] check_inlines + /// Check for inline file and line number matches. This option + /// should be used sparingly as it will cause all line tables + /// for every compile unit to be parsed and searched for + /// matching inline file entries. + /// + /// @param[in] resolve_scope + /// The scope that should be resolved (see + /// SymbolContext::Scope). + /// + /// @param[out] sc_list + /// A symbol context list that gets filled in with all of the + /// matches. + /// + /// @return + /// A integer that contains SymbolContext::Scope bits set for + /// each item that was successfully resolved. + /// + /// @see SymbolContext::Scope + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list); + + + void + SetFileSpecAndObjectName (const FileSpec &file, + const ConstString &object_name); + +protected: + //------------------------------------------------------------------ + // Member Variables + //------------------------------------------------------------------ + mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. + TimeValue m_mod_time; ///< The modification time for this module when it was created. + const ArchSpec m_arch; ///< The architecture for this module. + UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols. + FileSpec m_file; ///< The file representation on disk for this module (if there is one). + Flags m_flags; ///< Flags for this module to track what has been parsed already. + ConstString m_object_name; ///< The name an object within this module that is selected, or empty of the module is represented by \a m_file. + std::auto_ptr<ObjectFile> m_objfile_ap; ///< A pointer to the object file parser for this module. + std::auto_ptr<SymbolVendor> m_symfile_ap; ///< A pointer to the symbol vendor for this module. + //------------------------------------------------------------------ + /// Resolve a file or load virtual address. + /// + /// Tries to resolve \a vm_addr as a file address (if \a + /// vm_addr_is_file_addr is true) or as a load address if \a + /// vm_addr_is_file_addr is false) in the symbol vendor. + /// \a resolve_scope indicates what clients wish to resolve + /// and can be used to limit the scope of what is parsed. + /// + /// @param[in] vm_addr + /// The load virtual address to resolve. + /// + /// @param[in] vm_addr_is_file_addr + /// If \b true, \a vm_addr is a file address, else \a vm_addr + /// if a load address. + /// + /// @param[in] resolve_scope + /// The scope that should be resolved (see + /// SymbolContext::Scope). + /// + /// @param[out] so_addr + /// The section offset based address that got resolved if + /// any bits are returned. + /// + /// @param[out] sc + // The symbol context that has objects filled in. Each bit + /// in the \a resolve_scope pertains to a member in the \a sc. + /// + /// @return + /// A integer that contains SymbolContext::Scope bits set for + /// each item that was successfully resolved. + /// + /// @see SymbolContext::Scope + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextForAddress (lldb::addr_t vm_addr, bool vm_addr_is_file_addr, uint32_t resolve_scope, Address& so_addr, SymbolContext& sc); + + void SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list); + +private: + + DISALLOW_COPY_AND_ASSIGN (Module); +}; + +} // namespace lldb_private + +#endif // liblldb_Module_h_ diff --git a/lldb/include/lldb/Core/ModuleChild.h b/lldb/include/lldb/Core/ModuleChild.h new file mode 100644 index 00000000000..0a8475a4425 --- /dev/null +++ b/lldb/include/lldb/Core/ModuleChild.h @@ -0,0 +1,103 @@ +//===-- ModuleChild.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ModuleChild_h_ +#define liblldb_ModuleChild_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ModuleChild ModuleChild.h "lldb/Core/ModuleChild.h" +/// @brief A mix in class that contains a pointer back to the module +/// that owns the object which inherits from it. +//---------------------------------------------------------------------- +class ModuleChild +{ +public: + //------------------------------------------------------------------ + /// Construct with owning module. + /// + /// @param[in] module + /// The module that owns the object that inherits from this + /// class. + //------------------------------------------------------------------ + ModuleChild (Module* module); + + //------------------------------------------------------------------ + /// Copy constructor. + /// + /// @param[in] rhs + /// A const ModuleChild class reference to copy. + //------------------------------------------------------------------ + ModuleChild (const ModuleChild& rhs); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from. + //------------------------------------------------------------------ + virtual + ~ModuleChild(); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// @param[in] rhs + /// A const ModuleChild class reference to copy. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const ModuleChild& + operator= (const ModuleChild& rhs); + + //------------------------------------------------------------------ + /// Get accessor for the module pointer. + /// + /// @return + /// A pointer to the module that owns this object. + //------------------------------------------------------------------ + Module * + GetModule (); + + //------------------------------------------------------------------ + /// Get const accessor for the module pointer. + /// + /// @return + /// A const pointer to the module that owns the object that + /// inherits from this class. + //------------------------------------------------------------------ + Module * + GetModule () const; + + //------------------------------------------------------------------ + /// Set accessor for the module pointer. + /// + /// @param[in] module + /// A new module that owns the object that inherits from this + /// class. + //------------------------------------------------------------------ + void + SetModule (Module *module); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Module *m_module; ///< The Module that owns the object that inherits + ///< from this class. +}; + +} // namespace lldb_private + + +#endif // liblldb_ModuleChild_h_ diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h new file mode 100644 index 00000000000..e4959023857 --- /dev/null +++ b/lldb/include/lldb/Core/ModuleList.h @@ -0,0 +1,339 @@ +//===-- ModuleList.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ModuleList_h_ +#define liblldb_ModuleList_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ModuleList ModuleList.h "lldb/Core/ModuleList.h" +/// @brief A collection class for Module objects. +/// +/// Modules in the module collection class are stored as reference +/// counted shared pointers to Module objects. +//---------------------------------------------------------------------- +class ModuleList +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Creates an empty list of Module objects. + //------------------------------------------------------------------ + ModuleList (); + + //------------------------------------------------------------------ + /// Copy Constructor. + /// + /// Creates a new module list object with a copy of the modules from + /// \a rhs. + /// + /// @param[in] rhs + /// Another module list object. + //------------------------------------------------------------------ + ModuleList (const ModuleList& rhs); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~ModuleList (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies the module list from \a rhs into this list. + /// + /// @param[in] rhs + /// Another module list object. + /// + /// @return + /// A const reference to this object. + //------------------------------------------------------------------ + const ModuleList& + operator= (const ModuleList& rhs); + + //------------------------------------------------------------------ + /// Append a module to the module list. + /// + /// Appends the module to the collection. + /// + /// @param[in] module_sp + /// A shared pointer to a module to add to this collection. + //------------------------------------------------------------------ + void + Append (lldb::ModuleSP &module_sp); + + bool + AppendInNeeded (lldb::ModuleSP &module_sp); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Clears the list of modules and releases a reference to each + /// module object and if the reference count goes to zero, the + /// module will be deleted. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Dump the description of each module contained in this list. + /// + /// Dump the description of each module contained in this list to + /// the supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @see Module::Dump(Stream *) const + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + uint32_t + GetIndexForModule (const Module *module) const; + + //------------------------------------------------------------------ + /// Get the module shared pointer for the module at index \a idx. + /// + /// @param[in] idx + /// An index into this module collection. + /// + /// @return + /// A shared pointer to a Module which can contain NULL if + /// \a idx is out of range. + /// + /// @see ModuleList::GetSize() + //------------------------------------------------------------------ + lldb::ModuleSP + GetModuleAtIndex (uint32_t idx); + + //------------------------------------------------------------------ + /// Get the module pointer for the module at index \a idx. + /// + /// @param[in] idx + /// An index into this module collection. + /// + /// @return + /// A pointer to a Module which can by NULL if \a idx is out + /// of range. + /// + /// @see ModuleList::GetSize() + //------------------------------------------------------------------ + Module* + GetModulePointerAtIndex (uint32_t idx) const; + + //------------------------------------------------------------------ + /// Find functions by name. + /// + /// Finds all functions that match \a name in all of the modules and + /// returns the results in \a sc_list. + /// + /// @param[in] name + /// The name of the function we are looking for. + /// + /// @param[out] sc_list + /// A symbol context list that gets filled in with all of the + /// matches. + /// + /// @return + /// The number of matches added to \a sc_list. + //------------------------------------------------------------------ + size_t + FindFunctions (const ConstString &name, + SymbolContextList &sc_list); + + //------------------------------------------------------------------ + /// Find global and static variables by name. + /// + /// @param[in] name + /// The name of the global or static variable we are looking + /// for. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] variable_list + /// A list of variables that gets the matches appended to (if + /// \a append it \b true), or replace (if \a append is \b false). + /// + /// @return + /// The number of matches added to \a variable_list. + //------------------------------------------------------------------ + uint32_t + FindGlobalVariables (const ConstString &name, + bool append, + uint32_t max_matches, + VariableList& variable_list); + + //------------------------------------------------------------------ + /// Find global and static variables by regular exression. + /// + /// @param[in] regex + /// A regular expression to use when matching the name. + /// + /// @param[in] append + /// If \b true, any matches will be appended to \a + /// variable_list, else matches replace the contents of + /// \a variable_list. + /// + /// @param[in] max_matches + /// Allow the number of matches to be limited to \a + /// max_matches. Specify UINT_MAX to get all possible matches. + /// + /// @param[in] variable_list + /// A list of variables that gets the matches appended to (if + /// \a append it \b true), or replace (if \a append is \b false). + /// + /// @return + /// The number of matches added to \a variable_list. + //------------------------------------------------------------------ + uint32_t + FindGlobalVariables (const RegularExpression& regex, + bool append, + uint32_t max_matches, + VariableList& variable_list); + + //------------------------------------------------------------------ + /// Finds the first module whose file specification matches \a + /// file_spec. + /// + /// @param[in] file_spec_ptr + /// A file specification object to match against the Module's + /// file specifications. If \a file_spec does not have + /// directory information, matches will occur by matching only + /// the basename of any modules in this list. If this value is + /// NULL, then file specifications won't be compared when + /// searching for matching modules. + /// + /// @param[in] arch_ptr + /// The architecture to search for if non-NULL. If this value + /// is NULL no architecture matching will be performed. + /// + /// @param[in] uuid_ptr + /// The uuid to search for if non-NULL. If this value is NULL + /// no uuid matching will be performed. + /// + /// @param[in] object_name + /// An optional object name that must match as well. This value + /// can be NULL. + /// + /// @param[out] matching_module_list + /// A module list that gets filled in with any modules that + /// match the search criteria. + /// + /// @return + /// The number of matching modules found by the search. + //------------------------------------------------------------------ + size_t + FindModules (const FileSpec *file_spec_ptr, + const ArchSpec *arch_ptr, + const UUID *uuid_ptr, + const ConstString *object_name, + ModuleList& matching_module_list) const; + + lldb::ModuleSP + FindModule (lldb_private::Module *module_ptr); + + lldb::ModuleSP + FindFirstModuleForFileSpec (const FileSpec &file_spec, + const ConstString *object_name = NULL); + + size_t + FindSymbolsWithNameAndType (const ConstString &name, + lldb::SymbolType symbol_type, + SymbolContextList &sc_list); + + + bool + Remove (lldb::ModuleSP &module_sp); + + bool + ResolveFileAddress (lldb::addr_t vm_addr, + Address& so_addr); + + //------------------------------------------------------------------ + /// @copydoc Module::ResolveSymbolContextForAddress (const Address &,uint32_t,SymbolContext&) + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextForAddress (const Address& so_addr, + uint32_t resolve_scope, + SymbolContext& sc); + + //------------------------------------------------------------------ + /// @copydoc Module::ResolveSymbolContextForFilePath (const char *,uint32_t,bool,uint32_t,SymbolContextList&) + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextForFilePath (const char *file_path, + uint32_t line, + bool check_inlines, + uint32_t resolve_scope, + SymbolContextList& sc_list); + + //------------------------------------------------------------------ + /// @copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec &,uint32_t,bool,uint32_t,SymbolContextList&) + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, + uint32_t line, + bool check_inlines, + uint32_t resolve_scope, + SymbolContextList& sc_list); + + //------------------------------------------------------------------ + /// Gets the size of the module list. + /// + /// @return + /// The number of modules in the module list. + //------------------------------------------------------------------ + size_t + GetSize () const; + + static const lldb::ModuleSP + GetModuleSP (lldb_private::Module *module_ptr); + + static Error + GetSharedModule (const FileSpec& file_spec, + const ArchSpec& arch, + const UUID *uuid_ptr, + const ConstString *object_name, + off_t object_offset, + lldb::ModuleSP &module_sp, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr); + +protected: + //------------------------------------------------------------------ + // Class typedefs. + //------------------------------------------------------------------ + typedef std::vector<lldb::ModuleSP> collection; ///< The module collection type. + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + collection m_modules; ///< The collection of modules. + mutable Mutex m_modules_mutex; + +}; + +} // namespace lldb_private + +#endif // liblldb_ModuleList_h_ diff --git a/lldb/include/lldb/Core/Options.h b/lldb/include/lldb/Core/Options.h new file mode 100644 index 00000000000..acdd3118fae --- /dev/null +++ b/lldb/include/lldb/Core/Options.h @@ -0,0 +1,296 @@ +//===-- Options.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Options_h_ +#define liblldb_Options_h_ + +// C Includes +#include <getopt.h> + +// C++ Includes +#include <set> +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Args.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Options Options.h "lldb/Core/Options.h" +/// @brief A command line option parsing protocol class. +/// +/// Options is designed to be subclassed to contain all needed +/// options for a given command. The options can be parsed by calling: +/// \code +/// Error Args::ParseOptions (Options &); +/// \endcode +/// +/// The options are specified using the format defined for the libc +/// options parsing function getopt_long: +/// \code +/// #include <getopt.h> +/// int getopt_long(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex); +/// \endcode +/// +/// Example code: +/// \code +/// #include <getopt.h> +/// #include <string> +/// +/// class CommandOptions : public Options +/// { +/// public: +/// virtual struct option * +/// GetLongOptions() { +/// return g_options; +/// } +/// +/// virtual Error +/// SetOptionValue (int option_idx, int option_val, const char *option_arg) +/// { +/// Error error; +/// switch (option_val) +/// { +/// case 'g': debug = true; break; +/// case 'v': verbose = true; break; +/// case 'l': log_file = option_arg; break; +/// case 'f': log_flags = strtoull(option_arg, NULL, 0); break; +/// default: +/// error.SetErrorStringWithFormat("unrecognized short option %c", option_val); +/// break; +/// } +/// +/// return error; +/// } +/// +/// CommandOptions () : debug (true), verbose (false), log_file (), log_flags (0) +/// {} +/// +/// bool debug; +/// bool verbose; +/// std::string log_file; +/// uint32_t log_flags; +/// +/// static struct option g_options[]; +/// +/// }; +/// +/// struct option CommandOptions::g_options[] = +/// { +/// { "debug", no_argument, NULL, 'g' }, +/// { "log-file", required_argument, NULL, 'l' }, +/// { "log-flags", required_argument, NULL, 'f' }, +/// { "verbose", no_argument, NULL, 'v' }, +/// { NULL, 0, NULL, 0 } +/// }; +/// +/// int main (int argc, const char **argv, const char **envp) +/// { +/// CommandOptions options; +/// Args main_command; +/// main_command.SetArguments(argc, argv, false); +/// main_command.ParseOptions(options); +/// +/// if (options.verbose) +/// { +/// std::cout << "verbose is on" << std::endl; +/// } +/// } +/// \endcode +//---------------------------------------------------------------------- +class Options +{ +public: + + Options (); + + virtual + ~Options (); + + void + BuildGetoptTable (); + + void + BuildValidOptionSets (); + + uint32_t + NumCommandOptions (); + + //------------------------------------------------------------------ + /// Get the option definitions to use when parsing Args options. + /// + /// @see Args::ParseOptions (Options&) + /// @see man getopt_long + //------------------------------------------------------------------ + struct option * + GetLongOptions (); + + void + OptionSeen (int option_idx); + + bool + VerifyOptions (CommandReturnObject &result); + + // Verify that the options given are in the options table and can be used together, but there may be + // some required options that are missing (used to verify options that get folded into command aliases). + + bool + VerifyPartialOptions (CommandReturnObject &result); + +// void +// BuildAliasOptions (OptionArgVector *option_arg_vector, Args args); + + void + OutputFormattedUsageText (Stream &strm, + const char *text, + uint32_t output_max_columns); + + void + GenerateOptionUsage (Stream &strm, + CommandObject *cmd, + const char *program_name = NULL); + + // The following two pure virtual functions must be defined by every class that inherits from + // this class. + + virtual const lldb::OptionDefinition* + GetDefinitions () = 0; + + virtual void + ResetOptionValues () = 0; + + //------------------------------------------------------------------ + /// Set the value of an option. + /// + /// @param[in] option_idx + /// The index into the "struct option" array that was returned + /// by Options::GetLongOptions(). + /// + /// @param[in] option_arg + /// The argument value for the option that the user entered, or + /// NULL if there is no argument for the current option. + /// + /// + /// @see Args::ParseOptions (Options&) + /// @see man getopt_long + //------------------------------------------------------------------ + virtual Error + SetOptionValue (int option_idx, const char *option_arg) = 0; + + //------------------------------------------------------------------ + /// Handles the generic bits of figuring out whether we are in an option, and if so completing + /// it. + /// + /// @param[in] input + /// The command line parsed into words + /// + /// @param[in] cursor_index + /// The index in \ainput of the word in which the cursor lies. + /// + /// @param[in] char_pos + /// The character position of the cursor in its argument word. + /// + /// @param[in] match_start_point + /// @param[in] match_return_elements + /// See CommandObject::HandleCompletions for a description of how these work. + /// + /// @param[in] interpreter + /// The interpreter that's doing the completing. + /// + /// @param[out] matches + /// The array of matches returned. + /// + /// FIXME: This is the wrong return value, since we also need to make a distinction between + /// total number of matches, and the window the user wants returned. + /// + /// @return + /// \btrue if we were in an option, \bfalse otherwise. + //------------------------------------------------------------------ + bool + HandleOptionCompletion (Args &input, + OptionElementVector &option_map, + int cursor_index, + int char_pos, + int match_start_point, + int max_return_elements, + lldb_private::CommandInterpreter *interpreter, + lldb_private::StringList &matches); + + //------------------------------------------------------------------ + /// Handles the generic bits of figuring out whether we are in an option, and if so completing + /// it. + /// + /// @param[in] input + /// The command line parsed into words + /// + /// @param[in] cursor_index + /// The index in \ainput of the word in which the cursor lies. + /// + /// @param[in] char_pos + /// The character position of the cursor in its argument word. + /// + /// @param[in] opt_element_vector + /// The results of the options parse of \a input. + /// + /// @param[in] opt_element_index + /// The position in \a opt_element_vector of the word in \a input containing the cursor. + /// + /// @param[in] match_start_point + /// @param[in] match_return_elements + /// See CommandObject::HandleCompletions for a description of how these work. + /// + /// @param[in] interpreter + /// The interpreter that's doing the completing. + /// + /// @param[out] matches + /// The array of matches returned. + /// + /// FIXME: This is the wrong return value, since we also need to make a distinction between + /// total number of matches, and the window the user wants returned. + /// + /// @return + /// \btrue if we were in an option, \bfalse otherwise. + //------------------------------------------------------------------ + virtual bool + HandleOptionArgumentCompletion (Args &input, + int cursor_index, + int char_pos, + OptionElementVector &opt_element_vector, + int opt_element_index, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + +protected: + typedef std::set<char> OptionSet; + + std::vector<struct option> m_getopt_table; + OptionSet m_seen_options; + std::vector<OptionSet> m_required_options; + std::vector<OptionSet> m_optional_options; + + + + bool + IsASubset (const OptionSet& set_a, const OptionSet& set_b); + + size_t + OptionsSetDiff (const OptionSet &set_a, const OptionSet &set_b, OptionSet &diffs); + + void + OptionsSetUnion (const OptionSet &set_a, const OptionSet &set_b, OptionSet &union_set); +}; + +} // namespace lldb_private + +#endif // liblldb_Options_h_ diff --git a/lldb/include/lldb/Core/PluginInterface.h b/lldb/include/lldb/Core/PluginInterface.h new file mode 100644 index 00000000000..2c2823501fc --- /dev/null +++ b/lldb/include/lldb/Core/PluginInterface.h @@ -0,0 +1,46 @@ +//===-- PluginInterface.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PluginInterface_h_ +#define liblldb_PluginInterface_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class PluginInterface +{ +public: + + virtual const char * + GetPluginName() = 0; + + virtual const char * + GetShortPluginName() = 0; + + virtual uint32_t + GetPluginVersion() = 0; + + virtual void + GetPluginCommandHelp (const char *command, Stream *strm) = 0; + + virtual Error + ExecutePluginCommand (Args &command, Stream *strm) = 0; + + virtual Log * + EnablePluginLogging (Stream *strm, Args &command) = 0; +}; + +} // namespace lldb_private + +#endif // liblldb_PluginInterface_h_ diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h new file mode 100644 index 00000000000..fbd12a56dbb --- /dev/null +++ b/lldb/include/lldb/Core/PluginManager.h @@ -0,0 +1,186 @@ +//===-- PluginManager.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_PluginManager_h_ +#define liblldb_PluginManager_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class PluginManager +{ +public: + //------------------------------------------------------------------ + // ABI + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + ABICreateInstance create_callback); + + static bool + UnregisterPlugin (ABICreateInstance create_callback); + + static ABICreateInstance + GetABICreateCallbackAtIndex (uint32_t idx); + + static ABICreateInstance + GetABICreateCallbackForPluginName (const char *name); + + + //------------------------------------------------------------------ + // Disassembler + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + DisassemblerCreateInstance create_callback); + + static bool + UnregisterPlugin (DisassemblerCreateInstance create_callback); + + static DisassemblerCreateInstance + GetDisassemblerCreateCallbackAtIndex (uint32_t idx); + + static DisassemblerCreateInstance + GetDisassemblerCreateCallbackForPluginName (const char *name); + + + //------------------------------------------------------------------ + // DynamicLoader + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + DynamicLoaderCreateInstance create_callback); + + static bool + UnregisterPlugin (DynamicLoaderCreateInstance create_callback); + + static DynamicLoaderCreateInstance + GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx); + + static DynamicLoaderCreateInstance + GetDynamicLoaderCreateCallbackForPluginName (const char *name); + + + //------------------------------------------------------------------ + // ObjectFile + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + ObjectFileCreateInstance create_callback); + + static bool + UnregisterPlugin (ObjectFileCreateInstance create_callback); + + static ObjectFileCreateInstance + GetObjectFileCreateCallbackAtIndex (uint32_t idx); + + static ObjectFileCreateInstance + GetObjectFileCreateCallbackForPluginName (const char *name); + + + //------------------------------------------------------------------ + // ObjectContainer + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + ObjectContainerCreateInstance create_callback); + + static bool + UnregisterPlugin (ObjectContainerCreateInstance create_callback); + + static ObjectContainerCreateInstance + GetObjectContainerCreateCallbackAtIndex (uint32_t idx); + + static ObjectContainerCreateInstance + GetObjectContainerCreateCallbackForPluginName (const char *name); + + //------------------------------------------------------------------ + // LogChannel + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + LogChannelCreateInstance create_callback); + + static bool + UnregisterPlugin (LogChannelCreateInstance create_callback); + + static LogChannelCreateInstance + GetLogChannelCreateCallbackAtIndex (uint32_t idx); + + static LogChannelCreateInstance + GetLogChannelCreateCallbackForPluginName (const char *name); + + static const char * + GetLogChannelCreateNameAtIndex (uint32_t idx); + + //------------------------------------------------------------------ + // Process + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + ProcessCreateInstance create_callback); + + static bool + UnregisterPlugin (ProcessCreateInstance create_callback); + + static ProcessCreateInstance + GetProcessCreateCallbackAtIndex (uint32_t idx); + + static ProcessCreateInstance + GetProcessCreateCallbackForPluginName (const char *name); + + //------------------------------------------------------------------ + // SymbolFile + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + SymbolFileCreateInstance create_callback); + + static bool + UnregisterPlugin (SymbolFileCreateInstance create_callback); + + static SymbolFileCreateInstance + GetSymbolFileCreateCallbackAtIndex (uint32_t idx); + + static SymbolFileCreateInstance + GetSymbolFileCreateCallbackForPluginName (const char *name); + + + //------------------------------------------------------------------ + // SymbolVendor + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + SymbolVendorCreateInstance create_callback); + + static bool + UnregisterPlugin (SymbolVendorCreateInstance create_callback); + + static SymbolVendorCreateInstance + GetSymbolVendorCreateCallbackAtIndex (uint32_t idx); + + static SymbolVendorCreateInstance + GetSymbolVendorCreateCallbackForPluginName (const char *name); +}; + + +} // namespace lldb_private + +#endif // liblldb_PluginManager_h_ diff --git a/lldb/include/lldb/Core/RegularExpression.h b/lldb/include/lldb/Core/RegularExpression.h new file mode 100644 index 00000000000..23dabef1443 --- /dev/null +++ b/lldb/include/lldb/Core/RegularExpression.h @@ -0,0 +1,166 @@ +//===-- RegularExpression.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DBRegex_h_ +#define liblldb_DBRegex_h_ +#if defined(__cplusplus) + +#include <regex.h> + +#include <string> +#include <vector> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class RegularExpression RegularExpression.h "lldb/Core/RegularExpression.h" +/// @brief A C++ wrapper class for regex. +/// +/// This regular expression class wraps the posix regex functions +/// \c regcomp(), \c regerror(), \c regexec(), and \c regfree() from +/// the header file in \c /usr/include/regex\.h. +//---------------------------------------------------------------------- +class RegularExpression +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// The default constructor that initializes the object state such + /// that it contains no compiled regular expression. + //------------------------------------------------------------------ + RegularExpression (); + + //------------------------------------------------------------------ + /// Constructor that takes a regulare expression with flags. + /// + /// Constructor that compiles \a re using \a flags and stores the + /// resulting compiled regular expression into this object. + /// + /// @param[in] re + /// A c string that represents the regular expression to + /// compile. + /// + /// @param[in] flags + /// Flags that are passed the the \c regcomp() function. + //------------------------------------------------------------------ + RegularExpression (const char* re, int flags = REG_EXTENDED); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// Any previosuly compiled regular expression contained in this + /// object will be freed. + //------------------------------------------------------------------ + ~RegularExpression (); + + //------------------------------------------------------------------ + /// Compile a regular expression. + /// + /// Compile a regular expression using the supplied regular + /// expression text and flags. The compied regular expression lives + /// in this object so that it can be readily used for regular + /// expression matches. Execute() can be called after the regular + /// expression is compiled. Any previosuly compiled regular + /// expression contained in this object will be freed. + /// + /// @param[in] re + /// A NULL terminated C string that represents the regular + /// expression to compile. + /// + /// @param[in] flags + /// Flags that are passed the the \c regcomp() function. + /// + /// @return + /// \b true if the regular expression compiles successfully, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + Compile (const char* re, int flags = REG_EXTENDED); + + //------------------------------------------------------------------ + /// Executes a regular expression. + /// + /// Execute a regular expression match using the compiled regular + /// expression that is already in this object against the match + /// string \a s. If any parens are used for regular expression + /// matches \a match_count should indicate the number of regmatch_t + /// values that are present in \a match_ptr. The regular expression + /// will be executed using the \a execute_flags + /// + /// @param[in] string + /// The string to match against the compile regular expression. + /// + /// @param[in] match_count + /// The number of regmatch_t objects in \a match_ptr + /// + /// @param[out] match_ptr + /// A pointer to at least \a match_count regmatch_t objects + /// if \a match_count is non-zero. + /// + /// @param[in] execute_flags + /// Flags to pass to the \c regexec() function. + /// + /// @return + /// \b true if \a string matches the compiled regular + /// expression, \b false otherwise. + //------------------------------------------------------------------ + bool + Execute (const char* string, size_t match_count = 0, int execute_flags = 0) const; + + bool + GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const; + //------------------------------------------------------------------ + /// Free the compiled regular expression. + /// + /// If this object contains a valid compiled regular expression, + /// this function will free any resources it was consuming. + //------------------------------------------------------------------ + void + Free (); + + //------------------------------------------------------------------ + /// Access the regular expression text. + /// + /// Returns the text that was used to compile the current regular + /// expression. + /// + /// @return + /// The NULL terminated C string that was used to compile the + /// current regular expression + //------------------------------------------------------------------ + const char* + GetText () const; + + //------------------------------------------------------------------ + /// Test if valid. + /// + /// Test if this object contains a valid regular expression. + /// + /// @return + /// \b true if the regular expression compiled and is ready + /// for execution, \b false otherwise. + //------------------------------------------------------------------ + bool + IsValid () const; + +private: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + std::string m_re; ///< A copy of the original regular expression text + int m_comp_err; ///< Error code for the regular expression compilation + regex_t m_preg; ///< The compiled regular expression + mutable std::vector<regmatch_t> m_matches; ///< Where parenthesized subexpressions results are stored +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_DBRegex_h_ diff --git a/lldb/include/lldb/Core/STLUtils.h b/lldb/include/lldb/Core/STLUtils.h new file mode 100644 index 00000000000..21b9a0af6c5 --- /dev/null +++ b/lldb/include/lldb/Core/STLUtils.h @@ -0,0 +1,104 @@ +//===-- STLUtils.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_STLUtils_h_ +#define liblldb_STLUtils_h_ +#if defined(__cplusplus) + +#include <ext/hash_fun.h> +#include <string.h> + +#include <map> +#include <ostream> +#include <vector> + +//---------------------------------------------------------------------- +// C string less than compare function object +//---------------------------------------------------------------------- +struct CStringCompareFunctionObject +{ + bool operator() (const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } +}; + + +//---------------------------------------------------------------------- +// C string equality function object (binary predicate). +//---------------------------------------------------------------------- +struct CStringEqualBinaryPredicate +{ + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) == 0; + } +}; + + +//---------------------------------------------------------------------- +// Templated type for finding an entry in a std::map<F,S> whose value +// is equal to something +//---------------------------------------------------------------------- +template <class F, class S> +class ValueEquals +{ +private: + S second_value; + +public: + ValueEquals (const S& val) : second_value(val) + {} + // Compare the second item + bool operator() (std::pair<const F, S> elem) + { + return elem.second == second_value; + } +}; + +struct StdStringHash +{ + size_t operator()( const std::string& x ) const + { + return __gnu_cxx::hash<const char*>()( x.c_str() ); + } +}; + + +template <class T> +inline void PrintAllCollectionElements (std::ostream &s, const T& coll, const char* header_cstr=NULL, const char* separator_cstr=" ") +{ + typename T::const_iterator pos; + + if (header_cstr) + s << header_cstr; + for (pos=coll.begin(); pos!=coll.end(); ++pos) { + s << *pos << separator_cstr; + } + s << std::endl; +} + +// The function object below can be used to delete a STL container that +// contains C++ object pointers. +// +// Usage: std::for_each(vector.begin(), vector.end(), for_each_delete()); + +struct for_each_cplusplus_delete +{ + template <typename T> + void operator()(T *ptr){ delete ptr;} +}; + +typedef std::vector<std::string> STLStringArray; +typedef std::vector<const char *> CStringArray; + + + +#endif // #if defined(__cplusplus) +#endif // liblldb_STLUtils_h_ diff --git a/lldb/include/lldb/Core/Scalar.h b/lldb/include/lldb/Core/Scalar.h new file mode 100644 index 00000000000..4207bb6f59e --- /dev/null +++ b/lldb/include/lldb/Core/Scalar.h @@ -0,0 +1,302 @@ +//===-- Scalar.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Scalar_h_ +#define liblldb_Scalar_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A class designed to hold onto values and their corresponding types. +// Operators are defined and Scalar objects will correctly promote +// their types and values before performing these operations. Type +// promotion currently follows the ANSI C type promotion rules. +//---------------------------------------------------------------------- +class Scalar +{ +public: + enum Type + { + e_void = 0, + e_sint, + e_uint, + e_slong, + e_ulong, + e_slonglong, + e_ulonglong, + e_float, + e_double, + e_long_double + }; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Scalar(); + Scalar(int v) : m_type(e_sint), m_data() { m_data.sint = v; } + Scalar(unsigned int v) : m_type(e_uint), m_data() { m_data.uint = v; } + Scalar(long v) : m_type(e_slong), m_data() { m_data.slong = v; } + Scalar(unsigned long v) : m_type(e_ulong), m_data() { m_data.ulong = v; } + Scalar(long long v) : m_type(e_slonglong), m_data() { m_data.slonglong = v; } + Scalar(unsigned long long v): m_type(e_ulonglong), m_data() { m_data.ulonglong = v; } + Scalar(float v) : m_type(e_float), m_data() { m_data.flt = v; } + Scalar(double v) : m_type(e_double), m_data() { m_data.dbl = v; } + Scalar(long double v) : m_type(e_long_double), m_data() { m_data.ldbl = v; } + Scalar(const Scalar& rhs); + //Scalar(const RegisterValue& reg_value); + virtual ~Scalar(); + + size_t + GetByteSize() const; + + bool + GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const; + + bool + IsZero() const; + + void + Clear() { m_type = e_void; m_data.ulonglong = 0; } + + const char * + GetTypeAsCString() const; + + void + GetValue (Stream *s, bool show_type) const; + + bool + IsValid() const + { + return (m_type >= e_sint) && (m_type <= e_long_double); + } + + bool + Promote(Scalar::Type type); + + bool + Cast (Scalar::Type type); + + static const char * + GetValueTypeAsCString (Scalar::Type value_type); + + static Scalar::Type + GetValueTypeForSignedIntegerWithByteSize (size_t byte_size); + + static Scalar::Type + GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size); + + static Scalar::Type + GetValueTypeForFloatWithByteSize (size_t byte_size); + + //---------------------------------------------------------------------- + // All operators can benefits from the implicit conversions that will + // happen automagically by the compiler, so no temporary objects will + // need to be created. As a result, we currently don't need a variety of + // overloaded set value accessors. + //---------------------------------------------------------------------- + Scalar& operator= (const int i); + Scalar& operator= (unsigned int v); + Scalar& operator= (long v); + Scalar& operator= (unsigned long v); + Scalar& operator= (long long v); + Scalar& operator= (unsigned long long v); + Scalar& operator= (float v); + Scalar& operator= (double v); + Scalar& operator= (long double v); + Scalar& operator= (const Scalar& rhs); // Assignment operator + Scalar& operator+= (const Scalar& rhs); + Scalar& operator<<= (const Scalar& rhs); // Shift left + Scalar& operator>>= (const Scalar& rhs); // Shift right (arithmetic) + Scalar& operator&= (const Scalar& rhs); + + //---------------------------------------------------------------------- + // Shifts the current value to the right without maintaining the current + // sign of the value (if it is signed). + //---------------------------------------------------------------------- + bool + ShiftRightLogical(const Scalar& rhs); // Returns true on success + + //---------------------------------------------------------------------- + // Takes the absolute value of the current value if it is signed, else + // the value remains unchanged. + // Returns false if the contained value has a void type. + //---------------------------------------------------------------------- + bool + AbsoluteValue(); // Returns true on success + //---------------------------------------------------------------------- + // Negates the current value (even for unsigned values). + // Returns false if the contained value has a void type. + //---------------------------------------------------------------------- + bool + UnaryNegate(); // Returns true on success + //---------------------------------------------------------------------- + // Inverts all bits in the current value as long as it isn't void or + // a float/double/long double type. + // Returns false if the contained value has a void/float/double/long + // double type, else the value is inverted and true is returned. + //---------------------------------------------------------------------- + bool + OnesComplement(); // Returns true on success + + //---------------------------------------------------------------------- + // Access the type of the current value. + //---------------------------------------------------------------------- + Scalar::Type + GetType() const { return m_type; } + + //---------------------------------------------------------------------- + // Returns a casted value of the current contained data without + // modifying the current value. FAIL_VALUE will be returned if the type + // of the value is void or invalid. + //---------------------------------------------------------------------- + int + SInt(int fail_value = 0) const; + + // Return the raw unsigned integer without any casting or conversion + unsigned int + RawUInt () const; + + // Return the raw unsigned long without any casting or conversion + unsigned long + RawULong () const; + + // Return the raw unsigned long long without any casting or conversion + unsigned long long + RawULongLong () const; + + unsigned int + UInt(unsigned int fail_value = 0) const; + + long + SLong(long fail_value = 0) const; + + unsigned long + ULong(unsigned long fail_value = 0) const; + + long long + SLongLong(long long fail_value = 0) const; + + unsigned long long + ULongLong(unsigned long long fail_value = 0) const; + + float + Float(float fail_value = 0.0f) const; + + double + Double(double fail_value = 0.0) const; + + long double + LongDouble(long double fail_value = 0.0) const; + + uint64_t + GetRawBits64 (uint64_t fail_value) const; + + Error + SetValueFromCString (const char *s, lldb::Encoding encoding, uint32_t byte_size); + + static bool + UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size) + { + if (total_byte_size > 8) + return false; + + if (total_byte_size == 8) + return true; + + const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; + return uval64 <= max; + } + + static bool + SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size) + { + if (total_byte_size > 8) + return false; + + if (total_byte_size == 8) + return true; + + const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; + const int64_t min = ~(max); + return min <= sval64 && sval64 <= max; + } + +protected: + typedef union ValueData + { + int sint; + unsigned int uint; + long slong; + unsigned long ulong; + long long slonglong; + unsigned long long ulonglong; + float flt; + double dbl; + long double ldbl; + }; + + //------------------------------------------------------------------ + // Classes that inherit from Scalar can see and modify these + //------------------------------------------------------------------ + Scalar::Type m_type; + ValueData m_data; + +private: + friend const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator- (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator* (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator& (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator| (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator% (const Scalar& lhs, const Scalar& rhs); + friend const Scalar operator^ (const Scalar& lhs, const Scalar& rhs); + friend bool operator== (const Scalar& lhs, const Scalar& rhs); + friend bool operator!= (const Scalar& lhs, const Scalar& rhs); + friend bool operator< (const Scalar& lhs, const Scalar& rhs); + friend bool operator<= (const Scalar& lhs, const Scalar& rhs); + friend bool operator> (const Scalar& lhs, const Scalar& rhs); + friend bool operator>= (const Scalar& lhs, const Scalar& rhs); + +}; + +//---------------------------------------------------------------------- +// Split out the operators into a format where the compiler will be able +// to implicitly convert numbers into Scalar objects. +// +// This allows code like: +// Scalar two(2); +// Scalar four = two * 2; +// Scalar eight = 2 * four; // This would cause an error if the +// // operator* was implemented as a +// // member function. +// SEE: +// Item 19 of "Effective C++ Second Edition" by Scott Meyers +// Differentiate among members functions, non-member functions, and +// friend functions +//---------------------------------------------------------------------- +const Scalar operator+ (const Scalar& lhs, const Scalar& rhs); +const Scalar operator- (const Scalar& lhs, const Scalar& rhs); +const Scalar operator/ (const Scalar& lhs, const Scalar& rhs); +const Scalar operator* (const Scalar& lhs, const Scalar& rhs); +const Scalar operator& (const Scalar& lhs, const Scalar& rhs); +const Scalar operator| (const Scalar& lhs, const Scalar& rhs); +const Scalar operator% (const Scalar& lhs, const Scalar& rhs); +const Scalar operator^ (const Scalar& lhs, const Scalar& rhs); +bool operator== (const Scalar& lhs, const Scalar& rhs); +bool operator!= (const Scalar& lhs, const Scalar& rhs); +bool operator< (const Scalar& lhs, const Scalar& rhs); +bool operator<= (const Scalar& lhs, const Scalar& rhs); +bool operator> (const Scalar& lhs, const Scalar& rhs); +bool operator>= (const Scalar& lhs, const Scalar& rhs); + +} // namespace lldb_private + +#endif // liblldb_Scalar_h_ diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h new file mode 100644 index 00000000000..5864e85a141 --- /dev/null +++ b/lldb/include/lldb/Core/SearchFilter.h @@ -0,0 +1,326 @@ +//===-- SearchFilter.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SearchFilter_h_ +#define liblldb_SearchFilter_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/Address.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Core/Module.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" +/// @brief Class that is driven by the SearchFilter to search the +/// SymbolContext space of the target program. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// Provides the callback and search depth for the SearchFilter search. +//---------------------------------------------------------------------- + +class Searcher +{ +public: + typedef enum { + eCallbackReturnStop = 0, // Stop the iteration + eCallbackReturnContinue, // Continue the iteration + eCallbackReturnPop // Pop one level up and continue iterating + } CallbackReturn; + + typedef enum { + eDepthTarget, + eDepthModule, + eDepthCompUnit, + eDepthFunction, + eDepthBlock, + eDepthAddress + } Depth; + + Searcher (); + + virtual ~Searcher (); + + virtual CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool complete) = 0; + + virtual Depth + GetDepth () = 0; + + //------------------------------------------------------------------ + /// Prints a canonical description for the searcher to the stream \a s. + /// + /// @param[in] s + /// Stream to which the output is copied. + //------------------------------------------------------------------ + virtual void + GetDescription(Stream *s); +}; + +//---------------------------------------------------------------------- +/// @class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" +/// @brief Class descends through the SymbolContext space of the target, +/// applying a filter at each stage till it reaches the depth specified by +/// the GetDepth method of the searcher, and calls its callback at that point. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +/// General Outline: +/// Provides the callback and search depth for the SearchFilter search. +/// +/// The search is done by cooperation between the search filter and the searcher. +/// The search filter does the heavy work of recursing through the SymbolContext +/// space of the target program's symbol space. The Searcher specifies the depth +/// at which it wants its callback to be invoked. Note that since the resolution +/// of the Searcher may be greater than that of the SearchFilter, before the +/// Searcher qualifies an address it should pass it to "AddressPasses." +/// The default implementation is "Everything Passes." +//---------------------------------------------------------------------- + +class SearchFilter +{ +public: + + //------------------------------------------------------------------ + /// The basic constructor takes a Target, which gives the space to search. + /// + /// @param[in] target + /// The Target that provides the module list to search. + //------------------------------------------------------------------ + SearchFilter (lldb::TargetSP &target_sp); + + SearchFilter(const SearchFilter& rhs); + + virtual + ~SearchFilter (); + + const SearchFilter& + operator=(const SearchFilter& rhs); + + //------------------------------------------------------------------ + /// Call this method with a file spec to see if that spec passes the filter. + /// + /// @param[in] spec + /// The file spec to check against the filter. + /// @return + /// \b true if \a spec passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + ModulePasses (const FileSpec &spec); + + //------------------------------------------------------------------ + /// Call this method with a Module to see if that module passes the filter. + /// + /// @param[in] module + /// The Module to check against the filter. + /// + /// @return + /// \b true if \a module passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + ModulePasses (const lldb::ModuleSP &module_sp); + + //------------------------------------------------------------------ + /// Call this method with a SymbolContext and a SymbolContextScope to see if + /// that SymbolContext passes the filter up to the level in \a scope. + /// + /// @param[in] context + /// The SymbolContext to check against the filter. + /// + /// @param[in] scope + /// The SymbolContextItem indicating what bits of the SymbolContextScope + /// to check against the filter. + /// + /// @return + /// \b true if \a SymbolContext passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + SymbolContextPasses (const SymbolContext &context, + lldb::SymbolContextItem scope); + //------------------------------------------------------------------ + /// Call this method with a Address to see if \a address passes the filter. + /// + /// @param[in] addr + /// The address to check against the filter. + /// + /// @return + /// \b true if \a address passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + AddressPasses (Address &addr); + + //------------------------------------------------------------------ + /// Call this method with a FileSpec to see if \a file spec passes the filter + /// as the name of a compilation unit. + /// + /// @param[in] fileSpec + /// The file spec to check against the filter. + /// + /// @return + /// \b true if \a file spec passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + CompUnitPasses (FileSpec &fileSpec); + + //------------------------------------------------------------------ + /// Call this method with a CompileUnit to see if \a comp unit passes the filter. + /// + /// @param[in] compUnit + /// The CompileUnit to check against the filter. + /// + /// @return + /// \b true if \a Comp Unit passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool + CompUnitPasses (CompileUnit &compUnit); + + //------------------------------------------------------------------ + /// Call this method to do the search using the Searcher. + /// + /// @param[in] searcher + /// The searcher to drive with this search. + /// + //------------------------------------------------------------------ + virtual void + Search (Searcher &searcher); + + //------------------------------------------------------------------ + /// Call this method to do the search using the Searcher in the module list + /// \a modules. + /// + /// @param[in] searcher + /// The searcher to drive with this search. + /// + /// @param[in] modules + /// The module list within which to restrict the search. + /// + //------------------------------------------------------------------ + virtual void + SearchInModuleList (Searcher &searcher, ModuleList &modules); + + //------------------------------------------------------------------ + /// Prints a canonical description for the search filter to the stream \a s. + /// + /// @param[in] s + /// Stream to which the output is copied. + //------------------------------------------------------------------ + virtual void + GetDescription(Stream *s); + + //------------------------------------------------------------------ + /// Standard "Dump" method. At present it does nothing. + //------------------------------------------------------------------ + virtual void + Dump (Stream *s) const; + +protected: + + // These are utility functions to assist with the search iteration. They are used by the + // default Search method. + + Searcher::CallbackReturn + DoModuleIteration (const SymbolContext &context, + Searcher &searcher); + + Searcher::CallbackReturn + DoModuleIteration (const lldb::ModuleSP& module_sp, + Searcher &searcher); + + Searcher::CallbackReturn + DoCUIteration (const lldb::ModuleSP& module_sp, + const SymbolContext &context, + Searcher &searcher); + + Searcher::CallbackReturn + DoFunctionIteration (Function *function, + const SymbolContext &context, + Searcher &searcher); + + lldb::TargetSP m_target_sp; // Every filter has to be associated with a target for + // now since you need a starting place for the search. +}; + +//---------------------------------------------------------------------- +/// @class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" +/// @brief This is a SearchFilter that restricts the search to a given module. +//---------------------------------------------------------------------- + +class SearchFilterByModule : + public SearchFilter +{ +public: + + //------------------------------------------------------------------ + /// The basic constructor takes a Target, which gives the space to search, + /// and the module to restrict the search to. + /// + /// @param[in] target + /// The Target that provides the module list to search. + /// + /// @param[in] module + /// The Module that limits the search. + //------------------------------------------------------------------ + SearchFilterByModule (lldb::TargetSP &targetSP, + const FileSpec &module); + + SearchFilterByModule (const SearchFilterByModule& rhs); + + virtual + ~SearchFilterByModule (); + + const SearchFilterByModule& + operator=(const SearchFilterByModule& rhs); + + virtual bool + ModulePasses (const lldb::ModuleSP &module_sp); + + virtual bool + ModulePasses (const FileSpec &spec); + + virtual bool + SymbolContextPasses (const SymbolContext &context, + lldb::SymbolContextItem scope); + + virtual bool + AddressPasses (Address &address); + + virtual bool + CompUnitPasses (FileSpec &fileSpec); + + virtual bool + CompUnitPasses (CompileUnit &compUnit); + + virtual void + GetDescription(Stream *s); + + virtual void + Dump (Stream *s) const; + + virtual void + Search (Searcher &searcher); + +private: + FileSpec m_module_spec; +}; + +} // namespace lldb_private + +#endif // liblldb_SearchFilter_h_ diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h new file mode 100644 index 00000000000..358a7489523 --- /dev/null +++ b/lldb/include/lldb/Core/Section.h @@ -0,0 +1,231 @@ +//===-- Section.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Section_h_ +#define liblldb_Section_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/UserID.h" +#include "lldb/Core/VMRange.h" + +namespace lldb_private { + +class SectionList +{ +public: + typedef std::vector<lldb::SectionSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + SectionList(); + + virtual + ~SectionList(); + + uint32_t + AddSection (lldb::SectionSP& sect_sp); + + uint32_t + AddUniqueSection (lldb::SectionSP& sect_sp); + + uint32_t + FindSectionIndex (const Section* sect); + + bool + ContainsSection(lldb::user_id_t sect_id) const; + + void + Dump (Stream *s, Process *process, bool show_header) const; + + lldb::SectionSP + FindSectionByName (const ConstString §ion_dstr) const; + +// lldb::SectionSP +// FindSectionByNames (const char *sect, ...) const; + + lldb::SectionSP + FindSectionByID (lldb::user_id_t sect_id) const; + + lldb::SectionSP + GetSharedPointer (const Section *section, bool check_children) const; + + lldb::SectionSP + FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT_MAX) const; + + lldb::SectionSP + FindSectionContainingLinkedFileAddress (lldb::addr_t vm_addr) const; + + bool + GetSectionData (const DataExtractor& module_data, DataExtractor& section_data) const; + + // Get the number of sections in this list only + size_t + GetSize () const; + + // Get the number of sections in this list, and any contained child sections + size_t + GetNumSections (uint32_t depth) const; + + bool + ReplaceSection (lldb::user_id_t sect_id, lldb::SectionSP& sect_sp, uint32_t depth = UINT_MAX); + + lldb::SectionSP + GetSectionAtIndex (uint32_t idx) const; + + size_t + Slide (lldb::addr_t slide_amount, bool slide_children); + +protected: + collection m_sections; +}; + + +class Section : + public ModuleChild, + public UserID, + public Flags +{ +public: + Section ( + Section *parent, // NULL for top level sections, non-NULL for child sections + Module* module, + lldb::user_id_t sect_id, + const ConstString &name, + lldb::SectionType sect_type, + lldb::addr_t file_vm_addr, + lldb::addr_t vm_size, + uint64_t file_offset, + uint64_t file_size, + uint32_t flags); + + ~Section (); + + static int + Compare (const Section& a, const Section& b); + + // Get a valid shared pointer to this section object + lldb::SectionSP + GetSharedPointer() const; + + bool + ContainsFileAddress (lldb::addr_t vm_addr) const; + + SectionList& + GetChildren (); + + const SectionList& + GetChildren () const; + + void + Dump (Stream *s, Process *process) const; + + void + DumpName (Stream *s) const; + + lldb::addr_t + GetLoadBaseAddress (Process *process) const; + + bool + ResolveContainedAddress (lldb::addr_t offset, Address &so_addr) const; + + uint64_t + GetFileOffset () const; + + uint64_t + GetFileSize () const; + + lldb::addr_t + GetFileAddress () const; + + lldb::addr_t + GetOffset () const; + + lldb::addr_t + GetByteSize () const; + + void + SetByteSize (lldb::addr_t byte_size); + + size_t + GetSectionDataFromImage (const DataExtractor& image_data, DataExtractor& section_data) const; + + bool + IsFake() const; + + void + SetIsFake(bool fake); + + bool + IsDescendant (const Section *section); + + size_t + MemoryMapSectionDataFromObjectFile (const ObjectFile* file, DataExtractor& section_data) const; + + size_t + ReadSectionDataFromObjectFile (const ObjectFile* file, DataExtractor& section_data) const; + + ConstString& + GetName (); + + const ConstString& + GetName () const; + + bool + Slide (lldb::addr_t slide_amount, bool slide_children); + + void + SetLinkedLocation (const Section *linked_section, uint64_t linked_offset); + + bool + ContainsLinkedFileAddress (lldb::addr_t vm_addr) const; + + const Section * + GetLinkedSection () const; + + uint64_t + GetLinkedOffset () const; + + lldb::addr_t + GetLinkedFileAddress () const; + + lldb::SectionType + GetSectionType () const + { + return m_type; + } + +protected: + + Section * m_parent; // Parent section or NULL if no parent. + ConstString m_name; // Name of this section + lldb::SectionType m_type; // The type of this section + lldb::addr_t m_file_addr; // The absolute file virtual address range of this section if m_parent == NULL, + // offset from parent file virtual address if m_parent != NULL + lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in memory at runtime + uint64_t m_file_offset; // Object file offset (if any) + uint64_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...) + SectionList m_children; // Child sections + bool m_fake; // If true, then this section only can contain the address if one of its + // children contains an address. This allows for gaps between the children + // that are contained in the address range for this section, but do not produce + // hits unless the children contain the address. + const Section * m_linked_section; + uint64_t m_linked_offset; +private: + DISALLOW_COPY_AND_ASSIGN (Section); +}; + + +} // namespace lldb_private + +#endif // liblldb_Section_h_ diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h new file mode 100644 index 00000000000..6c6fdfdd602 --- /dev/null +++ b/lldb/include/lldb/Core/SourceManager.h @@ -0,0 +1,120 @@ +//===-- SourceManager.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SourceManager_h_ +#define liblldb_SourceManager_h_ + +// C Includes +// C++ Includes +#include <map> +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/FileSpec.h" + +namespace lldb_private { + +class SourceManager +{ +public: +#ifndef SWIG + class File + { + public: + File (const FileSpec &file_spec); + ~File(); + + size_t + DisplaySourceLines (uint32_t line, + uint32_t context_before, + uint32_t context_after, + Stream *s); + + uint32_t + GetLineOffset (uint32_t line); + + bool + LineIsValid (uint32_t line); + + bool + FileSpecMatches (const FileSpec &file_spec); + + protected: + + bool + CalculateLineOffsets (uint32_t line = UINT32_MAX); + + FileSpec m_file_spec; + lldb::DataBufferSP m_data_sp; + typedef std::vector<uint32_t> LineOffsets; + LineOffsets m_offsets; + }; +#endif + + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SourceManager(); + + ~SourceManager(); + + typedef lldb::SharedPtr<File>::Type FileSP; + + FileSP + GetFile (const FileSpec &file_spec); + + size_t + DisplaySourceLines (const FileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + Stream *s); + + size_t + DisplaySourceLinesWithLineNumbers (const FileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char* current_line_cstr, + Stream *s); + + // This variant uses the last file we visited. + size_t + DisplaySourceLinesWithLineNumbersUsingLastFile (uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char* current_line_cstr, + Stream *s); + + size_t + DisplayMoreWithLineNumbers (Stream *s); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from SourceManager can see and modify these + //------------------------------------------------------------------ + typedef std::map <FileSpec, FileSP> FileCache; + FileCache m_file_cache; + FileSP m_last_file_sp; + uint32_t m_last_file_line; + uint32_t m_last_file_context_before; + uint32_t m_last_file_context_after; +private: + //------------------------------------------------------------------ + // For SourceManager only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (SourceManager); +}; + +} // namespace lldb_private + +#endif // liblldb_SourceManager_h_ diff --git a/lldb/include/lldb/Core/State.h b/lldb/include/lldb/Core/State.h new file mode 100644 index 00000000000..2b9372ecd7d --- /dev/null +++ b/lldb/include/lldb/Core/State.h @@ -0,0 +1,43 @@ +//===-- State.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_State_h_ +#define liblldb_State_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//------------------------------------------------------------------ +/// Converts a StateType to a C string. +/// +/// @param[in] state +/// The StateType object to convert. +/// +/// @return +/// A NULL terminated C string that describes \a state. The +/// returned string comes from constant string buffers and does +/// not need to be freed. +//------------------------------------------------------------------ +const char * +StateAsCString (lldb::StateType state); + +bool +StateIsRunningState (lldb::StateType state); + +bool +StateIsStoppedState (lldb::StateType state); + +} // namespace lldb_private + +#endif // liblldb_State_h_ diff --git a/lldb/include/lldb/Core/Stream.h b/lldb/include/lldb/Core/Stream.h new file mode 100644 index 00000000000..250bd1f2afd --- /dev/null +++ b/lldb/include/lldb/Core/Stream.h @@ -0,0 +1,599 @@ +//===-- Stream.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Stream_h_ +#define liblldb_Stream_h_ +#if defined(__cplusplus) + +#include "lldb/lldb-private.h" +#include "lldb/Core/Flags.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Stream Stream.h "lldb/Core/Stream.h" +/// @brief A stream class that can stream formatted output to a file. +//---------------------------------------------------------------------- +class Stream +{ +public: + //------------------------------------------------------------------ + /// \a m_flags bit values. + //------------------------------------------------------------------ + enum + { + eVerbose = (1 << 0), ///< If set, verbose logging is enabled + eDebug = (1 << 1), ///< If set, debug logging is enabled + eAddPrefix = (1 << 2), ///< Add number prefixes for binary, octal and hex when eBinary is clear + eBinary = (1 << 3), ///< Get and put data as binary instead of as the default string mode. + }; + + //------------------------------------------------------------------ + /// Construct with flags and address size and byte order. + /// + /// Construct with dump flags \a flags and the default address + /// size. \a flags can be any of the above enumeration logical OR'ed + /// together. + //------------------------------------------------------------------ + Stream (uint32_t flags, + uint32_t addr_size, + lldb::ByteOrder byte_order); + + //------------------------------------------------------------------ + /// Construct a default Stream, not binary, host byte order and + /// host addr size. + /// + //------------------------------------------------------------------ + Stream (); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + virtual + ~Stream (); + + //------------------------------------------------------------------ + // Subclasses must override these methods + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Flush the stream. + /// + /// Subclasses should flush the stream to make any output appear + /// if the stream has any buffering. + //------------------------------------------------------------------ + virtual void + Flush () = 0; + + //------------------------------------------------------------------ + /// Output character bytes to the stream. + /// + /// Appends \a src_len characters from the buffer \a src to the + /// stream. + /// + /// @param[in] src + /// A buffer containing at least \a src_len bytes of data. + /// + /// @param[in] src_len + /// A number of bytes to append to the stream. + /// + /// @return + /// The number of bytes that were appended to the stream. + //------------------------------------------------------------------ + virtual int + Write (const void *src, size_t src_len) = 0; + + //------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------ + int + PutChar (char ch); + + //------------------------------------------------------------------ + /// Set the byte_order value. + /// + /// Sets the byte order of the data to extract. Extracted values + /// will be swapped if necessary when decoding. + /// + /// @param[in] byte_order + /// The byte order value to use when extracting data. + /// + /// @return + /// The old byte order value. + //------------------------------------------------------------------ + lldb::ByteOrder + SetByteOrder (lldb::ByteOrder byte_order); + + //------------------------------------------------------------------ + /// Format a C string from a printf style format and variable + /// arguments and encode and append the resulting C string as hex + /// bytes. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Any additional arguments needed for the printf format string. + /// + /// @return + /// The number of bytes that were appended to the stream. + //------------------------------------------------------------------ + int + PrintfAsRawHex8 (const char *format, ...); + + //------------------------------------------------------------------ + /// Format a C string from a printf style format and variable + /// arguments and encode and append the resulting C string as hex + /// bytes. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Any additional arguments needed for the printf format string. + /// + /// @return + /// The number of bytes that were appended to the stream. + //------------------------------------------------------------------ + int + PutHex8 (uint8_t uvalue); + + int + PutNHex8 (size_t n, uint8_t uvalue); + + int + PutHex16 (uint16_t uvalue, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutHex32 (uint32_t uvalue, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutHex64 (uint64_t uvalue, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutMaxHex64 (uint64_t uvalue, + size_t byte_size, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + int + PutFloat (float f, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutDouble (double d, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutLongDouble (long double ld, + lldb::ByteOrder byte_order = lldb::eByteOrderInvalid); + + int + PutPointer (void *ptr); + + int + PutBytesAsRawHex8 (const void *src, + size_t src_len, + lldb::ByteOrder src_byte_order, + lldb::ByteOrder dst_byte_order); + + int + PutRawBytes (const void *s, size_t src_len, + lldb::ByteOrder src_byte_order, + lldb::ByteOrder dst_byte_order); + + int + PutCStringAsRawHex8 (const char *s); + + //------------------------------------------------------------------ + /// Output a NULL terminated C string \a cstr to the stream \a s. + /// + /// @param[in] cstr + /// A NULL terminated C string. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (const char *cstr); + + //------------------------------------------------------------------ + /// Output a pointer value \a p to the stream \a s. + /// + /// @param[in] p + /// A void pointer. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (void *p); + + //------------------------------------------------------------------ + /// Output a character \a ch to the stream \a s. + /// + /// @param[in] ch + /// A printable character value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (char ch); + + //------------------------------------------------------------------ + /// Output a uint8_t \a uval to the stream \a s. + /// + /// @param[in] uval + /// A uint8_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (uint8_t uval); + + //------------------------------------------------------------------ + /// Output a uint16_t \a uval to the stream \a s. + /// + /// @param[in] uval + /// A uint16_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (uint16_t uval); + + //------------------------------------------------------------------ + /// Output a uint32_t \a uval to the stream \a s. + /// + /// @param[in] uval + /// A uint32_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (uint32_t uval); + + //------------------------------------------------------------------ + /// Output a uint64_t \a uval to the stream \a s. + /// + /// @param[in] uval + /// A uint64_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (uint64_t uval); + + //------------------------------------------------------------------ + /// Output a int8_t \a sval to the stream \a s. + /// + /// @param[in] sval + /// A int8_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (int8_t sval); + + //------------------------------------------------------------------ + /// Output a int16_t \a sval to the stream \a s. + /// + /// @param[in] sval + /// A int16_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (int16_t sval); + + //------------------------------------------------------------------ + /// Output a int32_t \a sval to the stream \a s. + /// + /// @param[in] sval + /// A int32_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (int32_t sval); + + //------------------------------------------------------------------ + /// Output a int64_t \a sval to the stream \a s. + /// + /// @param[in] sval + /// A int64_t value. + /// + /// @return + /// A reference to this class so multiple things can be streamed + /// in one statement. + //------------------------------------------------------------------ + Stream& + operator<< (int64_t sval); + + //------------------------------------------------------------------ + /// Output an address value to this stream. + /// + /// Put an address \a addr out to the stream with optional \a prefix + /// and \a suffix strings. + /// + /// @param[in] addr + /// An address value. + /// + /// @param[in] addr_size + /// Size in bytes of the address, used for formatting. + /// + /// @param[in] prefix + /// A prefix C string. If NULL, no prefix will be output. + /// + /// @param[in] suffix + /// A suffix C string. If NULL, no suffix will be output. + //------------------------------------------------------------------ + void + Address (uint64_t addr, int addr_size, const char *prefix = NULL, const char *suffix = NULL); + + //------------------------------------------------------------------ + /// Output an address range to this stream. + /// + /// Put an address range \a lo_addr - \a hi_addr out to the stream + /// with optional \a prefix and \a suffix strings. + /// + /// @param[in] lo_addr + /// The start address of the address range. + /// + /// @param[in] hi_addr + /// The end address of the address range. + /// + /// @param[in] addr_size + /// Size in bytes of the address, used for formatting. + /// + /// @param[in] prefix + /// A prefix C string. If NULL, no prefix will be output. + /// + /// @param[in] suffix + /// A suffix C string. If NULL, no suffix will be output. + //------------------------------------------------------------------ + void + AddressRange(uint64_t lo_addr, uint64_t hi_addr, int addr_size, const char *prefix = NULL, const char *suffix = NULL); + + //------------------------------------------------------------------ + /// Output a C string to the stream with optional format. + /// + /// Print a C string \a cstr to the stream using the printf format + /// in \a format. + /// + /// @param[in] format + /// The printf style format to use when outputting the C string. + //------------------------------------------------------------------ + int + PutCString (const char *cstr); + + //------------------------------------------------------------------ + /// Output and End of Line character to the stream. + //------------------------------------------------------------------ + int + EOL(); + + //------------------------------------------------------------------ + /// Get the address size in bytes. + /// + /// @return + /// The size of an address in bytes that is used when outputting + /// address and pointer values to the stream. + //------------------------------------------------------------------ + uint8_t + GetAddressByteSize () const; + + //------------------------------------------------------------------ + /// Test if debug logging is enabled. + /// + /// @return + // \b true if the debug flag bit is set in this stream, \b + // false otherwise. + //------------------------------------------------------------------ + bool + GetDebug() const; + + //------------------------------------------------------------------ + /// The flags accessor. + /// + /// @return + /// A reference to the Flags member variable. + //------------------------------------------------------------------ + Flags& + GetFlags(); + + //------------------------------------------------------------------ + /// The flags const accessor. + /// + /// @return + /// A const reference to the Flags member variable. + //------------------------------------------------------------------ + const Flags& + GetFlags() const; + + //------------------------------------------------------------------ + /// Get the current indentation level. + /// + /// @return + /// The current indentation level as an integer. + //------------------------------------------------------------------ + int + GetIndentLevel () const; + + //------------------------------------------------------------------ + /// Test if verbose logging is enabled. + /// + /// @return + // \b true if the verbose flag bit is set in this stream, \b + // false otherwise. + //------------------------------------------------------------------ + bool + GetVerbose() const; + + //------------------------------------------------------------------ + /// Indent the current line in the stream. + /// + /// Indent the current line using the current indentation level and + /// print an optional string following the idenatation spaces. + /// + /// @param[in] s + /// A C string to print following the indentation. If NULL, just + /// output the indentation characters. + //------------------------------------------------------------------ + int + Indent(const char *s = NULL); + + //------------------------------------------------------------------ + /// Decrement the current indentation level. + //------------------------------------------------------------------ + void + IndentLess (int amount = 2); + + //------------------------------------------------------------------ + /// Increment the current indentation level. + //------------------------------------------------------------------ + void + IndentMore (int amount = 2); + + //------------------------------------------------------------------ + /// Output an offset value. + /// + /// Put an offset \a uval out to the stream using the printf format + /// in \a format. + /// + /// @param[in] offset + /// The offset value. + /// + /// @param[in] format + /// The printf style format to use when outputting the offset. + //------------------------------------------------------------------ + void + Offset (uint32_t offset, const char *format = "0x%8.8x: "); + + //------------------------------------------------------------------ + /// Output printf formatted output to the stream. + /// + /// Print some formatted output to the stream. + /// + /// @param[in] format + /// A printf style format string. + /// + /// @param[in] ... + /// Variable arguments that are needed for the printf style + /// format string \a format. + //------------------------------------------------------------------ + int + Printf (const char *format, ...); + + int + PrintfVarArg(const char *format, va_list args); + + //------------------------------------------------------------------ + /// Output a quoted C string value to the stream. + /// + /// Print a double quoted NULL terminated C string to the stream + /// using the printf format in \a format. + /// + /// @param[in] cstr + /// A NULL terminated C string value. + /// + /// @param[in] format + /// The optional C string format that can be overridden. + //------------------------------------------------------------------ + void + QuotedCString (const char *cstr, const char *format = "\"%s\""); + + //------------------------------------------------------------------ + /// Set the address size in bytes. + /// + /// @param[in] addr_size + /// The new size in bytes of an address to use when outputting + /// address and pointer values. + //------------------------------------------------------------------ + void + SetAddressByteSize (uint8_t addr_size); + + //------------------------------------------------------------------ + /// Set the current indentation level. + /// + /// @param[in] level + /// The new indentation level. + //------------------------------------------------------------------ + void + SetIndentLevel (int level); + + //------------------------------------------------------------------ + /// Output a SLEB128 number to the stream. + /// + /// Put an SLEB128 \a uval out to the stream using the printf format + /// in \a format. + /// + /// @param[in] uval + /// A uint64_t value that was extracted as a SLEB128 value. + /// + /// @param[in] format + /// The optional printf format that can be overridden. + //------------------------------------------------------------------ + int + PutSLEB128 (int64_t uval); + + //------------------------------------------------------------------ + /// Output a ULEB128 number to the stream. + /// + /// Put an ULEB128 \a uval out to the stream using the printf format + /// in \a format. + /// + /// @param[in] uval + /// A uint64_t value that was extracted as a ULEB128 value. + /// + /// @param[in] format + /// The optional printf format that can be overridden. + //------------------------------------------------------------------ + int + PutULEB128 (uint64_t uval); + + static void + UnitTest(Stream *s); + +private: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Flags m_flags; ///< Dump flags. + uint8_t m_addr_size; ///< Size of an address in bytes. + lldb::ByteOrder m_byte_order;///< Byte order to use when encoding scalar types. + int m_indent_level; ///< Indention level. + + int _PutHex8 (uint8_t uvalue, bool add_prefix); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Stream_h_ + diff --git a/lldb/include/lldb/Core/StreamFile.h b/lldb/include/lldb/Core/StreamFile.h new file mode 100644 index 00000000000..c83f3c2f01c --- /dev/null +++ b/lldb/include/lldb/Core/StreamFile.h @@ -0,0 +1,76 @@ +//===-- StreamFile.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StreamFile_h_ +#define liblldb_StreamFile_h_ + +// C Includes +// C++ Includes + +#include <string> + +// Other libraries and framework includes +// Project includes + +#include "lldb/Core/Stream.h" + +namespace lldb_private { + +class StreamFile : public Stream +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StreamFile (); + + StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, FILE *f); + + StreamFile (FILE *f); + + StreamFile (uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order, const char *path, const char *permissions = "w"); + + StreamFile (const char *path, const char *permissions = "w"); + + virtual + ~StreamFile(); + + void + Close (); + + bool + Open (const char *path, const char *permissions = "w"); + + virtual void + Flush (); + + virtual int + Write (const void *s, size_t length); + + FILE * + GetFileHandle (); + + void + SetFileHandle (FILE *file, bool close_file); + + const char * + GetFilePathname (); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from StreamFile can see and modify these + //------------------------------------------------------------------ + FILE* m_file; ///< File handle to dump to. + bool m_close_file; + std::string m_path_name; +}; + +} // namespace lldb_private + +#endif // liblldb_StreamFile_h_ diff --git a/lldb/include/lldb/Core/StreamString.h b/lldb/include/lldb/Core/StreamString.h new file mode 100644 index 00000000000..699c7493fe9 --- /dev/null +++ b/lldb/include/lldb/Core/StreamString.h @@ -0,0 +1,61 @@ +//===-- StreamString.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StreamString_h_ +#define liblldb_StreamString_h_ + +#include <string> + +#include "lldb/Core/Stream.h" + +namespace lldb_private { + +class StreamString : public Stream +{ +public: + StreamString (); + + StreamString (uint32_t flags, + uint32_t addr_size, + lldb::ByteOrder byte_order); + + virtual + ~StreamString (); + + virtual void + Flush (); + + virtual int + Write (const void *s, size_t length); + + void + Clear(); + + void + Dump(FILE *f); + + const char * + GetData () const; + + size_t + GetSize() const; + + std::string & + GetString(); + + const std::string & + GetString() const; + +protected: + std::string m_packet; + +}; + +} // namespace lldb_private +#endif // #ifndef liblldb_StreamString_h_ diff --git a/lldb/include/lldb/Core/StringList.h b/lldb/include/lldb/Core/StringList.h new file mode 100644 index 00000000000..0b29bef54bf --- /dev/null +++ b/lldb/include/lldb/Core/StringList.h @@ -0,0 +1,74 @@ +//===-- StringList.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StringList_h_ +#define liblldb_StringList_h_ + + +#include "lldb/Core/STLUtils.h" + +namespace lldb_private { + +class StringList +{ +public: + + StringList (); + + StringList (const char *str); + + StringList (const char **strv, int strc); + + virtual + ~StringList (); + + void + AppendString (const char *str); + + void + AppendString (const char *str, size_t str_len); + + void + AppendList (const char ** strv, int strc); + + void + AppendList (StringList strings); + + uint32_t + GetSize (); + + const char * + GetStringAtIndex (size_t idx); + + void + Clear (); + + void + LongestCommonPrefix (std::string &common_prefix); + + void + InsertStringAtIndex (size_t id, const char *str); + + void + DeleteStringAtIndex (size_t id); + + void + RemoveBlankLines (); + + size_t + SplitIntoLines (const char *lines, size_t len); + +private: + + STLStringArray m_strings; +}; + +} // namespace lldb_private + +#endif // liblldb_StringList_h_ diff --git a/lldb/include/lldb/Core/TTYState.h b/lldb/include/lldb/Core/TTYState.h new file mode 100644 index 00000000000..ad0b62f1b64 --- /dev/null +++ b/lldb/include/lldb/Core/TTYState.h @@ -0,0 +1,202 @@ +//===-- TTYState.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TTYState_h_ +#define liblldb_TTYState_h_ +#if defined(__cplusplus) + +#include <termios.h> +#include <stdint.h> + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class TTYState TTYState.h "lldb/Core/TTYState.h" +/// @brief A TTY state managment class. +/// +/// This class can be used to remember the TTY state for a file +/// descriptor and later restore that state as it originally was. +//---------------------------------------------------------------------- +class TTYState +{ +public: + //------------------------------------------------------------------ + /// Default constructor + //------------------------------------------------------------------ + TTYState(); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~TTYState(); + + //------------------------------------------------------------------ + /// Save the TTY state for \a fd. + /// + /// Save the current state of the TTY for the file descriptor "fd" + /// and if "save_process_group" is true, attempt to save the process + /// group info for the TTY. + /// + /// @param[in] fd + /// The file descriptor to save the state of. + /// + /// @param[in] save_process_group + /// If \b true, save the process group settings, else do not + /// save the process group setttings for a TTY. + /// + /// @return + /// Returns \b true if \a fd describes a TTY and if the state + /// was able to be saved, \b false otherwise. + //------------------------------------------------------------------ + bool + Save (int fd, bool save_process_group); + + //------------------------------------------------------------------ + /// Restore the TTY state to the cached state. + /// + /// Restore the state of the TTY using the cached values from a + /// previous call to TTYState::Save(int,bool). + /// + /// @return + /// Returns \b true if the TTY state was successfully restored, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + Restore () const; + + //------------------------------------------------------------------ + /// Test for valid cached TTY state information. + /// + /// @return + /// Returns \b true if this object has valid saved TTY state + /// settings that can be used to restore a previous state, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + IsValid() const; + +protected: + + //------------------------------------------------------------------ + /// Test if tflags is valid. + /// + /// @return + /// Returns \b true if \a m_tflags is valid and can be restored, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + TFlagsIsValid() const; + + //------------------------------------------------------------------ + /// Test if ttystate is valid. + /// + /// @return + /// Returns \b true if \a m_ttystate is valid and can be + /// restored, \b false otherwise. + //------------------------------------------------------------------ + bool + TTYStateIsValid() const; + + //------------------------------------------------------------------ + /// Test if the process group information is valid. + /// + /// @return + /// Returns \b true if \a m_process_group is valid and can be + /// restored, \b false otherwise. + //------------------------------------------------------------------ + bool + ProcessGroupIsValid() const; + + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + int m_fd; ///< File descriptor of the TTY. + int m_tflags; ///< Cached tflags information. + int m_ttystate_err; ///< Error value from call to save tflags. + struct termios m_ttystate; ///< Cached ttystate information. + lldb::pid_t m_process_group;///< Cached process group information. + +}; + +//---------------------------------------------------------------------- +/// @class TTYStateSwitcher TTYState.h "lldb/Core/TTYState.h" +/// @brief A TTY state switching class. +/// +/// This class can be used to remember 2 TTY states for a given file +/// descriptor and switch between the two states. +//---------------------------------------------------------------------- +class TTYStateSwitcher +{ +public: + //------------------------------------------------------------------ + /// Constructor + //------------------------------------------------------------------ + TTYStateSwitcher(); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~TTYStateSwitcher(); + + //------------------------------------------------------------------ + /// Get the number of possible states to save. + /// + /// @return + /// The number of states that this TTY switcher object contains. + //------------------------------------------------------------------ + uint32_t + GetNumberOfStates() const; + + //------------------------------------------------------------------ + /// Restore the TTY state for state at index \a idx. + /// + /// @return + /// Returns \b true if the TTY state was successfully restored, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + Restore (uint32_t idx) const; + + //------------------------------------------------------------------ + /// Save the TTY state information for the state at index \a idx. + /// The TTY state is saved for the file descriptor \a fd and + /// the process group information will also be saved if requested + /// by \a save_process_group. + /// + /// @param[in] idx + /// The index into the state array where the state should be + /// saved. + /// + /// @param[in] fd + /// The file descriptor for which to save the settings. + /// + /// @param[in] save_process_group + /// If \b true, save the process group information for the TTY. + /// + /// @return + /// Returns \b true if the save was successful, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + Save (uint32_t idx, int fd, bool save_process_group); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + mutable uint32_t m_currentState; ///< The currently active TTY state index. + TTYState m_ttystates[2]; ///< The array of TTY states that holds saved TTY info. +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef liblldb_TTYState_h_ diff --git a/lldb/include/lldb/Core/ThreadSafeSTLMap.h b/lldb/include/lldb/Core/ThreadSafeSTLMap.h new file mode 100644 index 00000000000..a8921e5a802 --- /dev/null +++ b/lldb/include/lldb/Core/ThreadSafeSTLMap.h @@ -0,0 +1,170 @@ +//===-- ThreadSafeSTLMap.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadSafeSTLMap_h_ +#define liblldb_ThreadSafeSTLMap_h_ + +// C Includes +// C++ Includes +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +template <typename _Key, typename _Tp> +class ThreadSafeSTLMap +{ +public: + typedef std::map<_Key,_Tp> collection; + typedef typename collection::iterator iterator; + typedef typename collection::const_iterator const_iterator; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ThreadSafeSTLMap() : + m_collection (), + m_mutex (Mutex::eMutexTypeRecursive) + { + } + + ~ThreadSafeSTLMap() + { + } + + size_t + Erase (const _Key& key) + { + Mutex::Locker locker(m_mutex); + return EraseNoLock (key); + } + + size_t + EraseNoLock (const _Key& key) + { + return m_collection.erase (key); + } + + bool + GetValueForKey (const _Key& key, _Tp &value) const + { + Mutex::Locker locker(m_mutex); + return GetValueForKeyNoLock (key, value); + } + + // Call this if you have already manually locked the mutex using the + // GetMutex() accessor + bool + GetValueForKeyNoLock (const _Key& key, _Tp &value) const + { + const_iterator pos = m_collection.find(key); + if (pos != m_collection.end()) + { + value = pos->second; + return true; + } + return false; + } + + bool + GetFirstKeyForValue (const _Tp &value, _Key& key) const + { + Mutex::Locker locker(m_mutex); + return GetFirstKeyForValueNoLock (value, key); + } + + bool + GetFirstKeyForValueNoLock (const _Tp &value, _Key& key) const + { + const_iterator pos, end = m_collection.end(); + for (pos = m_collection.begin(); pos != end; ++pos) + { + if (pos->second == value) + { + key = pos->first; + return true; + } + } + return false; + } + + bool + LowerBound (const _Key& key, + _Key& match_key, + _Tp &match_value, + bool decrement_if_not_equal) const + { + Mutex::Locker locker(m_mutex); + return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal); + } + + bool + LowerBoundNoLock (const _Key& key, + _Key& match_key, + _Tp &match_value, + bool decrement_if_not_equal) const + { + const_iterator pos = m_collection.lower_bound (key); + if (pos != m_collection.end()) + { + match_key = pos->first; + if (decrement_if_not_equal && key != match_key && pos != m_collection.begin()) + { + --pos; + match_key = pos->first; + } + match_value = pos->second; + return true; + } + return false; + } + + iterator + lower_bound_unsafe (const _Key& key) + { + return m_collection.lower_bound (key); + } + + void + SetValueForKey (const _Key& key, const _Tp &value) + { + Mutex::Locker locker(m_mutex); + SetValueForKeyNoLock (key, value); + } + + // Call this if you have already manually locked the mutex using the + // GetMutex() accessor + void + SetValueForKeyNoLock (const _Key& key, const _Tp &value) + { + m_collection[key] = value; + } + + Mutex & + GetMutex () + { + return m_mutex; + } + +private: + collection m_collection; + mutable Mutex m_mutex; + + //------------------------------------------------------------------ + // For ThreadSafeSTLMap only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLMap); +}; + + +} // namespace lldb_private + +#endif // liblldb_ThreadSafeSTLMap_h_ diff --git a/lldb/include/lldb/Core/ThreadSafeValue.h b/lldb/include/lldb/Core/ThreadSafeValue.h new file mode 100644 index 00000000000..42a5a5c6725 --- /dev/null +++ b/lldb/include/lldb/Core/ThreadSafeValue.h @@ -0,0 +1,96 @@ +//===-- ThreadSafeValue.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadSafeValue_h_ +#define liblldb_ThreadSafeValue_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +template <class T> +class ThreadSafeValue +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ThreadSafeValue() : + m_value (), + m_mutex (Mutex::eMutexTypeRecursive) + { + } + + ThreadSafeValue(const T& value) : + m_value (value), + m_mutex (Mutex::eMutexTypeRecursive) + { + } + + ~ThreadSafeValue() + { + } + + T + GetValue () const + { + T value; + { + Mutex::Locker locker(m_mutex); + value = m_value; + } + return value; + } + + // Call this if you have already manually locked the mutex using the + // GetMutex() accessor + const T& + GetValueNoLock () const + { + return m_value; + } + + void + SetValue (const T& value) + { + Mutex::Locker locker(m_mutex); + m_value = value; + } + + // Call this if you have already manually locked the mutex using the + // GetMutex() accessor + void + SetValueNoLock (const T& value) + { + m_value = value; + } + + Mutex & + GetMutex () + { + return m_mutex; + } + +private: + T m_value; + mutable Mutex m_mutex; + + //------------------------------------------------------------------ + // For ThreadSafeValue only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ThreadSafeValue); +}; + + +} // namespace lldb_private +#endif // liblldb_ThreadSafeValue_h_ diff --git a/lldb/include/lldb/Core/Timer.h b/lldb/include/lldb/Core/Timer.h new file mode 100644 index 00000000000..50c8fdfd386 --- /dev/null +++ b/lldb/include/lldb/Core/Timer.h @@ -0,0 +1,93 @@ +//===-- Timer.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Timer_h_ +#define liblldb_Timer_h_ +#if defined(__cplusplus) + +#include <memory> +#include "lldb/lldb-private.h" +#include "lldb/Host/TimeValue.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Timer Timer.h "lldb/Core/Timer.h" +/// @brief A timer class that simplifies common timing metrics. +/// +/// A scoped timer class that allows a variety of pthread mutex +/// objects to have a mutex locked when an Timer::Locker +/// object is created, and unlocked when it goes out of scope or +/// when the Timer::Locker::Reset(pthread_mutex_t *) +/// is called. This provides an exception safe way to lock a mutex +/// in a scope. +//---------------------------------------------------------------------- + +class Timer +{ +public: + static void + Initialize (); + + //-------------------------------------------------------------- + /// Default constructor. + //-------------------------------------------------------------- + Timer(const char *category, const char *format, ...); + + //-------------------------------------------------------------- + /// Desstructor + //-------------------------------------------------------------- + ~Timer(); + + void + Dump (); + + static void + SetDisplayDepth (uint32_t depth); + + static void + DumpCategoryTimes (Stream *s); + + static void + ResetCategoryTimes (); + +protected: + + void + ChildStarted (const TimeValue& time); + + void + ChildStopped (const TimeValue& time); + + uint64_t + GetTotalElapsedNanoSeconds(); + + uint64_t + GetTimerElapsedNanoSeconds(); + + //-------------------------------------------------------------- + /// Member variables + //-------------------------------------------------------------- + const char *m_category; + TimeValue m_total_start; + TimeValue m_timer_start; + uint64_t m_total_ticks; // Total running time for this timer including when other timers below this are running + uint64_t m_timer_ticks; // Ticks for this timer that do not include when other timers below this one are running + static uint32_t g_depth; + static uint32_t g_display_depth; + static FILE * g_file; +private: + Timer(); + DISALLOW_COPY_AND_ASSIGN (Timer); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef liblldb_Timer_h_ diff --git a/lldb/include/lldb/Core/UUID.h b/lldb/include/lldb/Core/UUID.h new file mode 100644 index 00000000000..6e3402b9e74 --- /dev/null +++ b/lldb/include/lldb/Core/UUID.h @@ -0,0 +1,80 @@ +//===-- UUID.h --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_UUID_h_ +#define liblldb_UUID_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class UUID +{ +public: + typedef uint8_t ValueType[16]; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + UUID (); + UUID (const UUID& rhs); + UUID (const void *uuid_bytes, uint32_t num_uuid_bytes); + UUID (const uuid_t *uuid); + + ~UUID (); + + const UUID& + operator=(const UUID& rhs); + + void + Clear (); + + void + Dump (Stream *s) const; + + const void * + GetBytes() const; + + static size_t + GetByteSize(); + + bool + IsValid () const; + + void + SetBytes (const void *uuid_bytes); + + char * + GetAsCString (char *dst, size_t dst_len) const; + + size_t + SetfromCString (const char *c_str); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from UUID can see and modify these + //------------------------------------------------------------------ + ValueType m_uuid; +}; + +bool operator == (const UUID &lhs, const UUID &rhs); +bool operator != (const UUID &lhs, const UUID &rhs); +bool operator < (const UUID &lhs, const UUID &rhs); +bool operator <= (const UUID &lhs, const UUID &rhs); +bool operator > (const UUID &lhs, const UUID &rhs); +bool operator >= (const UUID &lhs, const UUID &rhs); + +} // namespace lldb_private + +#endif // liblldb_UUID_h_ diff --git a/lldb/include/lldb/Core/UniqueCStringMap.h b/lldb/include/lldb/Core/UniqueCStringMap.h new file mode 100644 index 00000000000..34b91f30a6d --- /dev/null +++ b/lldb/include/lldb/Core/UniqueCStringMap.h @@ -0,0 +1,232 @@ +//===-- UniqueCStringMap.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_UniqueCStringMap_h_ +#define liblldb_UniqueCStringMap_h_ +#if defined(__cplusplus) + +#include <assert.h> +#include <algorithm> +#include <vector> + +namespace lldb_private { + + + +//---------------------------------------------------------------------- +// Templatized uniqued string map. +// +// This map is useful for mapping unique C string names to values of +// type T. Each "const char *" name added must be unique for a given +// C string value. ConstString::GetCString() can provide such strings. +// Any other string table that has guaranteed unique values can also +// be used. +//---------------------------------------------------------------------- +template <typename T> +class UniqueCStringMap +{ +public: + struct Entry + { + Entry () : + cstring(NULL), + value() + { + } + + Entry (const char *cstr) : + cstring(cstr), + value() + { + } + + Entry (const char *cstr, const T&v) : + cstring(cstr), + value(v) + { + } + + bool + operator < (const Entry& rhs) const + { + return cstring < rhs.cstring; + } + + const char* cstring; + T value; + }; + + //------------------------------------------------------------------ + // Call this function multiple times to add a bunch of entries to + // this map, then later call UniqueCStringMap<T>::Sort() before doing + // any searches by name. + //------------------------------------------------------------------ + void + Append (const char *unique_cstr, const T& value) + { + m_map.push_back (typename UniqueCStringMap<T>::Entry(unique_cstr, value)); + } + + void + Append (const Entry &e) + { + m_map.push_back (e); + } + + void + Clear () + { + m_map.clear(); + } + + //------------------------------------------------------------------ + // Call this function to always keep the map sorted when putting + // entries into the map. + //------------------------------------------------------------------ + void + Insert (const char *unique_cstr, const T& value) + { + typename UniqueCStringMap<T>::Entry e(unique_cstr, value); + m_map.insert (std::upper_bound (m_map.begin(), m_map.end(), e), e); + } + + void + Insert (const Entry &e) + { + m_map.insert (std::upper_bound (m_map.begin(), m_map.end(), e), e); + } + + //------------------------------------------------------------------ + // Get an entry by index. + // + // The caller is responsible for ensuring that the collection does + // not change during while using the returned pointer. + //------------------------------------------------------------------ + const T * + GetValueAtIndex (uint32_t idx) const + { + if (idx < m_map.size()) + return &m_map[idx].value; + return NULL; + } + + const char * + GetCStringAtIndex (uint32_t idx) const + { + if (idx < m_map.size()) + return m_map[idx].cstring; + return NULL; + } + + //------------------------------------------------------------------ + // Get a pointer to the first entry that matches "name". NULL will + // be returned if there is no entry that matches "name". + // + // The caller is responsible for ensuring that the collection does + // not change during while using the returned pointer. + //------------------------------------------------------------------ + const Entry * + FindFirstValueForName (const char *unique_cstr) const + { + Entry search_entry (unique_cstr); + const_iterator end = m_map.end(); + const_iterator pos = std::lower_bound (m_map.begin(), end, search_entry); + if (pos != end) + { + const char *pos_cstr = pos->cstring; + if (pos_cstr == unique_cstr) + return &(*pos); + } + return NULL; + } + + //------------------------------------------------------------------ + // Get a pointer to the next entry that matches "name" from a + // previously returned Entry pointer. NULL will be returned if there + // is no subsequent entry that matches "name". + // + // The caller is responsible for ensuring that the collection does + // not change during while using the returned pointer. + //------------------------------------------------------------------ + const Entry * + FindNextValueForName (const char *unique_cstr, const Entry *entry_ptr) const + { + const Entry *first_entry = m_map.data(); + const Entry *after_last_entry = first_entry + m_map.size(); + const Entry *next_entry = entry_ptr + 1; + if (first_entry <= next_entry && next_entry < after_last_entry) + { + if (next_entry->cstring == unique_cstr) + return next_entry; + } + return NULL; + } + + //------------------------------------------------------------------ + // Get the total number of entries in this map. + //------------------------------------------------------------------ + size_t + GetSize () + { + return m_map.size(); + } + + + //------------------------------------------------------------------ + // Returns true if this map is empty. + //------------------------------------------------------------------ + bool + IsEmpty() const + { + return m_map.empty(); + } + + //------------------------------------------------------------------ + // Reserve memory for at least "n" entries in the map. This is + // useful to call when you know you will be adding a lot of entries + // using UniqueCStringMap::Append() (which should be followed by a + // call to UniqueCStringMap::Sort()) or to UniqueCStringMap::Insert(). + //------------------------------------------------------------------ + void + Reserve (size_t n) + { + m_map.reserve (n); + } + + //------------------------------------------------------------------ + // Sort the unsorted contents in this map. A typical code flow would + // be: + // size_t approximate_num_entries = .... + // UniqueCStringMap<uint32_t> my_map; + // my_map.Reserve (approximate_num_entries); + // for (...) + // { + // my_map.Append (UniqueCStringMap::Entry(GetName(...), GetValue(...))); + // } + // my_map.Sort(); + //------------------------------------------------------------------ + void + Sort () + { + std::sort (m_map.begin(), m_map.end()); + } + +protected: + typedef std::vector<Entry> collection; + typedef typename collection::iterator iterator; + typedef typename collection::const_iterator const_iterator; + collection m_map; +}; + + + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_UniqueCStringMap_h_ diff --git a/lldb/include/lldb/Core/UserID.h b/lldb/include/lldb/Core/UserID.h new file mode 100644 index 00000000000..a12884afe6d --- /dev/null +++ b/lldb/include/lldb/Core/UserID.h @@ -0,0 +1,123 @@ +//===-- UserID.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_UserID_h_ +#define liblldb_UserID_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class UserID UserID.h "lldb/Core/UserID.h" +/// @brief A mix in class that contains a generic user ID. +/// +/// UserID is desinged as a mix in class that can contain an integer +/// based unique identifier for a varietly of objects in lldb. +/// +/// The value for this identifier is chosen by each parser plug-in. A +/// value should be chosen that makes sense for each kind of object +/// should and allows quick access to further and more in depth parsing. +/// +/// Symbol table entries can use this to store the original symbol table +/// index, functions can use it to store the symbol table index or the +/// DWARF offset. +//---------------------------------------------------------------------- +struct UserID +{ + //------------------------------------------------------------------ + /// Construct with optional user ID. + //------------------------------------------------------------------ + UserID (lldb::user_id_t uid = LLDB_INVALID_UID); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual in case this class is subclassed. + //------------------------------------------------------------------ + virtual + ~UserID (); + + //------------------------------------------------------------------ + /// Clears the object state. + /// + /// Clears the object contents back to a default invalid state. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Get accessor for the user ID. + /// + /// @return + /// The user ID. + //------------------------------------------------------------------ + lldb::user_id_t + GetID () const; + + //------------------------------------------------------------------ + /// Set accessor for the user ID. + /// + /// @param[in] uid + /// The new user ID. + //------------------------------------------------------------------ + void + SetID (lldb::user_id_t uid); + + //------------------------------------------------------------------ + /// Unary predicate function object that can search for a matching + /// user ID. + /// + /// Function object that can be used on any class that inherits + /// from UserID: + /// \code + /// iterator pos; + /// pos = std::find_if (coll.begin(), coll.end(), UserID::IDMatches(blockID)); + /// \endcode + //------------------------------------------------------------------ + class IDMatches + { + public: + //-------------------------------------------------------------- + /// Construct with the user ID to look for. + //-------------------------------------------------------------- + IDMatches (lldb::user_id_t uid); + + //-------------------------------------------------------------- + /// Unary predicate function object callback. + //-------------------------------------------------------------- + bool + operator () (const UserID& rhs) const; + + private: + //-------------------------------------------------------------- + // Member variables. + //-------------------------------------------------------------- + const lldb::user_id_t m_uid; ///< The user ID we are looking for + }; + + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + lldb::user_id_t m_uid; ///< The user ID that uniquely identifies an object. +}; + +//-------------------------------------------------------------- +/// Stream the UserID object to a Stream. +//-------------------------------------------------------------- +bool operator== (const UserID& lhs, const UserID& rhs); +bool operator!= (const UserID& lhs, const UserID& rhs); +Stream& operator << (Stream& strm, const UserID& uid); + +} // namespace lldb_private + +#endif // liblldb_UserID_h_ diff --git a/lldb/include/lldb/Core/VMRange.h b/lldb/include/lldb/Core/VMRange.h new file mode 100644 index 00000000000..b97059f2577 --- /dev/null +++ b/lldb/include/lldb/Core/VMRange.h @@ -0,0 +1,165 @@ +//===-- VMRange.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_VMRange_h_ +#define liblldb_VMRange_h_ + +#include "lldb/lldb-private.h" +#include <vector> + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A vm address range. These can represent offsets ranges or actual +// addresses. +//---------------------------------------------------------------------- +class VMRange +{ +public: + + typedef std::vector<VMRange> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + VMRange() : + m_base_addr(0), + m_byte_size(0) + { + } + + VMRange(lldb::addr_t start_addr, lldb::addr_t end_addr) : + m_base_addr(start_addr), + m_byte_size(end_addr > start_addr ? end_addr - start_addr : 0) + { + } + + ~VMRange() + { + } + + // Set the start and end values + void Reset (lldb::addr_t start_addr, lldb::addr_t end_addr) + { + SetBaseAddress (start_addr); + SetEndAddress (end_addr); + } + + // Set the start value for the range, and keep the same size + void SetBaseAddress (lldb::addr_t base_addr) + { + m_base_addr = base_addr; + } + + void SetEndAddress (lldb::addr_t end_addr) + { + const lldb::addr_t base_addr = GetBaseAddress(); + if (end_addr > base_addr) + m_byte_size = end_addr - base_addr; + else + m_byte_size = 0; + } + + lldb::addr_t + GetByteSize () const + { + return m_byte_size; + } + + void + SetByteSize (lldb::addr_t byte_size) + { + m_byte_size = byte_size; + } + + lldb::addr_t + GetBaseAddress () const + { + return m_base_addr; + } + + lldb::addr_t + GetEndAddress () const + { + return GetBaseAddress() + m_byte_size; + } + + bool + IsValid() const + { + return GetByteSize() > 0; + } + + bool + Contains (lldb::addr_t addr) const + { + return (GetBaseAddress() <= addr) && (addr < GetEndAddress()); + } + + bool Contains (const VMRange& range) const + { + if (Contains(range.GetBaseAddress())) + { + lldb::addr_t range_end = range.GetEndAddress(); + return (GetBaseAddress() <= range_end) && (range_end <= GetEndAddress()); + } + return false; + } + + void + Dump(Stream *s, lldb::addr_t base_addr = 0) const; + + class ValueInRangeUnaryPredicate + { + public: + ValueInRangeUnaryPredicate(lldb::addr_t value) : + _value(value) + { + } + bool operator()(const VMRange& range) const + { + return range.Contains(_value); + } + lldb::addr_t _value; + }; + + class RangeInRangeUnaryPredicate + { + public: + RangeInRangeUnaryPredicate(VMRange range) : + _range(range) + { + } + bool operator()(const VMRange& range) const + { + return range.Contains(_range); + } + const VMRange& _range; + }; + + static bool + ContainsValue(const VMRange::collection& coll, lldb::addr_t value); + + static bool + ContainsRange(const VMRange::collection& coll, const VMRange& range); + +protected: + lldb::addr_t m_base_addr; + lldb::addr_t m_byte_size; +}; + +bool operator== (const VMRange& lhs, const VMRange& rhs); +bool operator!= (const VMRange& lhs, const VMRange& rhs); +bool operator< (const VMRange& lhs, const VMRange& rhs); +bool operator<= (const VMRange& lhs, const VMRange& rhs); +bool operator> (const VMRange& lhs, const VMRange& rhs); +bool operator>= (const VMRange& lhs, const VMRange& rhs); + +} // namespace lldb_private + +#endif // liblldb_VMRange_h_ diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h new file mode 100644 index 00000000000..9aaf44abc72 --- /dev/null +++ b/lldb/include/lldb/Core/Value.h @@ -0,0 +1,172 @@ +//===-- Value.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Value_h_ +#define liblldb_Value_h_ + +// C Includes +// C++ Includes +#include <vector> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Scalar.h" + +namespace lldb_private { + +class Value +{ +public: + + // Values Less than zero are an error, greater than or equal to zero + // returns what the Scalar result is. + enum ValueType + { + // m_value contains... + // ============================ + eValueTypeScalar, // raw scalar value + eValueTypeFileAddress, // file address value + eValueTypeLoadAddress, // load address value + eValueTypeHostAddress, // host address value (for memory in the process that is using liblldb) + }; + + enum ContextType // Type that describes Value::m_context + { + // m_context contains... + // ==================== + eContextTypeInvalid, // undefined + eContextTypeOpaqueClangQualType,// void * (an opaque clang::QualType * that can be fed to "static QualType QualType::getFromOpaquePtr(void *)") + eContextTypeDCRegisterInfo, // lldb::RegisterInfo * + eContextTypeDCType, // Type * + eContextTypeDCVariable, // Variable * + eContextTypeValue // Value * (making this a proxy value. Used when putting locals on the DWARF expression parser stack) + }; + + Value(); + Value(const Scalar& scalar); + Value(int v); + Value(unsigned int v); + Value(long v); + Value(unsigned long v); + Value(long long v); + Value(unsigned long long v); + Value(float v); + Value(double v); + Value(long double v); + Value(const uint8_t *bytes, int len); + Value(const Value &v); + + Value * + CreateProxy(); + + Value * + GetProxyTarget(); + + void * + GetOpaqueClangQualType(); + + ValueType + GetValueType() const; + + lldb::AddressType + GetValueAddressType () const; + + ContextType + GetContextType() const; + + void + SetValueType (ValueType value_type); + + void + ClearContext (); + + void + SetContext (ContextType context_type, void *p); + + lldb::RegisterInfo * + GetRegisterInfo(); + + Type * + GetType(); + + Scalar & + ResolveValue (ExecutionContext *exe_ctx, clang::ASTContext *ast_context); + + Scalar & + GetScalar(); + + void + ResizeData(int len); + + bool + ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context); + + Variable * + GetVariable(); + + void + Dump (Stream* strm); + + lldb::Format + GetValueDefaultFormat (); + + void * + GetValueOpaqueClangQualType (); + + size_t + GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr); + + Error + GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset); + + static const char * + GetValueTypeAsCString (ValueType context_type); + + static const char * + GetContextTypeAsCString (ContextType context_type); + +protected: + Scalar m_value; + ValueType m_value_type; + void * m_context; + ContextType m_context_type; + DataBufferHeap m_data_buffer; +}; + +class ValueList +{ +public: + ValueList () {} + ValueList (const ValueList &rhs); + + ~ValueList () {} + + const ValueList & operator= (const ValueList &rhs); + + // void InsertValue (Value *value, size_t idx); + void PushValue (const Value &value); + + size_t GetSize (); + Value *GetValueAtIndex(size_t idx); + void Clear(); + +protected: + +private: + typedef std::vector<Value> collection; + + collection m_values; +}; + +} // namespace lldb_private + +#endif // liblldb_Value_h_ diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h new file mode 100644 index 00000000000..75ae31bdffb --- /dev/null +++ b/lldb/include/lldb/Core/ValueObject.h @@ -0,0 +1,230 @@ +//===-- ValueObject.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObject_h_ +#define liblldb_ValueObject_h_ + +// C Includes +// C++ Includes +#include <map> +#include <vector> +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/UserID.h" +#include "lldb/Core/Value.h" +#include "lldb/Target/ExecutionContextScope.h" + +namespace lldb_private { + +class ValueObject : public UserID +{ +public: + friend class ValueObjectList; + + virtual ~ValueObject(); + + //------------------------------------------------------------------ + // Sublasses must implement the functions below. + //------------------------------------------------------------------ + virtual size_t + GetByteSize() = 0; + + virtual clang::ASTContext * + GetClangAST () = 0; + + virtual void * + GetOpaqueClangQualType () = 0; + + virtual lldb::ValueType + GetValueType() const = 0; + +protected: + // Should only be called by ValueObject::GetNumChildren() + virtual uint32_t + CalculateNumChildren() = 0; + +public: + virtual ConstString + GetTypeName() = 0; + + virtual void + UpdateValue (ExecutionContextScope *exe_scope) = 0; + + //------------------------------------------------------------------ + // Sublasses can implement the functions below if they need to. + //------------------------------------------------------------------ +protected: + // Should only be called by ValueObject::GetChildAtIndex() + virtual lldb::ValueObjectSP + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + +public: + + virtual bool + IsPointerType (); + + virtual bool + IsPointerOrReferenceType (); + + virtual bool + IsInScope (StackFrame *frame) + { + return true; + } + + virtual off_t + GetByteOffset() + { + return 0; + } + + virtual uint32_t + GetBitfieldBitSize() + { + return 0; + } + + virtual uint32_t + GetBitfieldBitOffset() + { + return 0; + } + + virtual const char * + GetValueAsCString (ExecutionContextScope *exe_scope); + + virtual bool + SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str); + + //------------------------------------------------------------------ + // The functions below should NOT be modified by sublasses + //------------------------------------------------------------------ + const Error & + GetError() const; + + const ConstString & + GetName() const; + + lldb::ValueObjectSP + GetChildAtIndex (uint32_t idx, bool can_create); + + lldb::ValueObjectSP + GetChildMemberWithName (const ConstString &name, bool can_create); + + uint32_t + GetIndexOfChildWithName (const ConstString &name); + + uint32_t + GetNumChildren (); + + const Value & + GetValue() const; + + Value & + GetValue(); + + const char * + GetLocationAsCString (ExecutionContextScope *exe_scope); + + const char * + GetSummaryAsCString (ExecutionContextScope *exe_scope); + + lldb::user_id_t + GetUpdateID() const; + + bool + GetValueIsValid (); + + bool + GetValueDidChange () const; + + bool + UpdateValueIfNeeded (ExecutionContextScope *exe_scope); + + const DataExtractor & + GetDataExtractor () const; + + DataExtractor & + GetDataExtractor (); + + bool + Write (); + + void + AddSyntheticChild (const ConstString &key, + lldb::ValueObjectSP& valobj_sp); + + lldb::ValueObjectSP + GetSyntheticChild (const ConstString &key) const; + + lldb::ValueObjectSP + GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create); + +protected: + enum { + eValueChanged = (1 << 0), + eNumChildrenHasBeenSet = (1 << 1), + eValueIsValid = (1 << 2) + }; + //------------------------------------------------------------------ + // Classes that inherit from ValueObject can see and modify these + //------------------------------------------------------------------ + lldb::user_id_t m_update_id; // An integer that specifies the update number for this value in + // this value object list. If this value object is asked to update itself + // it will first check if the update ID match the value object + // list update number. If the update numbers match, no update is + // needed, if it does not match, this value object should update its + // the next time it is asked. + ConstString m_name; // The name of this object + DataExtractor m_data; // A data extractor that can be used to extract the value. + Value m_value; + Error m_error; // An error object that can describe any errors that occur when updating values. + Flags m_flags; // A boolean that indicates this value has changed + std::string m_value_str; // Cached value string that will get cleared if/when the value is updated. + std::string m_location_str; // Cached location string that will get cleared if/when the value is updated. + std::string m_summary_str; // Cached summary string that will get cleared if/when the value is updated. + std::vector<lldb::ValueObjectSP> m_children; + std::map<ConstString, lldb::ValueObjectSP> m_synthetic_children; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ValueObject (); + + void + SetName (const char *name); + + void + SetName (const ConstString &name); + + void + SetNumChildren (uint32_t num_children); + + void + SetValueDidChange (bool value_changed); + + void + SetValueIsValid (bool valid); + +private: + //------------------------------------------------------------------ + // For ValueObject only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ValueObject); + +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObject_h_ diff --git a/lldb/include/lldb/Core/ValueObjectChild.h b/lldb/include/lldb/Core/ValueObjectChild.h new file mode 100644 index 00000000000..b5f842cfba9 --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectChild.h @@ -0,0 +1,95 @@ +//===-- ValueObjectChild.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObjectChild_h_ +#define liblldb_ValueObjectChild_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "clang/AST/Type.h" +// Project includes +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A child of another ValueObject. +//---------------------------------------------------------------------- +class ValueObjectChild : public ValueObject +{ +public: + ValueObjectChild (ValueObject *parent, + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + uint32_t byte_size, + int32_t byte_offset, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset); + + + virtual ~ValueObjectChild(); + + virtual size_t + GetByteSize(); + + virtual off_t + GetByteOffset(); + + virtual uint32_t + GetBitfieldBitSize(); + + virtual uint32_t + GetBitfieldBitOffset(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetOpaqueClangQualType (); + + virtual lldb::ValueType + GetValueType() const; + + virtual uint32_t + CalculateNumChildren(); + + virtual ConstString + GetTypeName(); + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + + virtual bool + IsInScope (StackFrame *frame); + +protected: + ValueObject* m_parent; // The parent value object of which this is a child of. + clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from + void *m_clang_type; // The type of the child in question within the parent (m_parent_sp) + ConstString m_type_name; + uint32_t m_byte_size; + int32_t m_byte_offset; + uint32_t m_bitfield_bit_size; + uint32_t m_bitfield_bit_offset; + + uint32_t + GetByteOffset() const; +// +// void +// ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); + +private: + DISALLOW_COPY_AND_ASSIGN (ValueObjectChild); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectChild_h_ diff --git a/lldb/include/lldb/Core/ValueObjectList.h b/lldb/include/lldb/Core/ValueObjectList.h new file mode 100644 index 00000000000..b312790acab --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectList.h @@ -0,0 +1,74 @@ +//===-- ValueObjectList.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObjectList_h_ +#define liblldb_ValueObjectList_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/UserID.h" +#include "lldb/Target/ExecutionContextScope.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A collection of ValueObject values that +//---------------------------------------------------------------------- +class ValueObjectList +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ValueObjectList (); + + ValueObjectList (const ValueObjectList &rhs); + + ~ValueObjectList(); + + const ValueObjectList & + operator = (const ValueObjectList &rhs); + + void + Append (const lldb::ValueObjectSP &val_obj_sp); + + lldb::ValueObjectSP + FindValueObjectByPointer (ValueObject *valobj); + + uint32_t + GetSize() const; + + lldb::ValueObjectSP + GetValueObjectAtIndex (uint32_t); + + lldb::ValueObjectSP + FindValueObjectByValueName (const char *name); + + lldb::ValueObjectSP + FindValueObjectByUID (lldb::user_id_t uid); + +protected: + typedef std::vector<lldb::ValueObjectSP> collection; + //------------------------------------------------------------------ + // Classes that inherit from ValueObjectList can see and modify these + //------------------------------------------------------------------ + collection m_value_objects; + +}; + + +} // namespace lldb_private + +#endif // liblldb_ValueObjectList_h_ diff --git a/lldb/include/lldb/Core/ValueObjectRegister.h b/lldb/include/lldb/Core/ValueObjectRegister.h new file mode 100644 index 00000000000..fe3ac480caa --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectRegister.h @@ -0,0 +1,168 @@ +//===-- ValueObjectRegister.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObjectRegister_h_ +#define liblldb_ValueObjectRegister_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A ValueObject that contains a root variable that may or may not +// have children. +//---------------------------------------------------------------------- +class ValueObjectRegisterContext : public ValueObject +{ +public: + ValueObjectRegisterContext (RegisterContext *reg_ctx); + + virtual + ~ValueObjectRegisterContext(); + + virtual size_t + GetByteSize(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetOpaqueClangQualType (); + + virtual lldb::ValueType + GetValueType () const + { + return lldb::eValueTypeRegisterSet; + } + + virtual ConstString + GetTypeName(); + + virtual uint32_t + CalculateNumChildren(); + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + + virtual lldb::ValueObjectSP + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + +protected: + RegisterContext *m_reg_ctx; + +private: + //------------------------------------------------------------------ + // For ValueObject only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ValueObjectRegisterContext); +}; + +class ValueObjectRegisterSet : public ValueObject +{ +public: + ValueObjectRegisterSet (RegisterContext *reg_ctx, uint32_t set_idx); + + virtual + ~ValueObjectRegisterSet(); + + virtual size_t + GetByteSize(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetOpaqueClangQualType (); + + virtual lldb::ValueType + GetValueType () const + { + return lldb::eValueTypeRegisterSet; + } + + virtual ConstString + GetTypeName(); + + virtual uint32_t + CalculateNumChildren(); + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + + virtual lldb::ValueObjectSP + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + +protected: + + RegisterContext *m_reg_ctx; + const lldb::RegisterSet *m_reg_set; + uint32_t m_reg_set_idx; + +private: + //------------------------------------------------------------------ + // For ValueObject only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ValueObjectRegisterSet); +}; + +class ValueObjectRegister : public ValueObject +{ +public: + ValueObjectRegister (RegisterContext *reg_ctx, uint32_t reg_num); + + virtual + ~ValueObjectRegister(); + + virtual size_t + GetByteSize(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetOpaqueClangQualType (); + + virtual lldb::ValueType + GetValueType () const + { + return lldb::eValueTypeRegister; + } + + virtual ConstString + GetTypeName(); + + virtual uint32_t + CalculateNumChildren(); + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + +protected: + + RegisterContext *m_reg_ctx; + const lldb::RegisterInfo *m_reg_info; + uint32_t m_reg_num; + ConstString m_type_name; + void *m_clang_type; + +private: + //------------------------------------------------------------------ + // For ValueObject only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ValueObjectRegister); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectRegister_h_ diff --git a/lldb/include/lldb/Core/ValueObjectVariable.h b/lldb/include/lldb/Core/ValueObjectVariable.h new file mode 100644 index 00000000000..80e0d05272e --- /dev/null +++ b/lldb/include/lldb/Core/ValueObjectVariable.h @@ -0,0 +1,70 @@ +//===-- ValueObjectVariable.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ValueObjectVariable_h_ +#define liblldb_ValueObjectVariable_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A ValueObject that contains a root variable that may or may not +// have children. +//---------------------------------------------------------------------- +class ValueObjectVariable : public ValueObject +{ +public: + ValueObjectVariable (lldb::VariableSP &var_sp); + + virtual + ~ValueObjectVariable(); + + virtual size_t + GetByteSize(); + + virtual clang::ASTContext * + GetClangAST (); + + virtual void * + GetOpaqueClangQualType (); + + virtual ConstString + GetTypeName(); + + virtual uint32_t + CalculateNumChildren(); + + virtual lldb::ValueType + GetValueType() const; + + virtual void + UpdateValue (ExecutionContextScope *exe_scope); + + virtual bool + IsInScope (StackFrame *frame); + +protected: + + lldb::VariableSP m_variable_sp; ///< The variable that this value object is based upon + +private: + //------------------------------------------------------------------ + // For ValueObject only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ValueObjectVariable); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectVariable_h_ diff --git a/lldb/include/lldb/Core/dwarf.h b/lldb/include/lldb/Core/dwarf.h new file mode 100644 index 00000000000..2b566dfd9d9 --- /dev/null +++ b/lldb/include/lldb/Core/dwarf.h @@ -0,0 +1,589 @@ +//===-- dwarf.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef DebugBase_dwarf_h_ +#define DebugBase_dwarf_h_ + +#include <stdint.h> +#include <stdbool.h> + +typedef uint32_t dw_uleb128_t; +typedef int32_t dw_sleb128_t; +typedef uint16_t dw_attr_t; +typedef uint8_t dw_form_t; +typedef uint16_t dw_tag_t; +typedef uint64_t dw_addr_t; // Dwarf address define that must be big enough for any addresses in the compile units that get parsed + +#ifdef DWARFUTILS_DWARF64 +#define DWARF_REF_ADDR_SIZE 8 +typedef uint64_t dw_offset_t; // Dwarf Debug Information Entry offset for any offset into the file +#else +#define DWARF_REF_ADDR_SIZE 4 +typedef uint32_t dw_offset_t; // Dwarf Debug Information Entry offset for any offset into the file +#endif + +/* Constants */ +#define DW_INVALID_ADDRESS (~(dw_addr_t)0) +#define DW_INVALID_OFFSET (~(dw_offset_t)0) +#define DW_INVALID_INDEX 0xFFFFFFFFul + + +/* [7.5.4] Figure 16 "Tag Encodings" (pp. 125-127) in DWARFv3 draft 8 */ + +#define DW_TAG_array_type 0x1 +#define DW_TAG_class_type 0x2 +#define DW_TAG_entry_point 0x3 +#define DW_TAG_enumeration_type 0x4 +#define DW_TAG_formal_parameter 0x5 +#define DW_TAG_imported_declaration 0x8 +#define DW_TAG_label 0xA +#define DW_TAG_lexical_block 0xB +#define DW_TAG_member 0xD +#define DW_TAG_pointer_type 0xF +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 +#define DW_TAG_string_type 0x12 +#define DW_TAG_structure_type 0x13 +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 +#define DW_TAG_unspecified_parameters 0x18 +#define DW_TAG_variant 0x19 +#define DW_TAG_common_block 0x1A +#define DW_TAG_common_inclusion 0x1B +#define DW_TAG_inheritance 0x1C +#define DW_TAG_inlined_subroutine 0x1D +#define DW_TAG_module 0x1E +#define DW_TAG_ptr_to_member_type 0x1F +#define DW_TAG_set_type 0x20 +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_with_stmt 0x22 +#define DW_TAG_access_declaration 0x23 +#define DW_TAG_base_type 0x24 +#define DW_TAG_catch_block 0x25 +#define DW_TAG_const_type 0x26 +#define DW_TAG_constant 0x27 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_file_type 0x29 +#define DW_TAG_friend 0x2A +#define DW_TAG_namelist 0x2B +#define DW_TAG_namelist_item 0x2C +#define DW_TAG_packed_type 0x2D +#define DW_TAG_subprogram 0x2E +#define DW_TAG_template_type_parameter 0x2F +#define DW_TAG_template_value_parameter 0x30 +#define DW_TAG_thrown_type 0x31 +#define DW_TAG_try_block 0x32 +#define DW_TAG_variant_part 0x33 +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 +#define DW_TAG_dwarf_procedure 0x36 +#define DW_TAG_restrict_type 0x37 +#define DW_TAG_interface_type 0x38 +#define DW_TAG_namespace 0x39 +#define DW_TAG_imported_module 0x3A +#define DW_TAG_unspecified_type 0x3B +#define DW_TAG_partial_unit 0x3C +#define DW_TAG_imported_unit 0x3D +#define DW_TAG_condition 0x3F +#define DW_TAG_shared_type 0x40 +#define DW_TAG_lo_user 0x4080 +#define DW_TAG_hi_user 0xFFFF + +/* [7.5.4] Figure 17 "Child determination encodings" (p. 128) in DWARFv3 draft 8 */ + +#define DW_CHILDREN_no 0x0 +#define DW_CHILDREN_yes 0x1 + +/* [7.5.4] Figure 18 "Attribute encodings" (pp. 129-132) in DWARFv3 draft 8 */ + +#define DW_AT_sibling 0x1 +#define DW_AT_location 0x2 +#define DW_AT_name 0x3 +#define DW_AT_ordering 0x9 +#define DW_AT_byte_size 0xB +#define DW_AT_bit_offset 0xC +#define DW_AT_bit_size 0xD +#define DW_AT_stmt_list 0x10 +#define DW_AT_low_pc 0x11 +#define DW_AT_high_pc 0x12 +#define DW_AT_language 0x13 +#define DW_AT_discr 0x15 +#define DW_AT_discr_value 0x16 +#define DW_AT_visibility 0x17 +#define DW_AT_import 0x18 +#define DW_AT_string_length 0x19 +#define DW_AT_common_reference 0x1A +#define DW_AT_comp_dir 0x1B +#define DW_AT_const_value 0x1C +#define DW_AT_containing_type 0x1D +#define DW_AT_default_value 0x1E +#define DW_AT_inline 0x20 +#define DW_AT_is_optional 0x21 +#define DW_AT_lower_bound 0x22 +#define DW_AT_producer 0x25 +#define DW_AT_prototyped 0x27 +#define DW_AT_return_addr 0x2A +#define DW_AT_start_scope 0x2C +#define DW_AT_bit_stride 0x2E +#define DW_AT_upper_bound 0x2F +#define DW_AT_abstract_origin 0x31 +#define DW_AT_accessibility 0x32 +#define DW_AT_address_class 0x33 +#define DW_AT_artificial 0x34 +#define DW_AT_base_types 0x35 +#define DW_AT_calling_convention 0x36 +#define DW_AT_count 0x37 +#define DW_AT_data_member_location 0x38 +#define DW_AT_decl_column 0x39 +#define DW_AT_decl_file 0x3A +#define DW_AT_decl_line 0x3B +#define DW_AT_declaration 0x3C +#define DW_AT_discr_list 0x3D +#define DW_AT_encoding 0x3E +#define DW_AT_external 0x3F +#define DW_AT_frame_base 0x40 +#define DW_AT_friend 0x41 +#define DW_AT_identifier_case 0x42 +#define DW_AT_macro_info 0x43 +#define DW_AT_namelist_item 0x44 +#define DW_AT_priority 0x45 +#define DW_AT_segment 0x46 +#define DW_AT_specification 0x47 +#define DW_AT_static_link 0x48 +#define DW_AT_type 0x49 +#define DW_AT_use_location 0x4A +#define DW_AT_variable_parameter 0x4B +#define DW_AT_virtuality 0x4C +#define DW_AT_vtable_elem_location 0x4D +#define DW_AT_allocated 0x4E +#define DW_AT_associated 0x4F +#define DW_AT_data_location 0x50 +#define DW_AT_byte_stride 0x51 +#define DW_AT_entry_pc 0x52 +#define DW_AT_use_UTF8 0x53 +#define DW_AT_extension 0x54 +#define DW_AT_ranges 0x55 +#define DW_AT_trampoline 0x56 +#define DW_AT_call_column 0x57 +#define DW_AT_call_file 0x58 +#define DW_AT_call_line 0x59 +#define DW_AT_description 0x5A +#define DW_AT_binary_scale 0x5B +#define DW_AT_decimal_scale 0x5C +#define DW_AT_small 0x5D +#define DW_AT_decimal_sign 0x5E +#define DW_AT_digit_count 0x5F +#define DW_AT_picture_string 0x60 +#define DW_AT_mutable 0x61 +#define DW_AT_threads_scaled 0x62 +#define DW_AT_explicit 0x63 +#define DW_AT_object_pointer 0x64 +#define DW_AT_endianity 0x65 +#define DW_AT_elemental 0x66 +#define DW_AT_pure 0x67 +#define DW_AT_recursive 0x68 +#define DW_AT_lo_user 0x2000 +#define DW_AT_hi_user 0x3FFF +#define DW_AT_MIPS_fde 0x2001 +#define DW_AT_MIPS_loop_begin 0x2002 +#define DW_AT_MIPS_tail_loop_begin 0x2003 +#define DW_AT_MIPS_epilog_begin 0x2004 +#define DW_AT_MIPS_loop_unroll_factor 0x2005 +#define DW_AT_MIPS_software_pipeline_depth 0x2006 +#define DW_AT_MIPS_linkage_name 0x2007 +#define DW_AT_MIPS_stride 0x2008 +#define DW_AT_MIPS_abstract_name 0x2009 +#define DW_AT_MIPS_clone_origin 0x200A +#define DW_AT_MIPS_has_inlines 0x200B +/* GNU extensions. */ +#define DW_AT_sf_names 0x2101 +#define DW_AT_src_info 0x2102 +#define DW_AT_mac_info 0x2103 +#define DW_AT_src_coords 0x2104 +#define DW_AT_body_begin 0x2105 +#define DW_AT_body_end 0x2106 +#define DW_AT_GNU_vector 0x2107 + +#define DW_AT_APPLE_repository_file 0x2501 +#define DW_AT_APPLE_repository_type 0x2502 +#define DW_AT_APPLE_repository_name 0x2503 +#define DW_AT_APPLE_repository_specification 0x2504 +#define DW_AT_APPLE_repository_import 0x2505 +#define DW_AT_APPLE_repository_abstract_origin 0x2506 +#define DW_AT_APPLE_optimized 0x3FE1 +#define DW_AT_APPLE_flags 0x3FE2 +#define DW_AT_APPLE_isa 0x3FE3 +#define DW_AT_APPLE_block 0x3FE4 + +/* [7.5.4] Figure 19 "Attribute form encodings" (pp. 133-134) in DWARFv3 draft 8 */ + +#define DW_FORM_addr 0x1 +#define DW_FORM_block2 0x3 +#define DW_FORM_block4 0x4 +#define DW_FORM_data2 0x5 +#define DW_FORM_data4 0x6 +#define DW_FORM_data8 0x7 +#define DW_FORM_string 0x8 +#define DW_FORM_block 0x9 +#define DW_FORM_block1 0xA +#define DW_FORM_data1 0xB +#define DW_FORM_flag 0xC +#define DW_FORM_sdata 0xD +#define DW_FORM_strp 0xE +#define DW_FORM_udata 0xF +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_ref1 0x11 +#define DW_FORM_ref2 0x12 +#define DW_FORM_ref4 0x13 +#define DW_FORM_ref8 0x14 +#define DW_FORM_ref_udata 0x15 +#define DW_FORM_indirect 0x16 // cf section 7.5.3, "Abbreviations Tables", p. 119 DWARFv3 draft 8 +#define DW_FORM_APPLE_db_str 0x50 // read same as udata, but refers to string in repository + +/* [7.7.1] Figure 22 "DWARF operation encodings" (pp. 136-139) in DWARFv3 draft 8 */ + +#define DW_OP_addr 0x3 // constant address (size target specific) +#define DW_OP_deref 0x6 +#define DW_OP_const1u 0x8 // 1-byte constant +#define DW_OP_const1s 0x9 // 1-byte constant +#define DW_OP_const2u 0xA // 2-byte constant +#define DW_OP_const2s 0xB // 2-byte constant +#define DW_OP_const4u 0xC // 4-byte constant +#define DW_OP_const4s 0xD // 4-byte constant +#define DW_OP_const8u 0xE // 8-byte constant +#define DW_OP_const8s 0xF // 8-byte constant +#define DW_OP_constu 0x10 // ULEB128 constant +#define DW_OP_consts 0x11 // SLEB128 constant +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 // 1-byte stack index +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_xderef 0x18 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1A +#define DW_OP_div 0x1B +#define DW_OP_minus 0x1C +#define DW_OP_mod 0x1D +#define DW_OP_mul 0x1E +#define DW_OP_neg 0x1F +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 // ULEB128 addend +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_skip 0x2F // signed 2-byte constant +#define DW_OP_bra 0x28 // signed 2-byte constant +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2A +#define DW_OP_gt 0x2B +#define DW_OP_le 0x2C +#define DW_OP_lt 0x2D +#define DW_OP_ne 0x2E +#define DW_OP_lit0 0x30 // Literal 0 +#define DW_OP_lit1 0x31 // Literal 1 +#define DW_OP_lit2 0x32 // Literal 2 +#define DW_OP_lit3 0x33 // Literal 3 +#define DW_OP_lit4 0x34 // Literal 4 +#define DW_OP_lit5 0x35 // Literal 5 +#define DW_OP_lit6 0x36 // Literal 6 +#define DW_OP_lit7 0x37 // Literal 7 +#define DW_OP_lit8 0x38 // Literal 8 +#define DW_OP_lit9 0x39 // Literal 9 +#define DW_OP_lit10 0x3A // Literal 10 +#define DW_OP_lit11 0x3B // Literal 11 +#define DW_OP_lit12 0x3C // Literal 12 +#define DW_OP_lit13 0x3D // Literal 13 +#define DW_OP_lit14 0x3E // Literal 14 +#define DW_OP_lit15 0x3F // Literal 15 +#define DW_OP_lit16 0x40 // Literal 16 +#define DW_OP_lit17 0x41 // Literal 17 +#define DW_OP_lit18 0x42 // Literal 18 +#define DW_OP_lit19 0x43 // Literal 19 +#define DW_OP_lit20 0x44 // Literal 20 +#define DW_OP_lit21 0x45 // Literal 21 +#define DW_OP_lit22 0x46 // Literal 22 +#define DW_OP_lit23 0x47 // Literal 23 +#define DW_OP_lit24 0x48 // Literal 24 +#define DW_OP_lit25 0x49 // Literal 25 +#define DW_OP_lit26 0x4A // Literal 26 +#define DW_OP_lit27 0x4B // Literal 27 +#define DW_OP_lit28 0x4C // Literal 28 +#define DW_OP_lit29 0x4D // Literal 29 +#define DW_OP_lit30 0x4E // Literal 30 +#define DW_OP_lit31 0x4F // Literal 31 +#define DW_OP_reg0 0x50 // Contents of reg0 +#define DW_OP_reg1 0x51 // Contents of reg1 +#define DW_OP_reg2 0x52 // Contents of reg2 +#define DW_OP_reg3 0x53 // Contents of reg3 +#define DW_OP_reg4 0x54 // Contents of reg4 +#define DW_OP_reg5 0x55 // Contents of reg5 +#define DW_OP_reg6 0x56 // Contents of reg6 +#define DW_OP_reg7 0x57 // Contents of reg7 +#define DW_OP_reg8 0x58 // Contents of reg8 +#define DW_OP_reg9 0x59 // Contents of reg9 +#define DW_OP_reg10 0x5A // Contents of reg10 +#define DW_OP_reg11 0x5B // Contents of reg11 +#define DW_OP_reg12 0x5C // Contents of reg12 +#define DW_OP_reg13 0x5D // Contents of reg13 +#define DW_OP_reg14 0x5E // Contents of reg14 +#define DW_OP_reg15 0x5F // Contents of reg15 +#define DW_OP_reg16 0x60 // Contents of reg16 +#define DW_OP_reg17 0x61 // Contents of reg17 +#define DW_OP_reg18 0x62 // Contents of reg18 +#define DW_OP_reg19 0x63 // Contents of reg19 +#define DW_OP_reg20 0x64 // Contents of reg20 +#define DW_OP_reg21 0x65 // Contents of reg21 +#define DW_OP_reg22 0x66 // Contents of reg22 +#define DW_OP_reg23 0x67 // Contents of reg23 +#define DW_OP_reg24 0x68 // Contents of reg24 +#define DW_OP_reg25 0x69 // Contents of reg25 +#define DW_OP_reg26 0x6A // Contents of reg26 +#define DW_OP_reg27 0x6B // Contents of reg27 +#define DW_OP_reg28 0x6C // Contents of reg28 +#define DW_OP_reg29 0x6D // Contents of reg29 +#define DW_OP_reg30 0x6E // Contents of reg30 +#define DW_OP_reg31 0x6F // Contents of reg31 +#define DW_OP_breg0 0x70 // base register 0 + SLEB128 offset +#define DW_OP_breg1 0x71 // base register 1 + SLEB128 offset +#define DW_OP_breg2 0x72 // base register 2 + SLEB128 offset +#define DW_OP_breg3 0x73 // base register 3 + SLEB128 offset +#define DW_OP_breg4 0x74 // base register 4 + SLEB128 offset +#define DW_OP_breg5 0x75 // base register 5 + SLEB128 offset +#define DW_OP_breg6 0x76 // base register 6 + SLEB128 offset +#define DW_OP_breg7 0x77 // base register 7 + SLEB128 offset +#define DW_OP_breg8 0x78 // base register 8 + SLEB128 offset +#define DW_OP_breg9 0x79 // base register 9 + SLEB128 offset +#define DW_OP_breg10 0x7A // base register 10 + SLEB128 offset +#define DW_OP_breg11 0x7B // base register 11 + SLEB128 offset +#define DW_OP_breg12 0x7C // base register 12 + SLEB128 offset +#define DW_OP_breg13 0x7D // base register 13 + SLEB128 offset +#define DW_OP_breg14 0x7E // base register 14 + SLEB128 offset +#define DW_OP_breg15 0x7F // base register 15 + SLEB128 offset +#define DW_OP_breg16 0x80 // base register 16 + SLEB128 offset +#define DW_OP_breg17 0x81 // base register 17 + SLEB128 offset +#define DW_OP_breg18 0x82 // base register 18 + SLEB128 offset +#define DW_OP_breg19 0x83 // base register 19 + SLEB128 offset +#define DW_OP_breg20 0x84 // base register 20 + SLEB128 offset +#define DW_OP_breg21 0x85 // base register 21 + SLEB128 offset +#define DW_OP_breg22 0x86 // base register 22 + SLEB128 offset +#define DW_OP_breg23 0x87 // base register 23 + SLEB128 offset +#define DW_OP_breg24 0x88 // base register 24 + SLEB128 offset +#define DW_OP_breg25 0x89 // base register 25 + SLEB128 offset +#define DW_OP_breg26 0x8A // base register 26 + SLEB128 offset +#define DW_OP_breg27 0x8B // base register 27 + SLEB128 offset +#define DW_OP_breg28 0x8C // base register 28 + SLEB128 offset +#define DW_OP_breg29 0x8D // base register 29 + SLEB128 offset +#define DW_OP_breg30 0x8E // base register 30 + SLEB128 offset +#define DW_OP_breg31 0x8F // base register 31 + SLEB128 offset +#define DW_OP_regx 0x90 // ULEB128 register +#define DW_OP_fbreg 0x91 // SLEB128 offset +#define DW_OP_bregx 0x92 // ULEB128 register followed by SLEB128 offset +#define DW_OP_piece 0x93 // ULEB128 size of piece addressed +#define DW_OP_deref_size 0x94 // 1-byte size of data retrieved +#define DW_OP_xderef_size 0x95 // 1-byte size of data retrieved +#define DW_OP_nop 0x96 +#define DW_OP_push_object_address 0x97 +#define DW_OP_call2 0x98 // 2-byte offset of DIE +#define DW_OP_call4 0x99 // 4-byte offset of DIE +#define DW_OP_call_ref 0x9A // 4- or 8-byte offset of DIE +#define DW_OP_lo_user 0xE0 +#define DW_OP_APPLE_array_ref 0xEE // first pops index, then pops array; pushes array[index] +#define DW_OP_APPLE_extern 0xEF // ULEB128 index of external object (i.e., an entity from the program that was used in the expression) +#define DW_OP_APPLE_uninit 0xF0 +#define DW_OP_APPLE_assign 0xF1 // pops value off and assigns it to second item on stack (2nd item must have assignable context) +#define DW_OP_APPLE_address_of 0xF2 // gets the address of the top stack item (top item must be a variable, or have value_type that is an address already) +#define DW_OP_APPLE_value_of 0xF3 // pops the value off the stack and pushes the value of that object (top item must be a variable, or expression local) +#define DW_OP_APPLE_deref_type 0xF4 // gets the address of the top stack item (top item must be a variable, or a clang type) +#define DW_OP_APPLE_expr_local 0xF5 // ULEB128 expression local index +#define DW_OP_APPLE_constf 0xF6 // 1 byte float size, followed by constant float data +#define DW_OP_APPLE_scalar_cast 0xF7 // Cast top of stack to 2nd in stack's type leaving all items in place +#define DW_OP_APPLE_clang_cast 0xF8 // pointer size clang::Type * off the stack and cast top stack item to this type +#define DW_OP_APPLE_clear 0xFE // clears the entire expression stack, ok if the stack is empty +#define DW_OP_APPLE_error 0xFF // Stops expression evaluation and returns an error (no args) +#define DW_OP_hi_user 0xFF + +/* [7.8] Figure 23 "Base type encoding values" (pp. 140-141) in DWARFv3 draft 8 */ + +#define DW_ATE_address 0x1 +#define DW_ATE_boolean 0x2 +#define DW_ATE_complex_float 0x3 +#define DW_ATE_float 0x4 +#define DW_ATE_signed 0x5 +#define DW_ATE_signed_char 0x6 +#define DW_ATE_unsigned 0x7 +#define DW_ATE_unsigned_char 0x8 +#define DW_ATE_imaginary_float 0x9 +#define DW_ATE_lo_user 0x80 +#define DW_ATE_hi_user 0xFF + +/* [7.9] Figure 24 "Accessibility encodings" (p. 141) in DWARFv3 draft 8 */ + +#define DW_ACCESS_public 0x1 +#define DW_ACCESS_protected 0x2 +#define DW_ACCESS_private 0x3 + +/* [7.10] Figure 25 "Visibility encodings" (p. 142) in DWARFv3 draft 8 */ + +#define DW_VIS_local 0x1 +#define DW_VIS_exported 0x2 +#define DW_VIS_qualified 0x3 + +/* [7.11] Figure 26 "Virtuality encodings" (p. 142) in DWARFv3 draft 8 */ + +#define DW_VIRTUALITY_none 0x0 +#define DW_VIRTUALITY_virtual 0x1 +#define DW_VIRTUALITY_pure_virtual 0x2 + + +/* [7.12] Figure 27 "Language encodings" (p. 143) in DWARFv3 draft 8 */ + +#define DW_LANG_C89 0x1 +#define DW_LANG_C 0x2 +#define DW_LANG_Ada83 0x3 +#define DW_LANG_C_plus_plus 0x4 +#define DW_LANG_Cobol74 0x5 +#define DW_LANG_Cobol85 0x6 +#define DW_LANG_Fortran77 0x7 +#define DW_LANG_Fortran90 0x8 +#define DW_LANG_Pascal83 0x9 +#define DW_LANG_Modula2 0xA +#define DW_LANG_Java 0xB +#define DW_LANG_C99 0xC +#define DW_LANG_Ada95 0xD +#define DW_LANG_Fortran95 0xE +#define DW_LANG_PLI 0xF +#define DW_LANG_lo_user 0x8000 +#define DW_LANG_hi_user 0xFFFF + +/* [7.13], "Address Class Encodings" (p. 144) in DWARFv3 draft 8 */ + +#define DW_ADDR_none 0x0 + +/* [7.14] Figure 28 "Identifier case encodings" (p. 144) in DWARFv3 draft 8 */ + +#define DW_ID_case_sensitive 0x0 +#define DW_ID_up_case 0x1 +#define DW_ID_down_case 0x2 +#define DW_ID_case_insensitive 0x3 + +/* [7.15] Figure 29 "Calling convention encodings" (p. 144) in DWARFv3 draft 8 */ + +#define DW_CC_normal 0x1 +#define DW_CC_program 0x2 +#define DW_CC_nocall 0x3 +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xFF + +/* [7.16] Figure 30 "Inline encodings" (p. 145) in DWARFv3 draft 8 */ + +#define DW_INL_not_inlined 0x0 +#define DW_INL_inlined 0x1 +#define DW_INL_declared_not_inlined 0x2 +#define DW_INL_declared_inlined 0x3 + +/* [7.17] Figure 31 "Ordering encodings" (p. 145) in DWARFv3 draft 8 */ + +#define DW_ORD_row_major 0x0 +#define DW_ORD_col_major 0x1 + +/* [7.18] Figure 32 "Discriminant descriptor encodings" (p. 146) in DWARFv3 draft 8 */ + +#define DW_DSC_label 0x0 +#define DW_DSC_range 0x1 + +/* [7.21] Figure 33 "Line Number Standard Opcode Encodings" (pp. 148-149) in DWARFv3 draft 8 */ + +#define DW_LNS_copy 0x1 +#define DW_LNS_advance_pc 0x2 +#define DW_LNS_advance_line 0x3 +#define DW_LNS_set_file 0x4 +#define DW_LNS_set_column 0x5 +#define DW_LNS_negate_stmt 0x6 +#define DW_LNS_set_basic_block 0x7 +#define DW_LNS_const_add_pc 0x8 +#define DW_LNS_fixed_advance_pc 0x9 +#define DW_LNS_set_prologue_end 0xA +#define DW_LNS_set_epilogue_begin 0xB +#define DW_LNS_set_isa 0xC + +/* [7.21] Figure 34 "Line Number Extended Opcode Encodings" (p. 149) in DWARFv3 draft 8 */ + +#define DW_LNE_end_sequence 0x1 +#define DW_LNE_set_address 0x2 +#define DW_LNE_define_file 0x3 +#define DW_LNE_lo_user 0x80 +#define DW_LNE_hi_user 0xFF + +/* [7.22] Figure 35 "Macinfo Type Encodings" (p. 150) in DWARFv3 draft 8 */ + +#define DW_MACINFO_define 0x1 +#define DW_MACINFO_undef 0x2 +#define DW_MACINFO_start_file 0x3 +#define DW_MACINFO_end_file 0x4 +#define DW_MACINFO_vendor_ext 0xFF + +/* [7.23] Figure 36 "Call frame instruction encodings" (pp. 151-152) in DWARFv3 draft 8 */ + +#define DW_CFA_advance_loc 0x40 // high 2 bits are 0x1, lower 6 bits are delta +#define DW_CFA_offset 0x80 // high 2 bits are 0x2, lower 6 bits are register +#define DW_CFA_restore 0xC0 // high 2 bits are 0x3, lower 6 bits are register +#define DW_CFA_nop 0x0 +#define DW_CFA_set_loc 0x1 +#define DW_CFA_advance_loc1 0x2 +#define DW_CFA_advance_loc2 0x3 +#define DW_CFA_advance_loc4 0x4 +#define DW_CFA_offset_extended 0x5 +#define DW_CFA_restore_extended 0x6 +#define DW_CFA_undefined 0x7 +#define DW_CFA_same_value 0x8 +#define DW_CFA_register 0x9 +#define DW_CFA_remember_state 0xA +#define DW_CFA_restore_state 0xB +#define DW_CFA_def_cfa 0xC +#define DW_CFA_def_cfa_register 0xD +#define DW_CFA_def_cfa_offset 0xE +#define DW_CFA_def_cfa_expression 0xF +#define DW_CFA_expression 0x10 +#define DW_CFA_offset_extended_sf 0x11 +#define DW_CFA_def_cfa_sf 0x12 +#define DW_CFA_def_cfa_offset_sf 0x13 +#define DW_CFA_val_offset 0x14 +#define DW_CFA_val_offset_sf 0x15 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_lo_user 0x1C +#define DW_CFA_hi_user 0x3F + +/* FSF exception handling Pointer-Encoding constants (CFI augmentation) -- "DW_EH_PE_..." in the FSF sources */ + +#define DW_GNU_EH_PE_absptr 0x0 +#define DW_GNU_EH_PE_uleb128 0x1 +#define DW_GNU_EH_PE_udata2 0x2 +#define DW_GNU_EH_PE_udata4 0x3 +#define DW_GNU_EH_PE_udata8 0x4 +#define DW_GNU_EH_PE_sleb128 0x9 +#define DW_GNU_EH_PE_sdata2 0xA +#define DW_GNU_EH_PE_sdata4 0xB +#define DW_GNU_EH_PE_sdata8 0xC +#define DW_GNU_EH_PE_signed 0x8 +#define DW_GNU_EH_PE_MASK_ENCODING 0x0F +#define DW_GNU_EH_PE_pcrel 0x10 +#define DW_GNU_EH_PE_textrel 0x20 +#define DW_GNU_EH_PE_datarel 0x30 +#define DW_GNU_EH_PE_funcrel 0x40 +#define DW_GNU_EH_PE_aligned 0x50 +#define DW_GNU_EH_PE_indirect 0x80 +#define DW_GNU_EH_PE_omit 0xFF + +#endif // DebugBase_dwarf_h_ diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h new file mode 100644 index 00000000000..4f1e5631525 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -0,0 +1,67 @@ +/* + * ClangASTSource.h + * lldb + * + * Created by John McCall on 6/1/10. + * Copyright 2010 Apple. All rights reserved. + * + */ +#ifndef liblldb_ClangASTSource_h_ +#define liblldb_ClangASTSource_h_ + +#include "clang/Sema/ExternalSemaSource.h" + +namespace lldb_private { + +class ClangExpressionDeclMap; + +class ClangASTSource : public clang::ExternalSemaSource { + clang::ASTContext &Context; + ClangExpressionDeclMap &DeclMap; +public: + friend struct NameSearchContext; + + ClangASTSource(clang::ASTContext &Context, + ClangExpressionDeclMap &DeclMap) : + Context(Context), + DeclMap(DeclMap) {} + ~ClangASTSource(); + + clang::Decl *GetExternalDecl(uint32_t); + clang::Stmt *GetExternalDeclStmt(uint64_t); + + clang::Selector GetExternalSelector(uint32_t); + uint32_t GetNumExternalSelectors(); + + clang::DeclContext::lookup_result FindExternalVisibleDeclsByName(const clang::DeclContext *DC, + clang::DeclarationName Name); + + bool FindExternalLexicalDecls(const clang::DeclContext *DC, + llvm::SmallVectorImpl<clang::Decl*> &Decls); + + void StartTranslationUnit(clang::ASTConsumer *Consumer); +}; + +// API for ClangExpressionDeclMap +struct NameSearchContext { + ClangASTSource &ASTSource; + llvm::SmallVectorImpl<clang::NamedDecl*> &Decls; + clang::DeclarationName &Name; + const clang::DeclContext *DC; + + NameSearchContext (ClangASTSource &ASTSource, + llvm::SmallVectorImpl<clang::NamedDecl*> &Decls, + clang::DeclarationName &Name, + const clang::DeclContext *DC) : + ASTSource(ASTSource), + Decls(Decls), + Name(Name), + DC(DC) {} + + clang::ASTContext *GetASTContext(); + clang::NamedDecl *AddVarDecl(void *type); +}; + +} + +#endif
\ No newline at end of file diff --git a/lldb/include/lldb/Expression/ClangExpression.h b/lldb/include/lldb/Expression/ClangExpression.h new file mode 100644 index 00000000000..a645abf8829 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangExpression.h @@ -0,0 +1,124 @@ +//===-- ClangExpression.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangExpression_h_ +#define liblldb_ClangExpression_h_ + +// C Includes +// C++ Includes +#include <string> +#include <map> + +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" + +namespace llvm +{ + class ExecutionEngine; + class StringRef; +} + +namespace lldb_private { + +class RecordingMemoryManager; + +class ClangExpression +{ +public: + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ClangExpression(const char *target_triple, + ClangExpressionDeclMap *expr_decl_map); + + ~ClangExpression(); + + unsigned Compile(); + + unsigned + ParseExpression (const char *expr_text, Stream &stream); + + unsigned + ParseBareExpression (llvm::StringRef expr_text, Stream &stream); + + unsigned + ConvertExpressionToDWARF (ClangExpressionVariableList &expr_local_variable_list, + StreamString &dwarf_opcode_strm); + + bool + JITFunction (const ExecutionContext &exc_context, const char *func_name); + + bool + WriteJITCode (const ExecutionContext &exc_context); + + lldb::addr_t + GetFunctionAddress (const char *name); + + clang::CompilerInstance * + GetCompilerInstance () + { + return m_clang_ap.get(); + } + + clang::ASTContext * + GetASTContext (); + + static Mutex & + GetClangMutex (); +protected: + + // This class is a pass-through for the default JIT memory manager, + // which just records the memory regions that were handed out so we + // can copy them into the target later on. + + + //------------------------------------------------------------------ + // Classes that inherit from ClangExpression can see and modify these + //------------------------------------------------------------------ + + struct JittedFunction { + std::string m_name; + lldb::addr_t m_local_addr; + lldb::addr_t m_remote_addr; + + JittedFunction (const char *name, + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + m_name (name), + m_local_addr (local_addr), + m_remote_addr (remote_addr) {} + }; + + std::string m_target_triple; + ClangExpressionDeclMap *m_decl_map; + std::auto_ptr<clang::CompilerInstance> m_clang_ap; + clang::CodeGenerator *m_code_generator_ptr; // This will be deleted by the Execution Engine. + RecordingMemoryManager *m_jit_mm_ptr; // This will be deleted by the Execution Engine. + std::auto_ptr<llvm::ExecutionEngine> m_execution_engine; + std::vector<JittedFunction> m_jitted_functions; +private: + + bool CreateCompilerInstance(bool &IsAST); + + //------------------------------------------------------------------ + // For ClangExpression only + //------------------------------------------------------------------ + ClangExpression(const ClangExpression&); + const ClangExpression& operator=(const ClangExpression&); +}; + +} // namespace lldb_private + +#endif // liblldb_ClangExpression_h_ diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h new file mode 100644 index 00000000000..e1c9dc4ebc3 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -0,0 +1,71 @@ +//===-- ClangExpressionDeclMap.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangExpressionDeclMap_h_ +#define liblldb_ClangExpressionDeclMap_h_ + +// C Includes +#include <signal.h> +#include <stdint.h> + +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/Value.h" + +namespace clang { + class DeclarationName; + class DeclContext; +} + +namespace lldb_private { + +class NameSearchContext; +class Variable; + +class ClangExpressionDeclMap +{ +public: + ClangExpressionDeclMap(ExecutionContext *exe_ctx); + ~ClangExpressionDeclMap(); + + // Interface for ClangStmtVisitor + bool GetIndexForDecl (uint32_t &index, + const clang::Decl *decl); + + // Interface for DwarfExpression + Value *GetValueForIndex (uint32_t index); + + // Interface for ClangASTSource + void GetDecls (NameSearchContext &context, + const char *name); +protected: +private: + struct Tuple + { + const clang::NamedDecl *m_decl; + Value *m_value; /* owned by ClangExpressionDeclMap */ + }; + + typedef std::vector<Tuple> TupleVector; + typedef TupleVector::iterator TupleIterator; + + TupleVector m_tuples; + ExecutionContext *m_exe_ctx; + SymbolContext *m_sym_ctx; /* owned by ClangExpressionDeclMap */ + + void AddOneVariable(NameSearchContext &context, Variable* var); +}; + +} // namespace lldb_private + +#endif // liblldb_ClangExpressionDeclMap_h_ diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h new file mode 100644 index 00000000000..fc6cccced11 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -0,0 +1,58 @@ +//===-- ClangExpressionVariable.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangExpressionVariable_h_ +#define liblldb_ClangExpressionVariable_h_ + +// C Includes +#include <signal.h> +#include <stdint.h> + +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/Value.h" + +namespace lldb_private { + +class ClangExpressionVariableList +{ +public: + ClangExpressionVariableList(); + ~ClangExpressionVariableList(); + + Value * + GetVariableForVarDecl (clang::ASTContext &ast_context, + const clang::VarDecl *var_decl, + uint32_t& idx, + bool can_create); + + Value * + GetVariableAtIndex (uint32_t idx); + + uint32_t + AppendValue (Value *value); // takes ownership + +private: + struct ClangExpressionVariable + { + const clang::VarDecl *m_var_decl; + Value *m_value; + }; + + typedef std::vector<ClangExpressionVariable> Variables; + Variables m_variables; +}; + +} // namespace lldb_private + +#endif // liblldb_ClangExpressionVariable_h_ diff --git a/lldb/include/lldb/Expression/ClangFunction.h b/lldb/include/lldb/Expression/ClangFunction.h new file mode 100644 index 00000000000..bf0a8172067 --- /dev/null +++ b/lldb/include/lldb/Expression/ClangFunction.h @@ -0,0 +1,241 @@ +//===-- ClangFunction.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_ClangFunction_h_ +#define lldb_ClangFunction_h_ + +// C Includes +// C++ Includes +#include <vector> +#include <list> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectList.h" + +#include "lldb/Expression/ClangExpression.h" + +// Right now, this is just a toy. It calls a set function, with fixed +// values. + +namespace clang +{ + class ASTRecordLayout; +} + +namespace lldb_private +{ + +class ClangFunction : private ClangExpression +{ +public: + + typedef enum ExecutionResults + { + eExecutionSetupError, + eExecutionCompleted, + eExecutionDiscarded, + eExecutionInterrupted, + eExecutionTimedOut + }; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + // Usage Note: + + // A given ClangFunction object can handle any function with a common signature. It can also be used to + // set up any number of concurrent functions calls once it has been constructed. + // When you construct it you pass in a particular function, information sufficient to determine the function signature + // and value list. + // The simplest use of the ClangFunction is to construct the function, then call ExecuteFunction (context, errors, results). The function + // will be called using the initial arguments, and the results determined for you, and all cleanup done. + // + // However, if you need to use the function caller in Thread Plans, you need to call the function on the plan stack. + // In that case, you call GetThreadPlanToCallFunction, args_addr will be the location of the args struct, and after you are + // done running this thread plan you can recover the results using FetchFunctionResults passing in the same value. + // You are required to call InsertFunction before calling GetThreadPlanToCallFunction. + // + // You can also reuse the struct if you want, by calling ExecuteFunction but passing in args_addr_ptr primed to this value. + // + // You can also reuse the ClangFunction for the same signature but different function or argument values by rewriting the + // Functions arguments with WriteFunctionArguments, and then calling ExecuteFunction passing in the same args_addr. + // + // Note, any of the functions below that take arg_addr_ptr, or arg_addr_ref, can be passed a pointer set to LLDB_INVALID_ADDRESS and + // new structure will be allocated and its address returned in that variable. + // Any of the functions below that take arg_addr_ptr can be passed NULL, and the argument space will be managed for you. + + ClangFunction(const char *target_triple, Function &function_ptr, ClangASTContext *ast_context, const ValueList &arg_value_list); + // This constructor takes its return type as a Clang QualType opaque pointer, and the ast_context it comes from. + // FIXME: We really should be able to easily make a Type from the qualtype, and then just pass that in. + ClangFunction(const char *target_triple, ClangASTContext *ast_context, void *return_qualtype, const Address& functionAddress, const ValueList &arg_value_list); + virtual ~ClangFunction(); + + unsigned CompileFunction (Stream &errors); + + // args_addr is a pointer to the address the addr will be filled with. If the value on + // input is LLDB_INVALID_ADDRESS then a new address will be allocated, and returned in args_addr. + // If args_addr is a value already returned from a previous call to InsertFunction, then + // the args structure at that address is overwritten. + // If any other value is returned, then we return false, and do nothing. + bool InsertFunction (ExecutionContext &context, lldb::addr_t &args_addr_ref, Stream &errors); + + bool WriteFunctionWrapper (ExecutionContext &exec_ctx, Stream &errors); + + // This variant writes down the original function address and values to args_addr. + bool WriteFunctionArguments (ExecutionContext &exec_ctx, lldb::addr_t &args_addr_ref, Stream &errors); + + // This variant writes down function_address and arg_value. + bool WriteFunctionArguments (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Address function_address, ValueList &arg_values, Stream &errors); + + //------------------------------------------------------------------ + /// Run the function this ClangFunction was created with. + /// + /// This simple version will run the function stopping other threads + /// for a fixed timeout period (1000 usec) and if it does not complete, + /// we halt the process and try with all threads running. + /// + /// @param[in] context + /// The thread & process in which this function will run. + /// + /// @param[in] errors + /// Errors will be written here if there are any. + /// + /// @param[out] results + /// The result value will be put here after running the function. + /// + /// @return + /// Returns one of the ExecutionResults enum indicating function call status. + //------------------------------------------------------------------ + ExecutionResults ExecuteFunction(ExecutionContext &context, Stream &errors, Value &results); + + //------------------------------------------------------------------ + /// Run the function this ClangFunction was created with. + /// + /// This simple version will run the function obeying the stop_others + /// argument. There is no timeout. + /// + /// @param[in] context + /// The thread & process in which this function will run. + /// + /// @param[in] errors + /// Errors will be written here if there are any. + /// + /// @param[in] stop_others + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[out] results + /// The result value will be put here after running the function. + /// + /// @return + /// Returns one of the ExecutionResults enum indicating function call status. + //------------------------------------------------------------------ + ExecutionResults ExecuteFunction(ExecutionContext &exc_context, Stream &errors, bool stop_others, Value &results); + + //------------------------------------------------------------------ + /// Run the function this ClangFunction was created with. + /// + /// This simple version will run the function on one thread. If \a single_thread_timeout_usec + /// is not zero, we time out after that timeout. If \a try_all_threads is true, then we will + /// resume with all threads on, otherwise we halt the process, and eExecutionInterrupted will be returned. + /// + /// @param[in] context + /// The thread & process in which this function will run. + /// + /// @param[in] errors + /// Errors will be written here if there are any. + /// + /// @param[in] single_thread_timeout_usec + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[in] try_all_threads + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[out] results + /// The result value will be put here after running the function. + /// + /// @return + /// Returns one of the ExecutionResults enum indicating function call status. + //------------------------------------------------------------------ + ExecutionResults ExecuteFunction(ExecutionContext &context, Stream &errors, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results); + + //------------------------------------------------------------------ + /// Run the function this ClangFunction was created with. + /// + /// This is the full version. + /// + /// @param[in] context + /// The thread & process in which this function will run. + /// + /// @param[in] args_addr_ptr + /// If NULL, the function will take care of allocating & deallocating the wrapper + /// args structure. Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure + /// will be allocated, filled and the address returned to you. You are responsible + /// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS, + /// this should point to an already allocated structure with the values already written. + /// + /// @param[in] errors + /// Errors will be written here if there are any. + /// + /// @param[in] stop_others + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[in] single_thread_timeout_usec + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[in] try_all_threads + /// If \b true, run only this thread, if \b false let all threads run. + /// + /// @param[out] results + /// The result value will be put here after running the function. + /// + /// @return + /// Returns one of the ExecutionResults enum indicating function call status. + //------------------------------------------------------------------ + ExecutionResults ExecuteFunction(ExecutionContext &context, lldb::addr_t *args_addr_ptr, Stream &errors, bool stop_others, uint32_t single_thread_timeout_usec, bool try_all_threads, Value &results); + ExecutionResults ExecuteFunctionWithABI(ExecutionContext &context, Stream &errors, Value &results); + + ThreadPlan *GetThreadPlanToCallFunction (ExecutionContext &exc_context, lldb::addr_t &args_addr_ref, Stream &errors, bool stop_others, bool discard_on_error = true); + bool FetchFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr, Value &ret_value); + void DeallocateFunctionResults (ExecutionContext &exc_context, lldb::addr_t args_addr); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from ClangFunction can see and modify these + //------------------------------------------------------------------ + +private: + //------------------------------------------------------------------ + // For ClangFunction only + //------------------------------------------------------------------ + + Function *m_function_ptr; // The function we're going to call. May be NULL if we don't have debug info for the function. + Address m_function_addr; // If we don't have the FunctionSP, we at least need the address & return type. + void *m_function_return_qual_type; // The opaque clang qual type for the function return type. + ClangASTContext *m_clang_ast_context; // This is the clang_ast_context that we're getting types from the and value, and the function return the function pointer is NULL. + + std::string m_wrapper_function_name; + std::string m_wrapper_struct_name; + const clang::ASTRecordLayout *m_struct_layout; + ValueList m_arg_values; + lldb::addr_t m_wrapper_fun_addr; + std::list<lldb::addr_t> m_wrapper_args_addrs; + + size_t m_value_struct_size; + size_t m_return_offset; + uint64_t m_return_size; // Not strictly necessary, could get it from the Function... + bool m_compiled; + bool m_JITted; +}; + +}; // Namespace lldb_private +#endif // lldb_ClangFunction_h_ diff --git a/lldb/include/lldb/Expression/ClangStmtVisitor.h b/lldb/include/lldb/Expression/ClangStmtVisitor.h new file mode 100644 index 00000000000..5f8d6e5936f --- /dev/null +++ b/lldb/include/lldb/Expression/ClangStmtVisitor.h @@ -0,0 +1,109 @@ +//===-- ClangStmtVisitor.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangStmtVisitor_h_ +#define liblldb_ClangStmtVisitor_h_ + +// C Includes +// C++ Includes + +// Other libraries and framework includes +#include "clang/AST/StmtVisitor.h" + +// Project includes +#include "lldb/Core/ClangForward.h" + +namespace lldb_private { + +class StreamString; +class ClangExpressionDeclMap; +class ClangExpressionVariableList; + +#define CLANG_STMT_RESULT void + +class ClangStmtVisitor : public clang::StmtVisitor<ClangStmtVisitor, CLANG_STMT_RESULT> +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ClangStmtVisitor (clang::ASTContext &ast_context, + ClangExpressionVariableList &variable_list, + ClangExpressionDeclMap *decl_map, + StreamString &strm); + virtual ~ClangStmtVisitor (); + + // Stmts. + CLANG_STMT_RESULT VisitStmt (clang::Stmt *Node); + CLANG_STMT_RESULT VisitDeclStmt (clang::DeclStmt *Node); + CLANG_STMT_RESULT VisitLabelStmt (clang::LabelStmt *Node); + CLANG_STMT_RESULT VisitGotoStmt (clang::GotoStmt *Node); + + // Exprs + CLANG_STMT_RESULT VisitExpr (clang::Expr *Node); + CLANG_STMT_RESULT VisitDeclRefExpr (clang::DeclRefExpr *Node); + CLANG_STMT_RESULT VisitPredefinedExpr (clang::PredefinedExpr *Node); + CLANG_STMT_RESULT VisitCharacterLiteral (clang::CharacterLiteral *Node); + CLANG_STMT_RESULT VisitIntegerLiteral (clang::IntegerLiteral *Node); + CLANG_STMT_RESULT VisitFloatingLiteral (clang::FloatingLiteral *Node); + CLANG_STMT_RESULT VisitStringLiteral (clang::StringLiteral *Str); + CLANG_STMT_RESULT VisitUnaryOperator (clang::UnaryOperator *Node); + CLANG_STMT_RESULT VisitSizeOfAlignOfExpr (clang::SizeOfAlignOfExpr *Node); + CLANG_STMT_RESULT VisitMemberExpr (clang::MemberExpr *Node); + CLANG_STMT_RESULT VisitExtVectorElementExpr (clang::ExtVectorElementExpr *Node); + CLANG_STMT_RESULT VisitBinaryOperator (clang::BinaryOperator *Node); +// CLANG_STMT_RESULT VisitCompoundAssignOperator (clang::CompoundAssignOperator *Node); + CLANG_STMT_RESULT VisitAddrLabelExpr (clang::AddrLabelExpr *Node); + CLANG_STMT_RESULT VisitTypesCompatibleExpr (clang::TypesCompatibleExpr *Node); + CLANG_STMT_RESULT VisitParenExpr(clang::ParenExpr *Node); + CLANG_STMT_RESULT VisitInitListExpr (clang::InitListExpr *Node); + CLANG_STMT_RESULT VisitCastExpr (clang::CastExpr *Node); +// CLANG_STMT_RESULT VisitImplicitCastExpr (clang::ImplicitCastExpr *Node); + CLANG_STMT_RESULT VisitArraySubscriptExpr (clang::ArraySubscriptExpr *Node); + // C++ + CLANG_STMT_RESULT VisitCXXNamedCastExpr (clang::CXXNamedCastExpr *Node); + CLANG_STMT_RESULT VisitCXXBoolLiteralExpr (clang::CXXBoolLiteralExpr *Node); + CLANG_STMT_RESULT VisitCXXThisExpr (clang::CXXThisExpr *Node); + CLANG_STMT_RESULT VisitCXXFunctionalCastExpr (clang::CXXFunctionalCastExpr *Node); + + // ObjC + CLANG_STMT_RESULT VisitObjCEncodeExpr (clang::ObjCEncodeExpr *Node); + CLANG_STMT_RESULT VisitObjCMessageExpr (clang::ObjCMessageExpr* Node); + CLANG_STMT_RESULT VisitObjCSelectorExpr (clang::ObjCSelectorExpr *Node); + CLANG_STMT_RESULT VisitObjCProtocolExpr (clang::ObjCProtocolExpr *Node); + CLANG_STMT_RESULT VisitObjCPropertyRefExpr (clang::ObjCPropertyRefExpr *Node); + CLANG_STMT_RESULT VisitObjCImplicitSetterGetterRefExpr (clang::ObjCImplicitSetterGetterRefExpr *Node); + CLANG_STMT_RESULT VisitObjCIvarRefExpr (clang::ObjCIvarRefExpr *Node); + CLANG_STMT_RESULT VisitObjCSuperExpr (clang::ObjCSuperExpr *Node); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from ClangStmtVisitor can see and modify these + //------------------------------------------------------------------ + clang::ASTContext &m_ast_context; + ClangExpressionDeclMap *m_decl_map; + ClangExpressionVariableList &m_variable_list; + StreamString &m_stream; +private: + //------------------------------------------------------------------ + // For ClangStmtVisitor only + //------------------------------------------------------------------ + ClangStmtVisitor (const ClangStmtVisitor&); + const ClangStmtVisitor& operator= (const ClangStmtVisitor&); + + bool + EncodeUInt64 (uint64_t uval, uint32_t bit_size); + + bool + EncodeSInt64 (int64_t sval, uint32_t bit_size); +}; + +} // namespace lldb_private + +#endif // liblldb_ClangStmtVisitor_h_ diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h new file mode 100644 index 00000000000..072697659fa --- /dev/null +++ b/lldb/include/lldb/Expression/DWARFExpression.h @@ -0,0 +1,126 @@ +//===-- DWARFExpression.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DWARFExpression_h_ +#define liblldb_DWARFExpression_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Scalar.h" + +class ClangExpressionVariable; +class ClangExpressionVariableList; + +namespace lldb_private { + +class ClangExpressionDeclMap; + +//---------------------------------------------------------------------- +// A class designed to evaluate the DWARF expression opcodes. We will +// likely augment its abilities to handle features not supported by +// the DWARF expression engine. +//---------------------------------------------------------------------- +class DWARFExpression +{ +public: + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + DWARFExpression(); + + DWARFExpression(const DataExtractor& data, + uint32_t data_offset, + uint32_t data_length, + const Address* loclist_base_addr_ptr); + + DWARFExpression(const DWARFExpression& rhs); + + virtual + ~DWARFExpression(); + + void + GetDescription (Stream *s, lldb::DescriptionLevel level) const; + + bool + IsValid() const; + + bool + IsLocationList() const; + + bool + LocationListContainsLoadAddress (Process* process, const Address &addr) const; + + void + SetOpcodeData(const DataExtractor& data, const Address* loclist_base_addr_ptr); + + void + SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length, const Address* loclist_base_addr_ptr); + + void + SetLocationListBaseAddress(Address& base_addr); + + int + GetRegisterKind (); + + void + SetRegisterKind (int reg_kind); + + bool + Evaluate (ExecutionContextScope *exe_scope, + clang::ASTContext *ast_context, + const Value* initial_value_ptr, + Value& result, + Error *error_ptr) const; + + bool + Evaluate (ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + const Value* initial_value_ptr, + Value& result, + Error *error_ptr) const; + + static bool + Evaluate (ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + const DataExtractor& opcodes, + ClangExpressionVariableList *expr_locals, + ClangExpressionDeclMap *decl_map, + const uint32_t offset, + const uint32_t length, + const uint32_t reg_set, + const Value* initial_value_ptr, + Value& result, + Error *error_ptr); + + void + SetExpressionLocalVariableList (ClangExpressionVariableList *locals); + + void + SetExpressionDeclMap (ClangExpressionDeclMap *decl_map); + +protected: + + void DumpLocation(Stream *s, uint32_t offset, uint32_t length, lldb::DescriptionLevel level) const; + //------------------------------------------------------------------ + // Classes that inherit from DWARFExpression can see and modify these + //------------------------------------------------------------------ + DataExtractor m_data; + int m_reg_kind; // One of the defines that starts with LLDB_REGKIND_ + Address m_loclist_base_addr; // Base address needed for location lists + ClangExpressionVariableList *m_expr_locals; + ClangExpressionDeclMap *m_decl_map; +}; + +} // namespace lldb_private + +#endif // liblldb_DWARFExpression_h_ diff --git a/lldb/include/lldb/Expression/RecordingMemoryManager.h b/lldb/include/lldb/Expression/RecordingMemoryManager.h new file mode 100644 index 00000000000..8ebc08e1158 --- /dev/null +++ b/lldb/include/lldb/Expression/RecordingMemoryManager.h @@ -0,0 +1,154 @@ +//===-- RecordingMemoryManager.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_RecordingMemoryManager_h_ +#define lldb_RecordingMemoryManager_h_ + +// C Includes +// C++ Includes +#include <string> +#include <vector> +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "lldb/Expression/ClangExpression.h" + +namespace lldb_private { + +class RecordingMemoryManager : public llvm::JITMemoryManager +{ + +// I can't write the JIT code in this class because this class has to be +// built without RTTI, which means I can't include Process.h. But I don't +// want to write iterators or "do_over_regions" functions right now, so I'm +// just going to let the ClangExpression handle it using our data members directly. + +friend bool ClangExpression::WriteJITCode (const ExecutionContext &exc_context); + +public: + RecordingMemoryManager (); + virtual ~RecordingMemoryManager(); + + virtual void setMemoryWritable (); + + virtual void setMemoryExecutable (); + + virtual void setPoisonMemory (bool poison) + { + m_default_mm_ap->setPoisonMemory (poison); + } + + virtual void AllocateGOT() + { + m_default_mm_ap->AllocateGOT(); + } + + + virtual uint8_t *getGOTBase() const + { + return m_default_mm_ap->getGOTBase(); + } + + virtual uint8_t *startFunctionBody(const llvm::Function *F, + uintptr_t &ActualSize); + + virtual uint8_t *allocateStub(const llvm::GlobalValue* F, unsigned StubSize, + unsigned Alignment); + + virtual void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd); + + virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); + + virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); + + virtual void deallocateFunctionBody(void *Body); + + virtual uint8_t* startExceptionTable(const llvm::Function* F, + uintptr_t &ActualSize); + + virtual void endExceptionTable(const llvm::Function *F, uint8_t *TableStart, + uint8_t *TableEnd, uint8_t* FrameRegister); + + virtual void deallocateExceptionTable(void *ET); + + virtual size_t GetDefaultCodeSlabSize() { + return m_default_mm_ap->GetDefaultCodeSlabSize(); + } + + virtual size_t GetDefaultDataSlabSize() { + return m_default_mm_ap->GetDefaultDataSlabSize(); + } + + virtual size_t GetDefaultStubSlabSize() { + return m_default_mm_ap->GetDefaultStubSlabSize(); + } + + virtual unsigned GetNumCodeSlabs() { + return m_default_mm_ap->GetNumCodeSlabs(); + } + + virtual unsigned GetNumDataSlabs() { + return m_default_mm_ap->GetNumDataSlabs(); + } + + virtual unsigned GetNumStubSlabs() { + return m_default_mm_ap->GetNumStubSlabs(); + } + + // These are methods I've added so we can transfer the memory we've remembered down + // to the target program. For now I'm assuming all this code is PIC without fixups, + // so I'll just copy it blind, but if we need to we can do fixups later. + + lldb::addr_t + GetRemoteAddressForLocal (lldb::addr_t local_address); + + bool + WriteJITRegions (const ExecutionContext &exc_context); + + +private: + std::auto_ptr<JITMemoryManager> m_default_mm_ap; + std::map<uint8_t *, uint8_t *> m_functions; + std::map<uint8_t *, intptr_t> m_spaceBlocks; + std::map<uint8_t *, unsigned> m_stubs; + std::map<uint8_t *, uintptr_t> m_globals; + std::map<uint8_t *, uint8_t *> m_exception_tables; + + struct LocalToRemoteAddressRange + { + lldb::addr_t m_local_start; + size_t m_size; + lldb::addr_t m_remote_start; + + LocalToRemoteAddressRange (lldb::addr_t lstart, size_t size, lldb::addr_t rstart) : + m_local_start (lstart), + m_size (size), + m_remote_start (rstart) + {} + + }; + + void + AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart); + + // We should probably store this by address so we can efficiently + // search it but there really won't be many elements in this array + // at present. So we can put that off for now. + std::vector<LocalToRemoteAddressRange> m_address_map; + +}; + +}; // namespace lldb_private +#endif // lldb_RecordingMemoryManager_h_ diff --git a/lldb/include/lldb/Host/Condition.h b/lldb/include/lldb/Host/Condition.h new file mode 100644 index 00000000000..5ae50ae3fac --- /dev/null +++ b/lldb/include/lldb/Host/Condition.h @@ -0,0 +1,123 @@ +//===-- Condition.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DBCondition_h_ +#define liblldb_DBCondition_h_ +#if defined(__cplusplus) + + +#include <pthread.h> + +namespace lldb_private { + +class TimeValue; + +//---------------------------------------------------------------------- +/// @class Condition Condition.h "lldb/Host/Condition.h" +/// @brief A C++ wrapper class for pthread condition variables. +/// +/// A class that wraps up a pthread condition (pthread_cond_t). The +/// class will create a pthread condition when an instance is +/// constructed, and detroy it when it is destructed. It also provides +/// access to the standard pthread condition calls. +//---------------------------------------------------------------------- +class Condition +{ +public: + + //------------------------------------------------------------------ + /// Default constructor + /// + /// The default constructor will initialize a new pthread condition + /// and maintain the condition in the object state. + //------------------------------------------------------------------ + Condition (); + + //------------------------------------------------------------------ + /// Destructor + /// + /// Destroys the pthread condition that the object owns. + //------------------------------------------------------------------ + ~Condition (); + + //------------------------------------------------------------------ + /// Unblock all threads waiting for a condition variable + /// + /// @return + /// The return value from \c pthread_cond_broadcast() + //------------------------------------------------------------------ + int + Broadcast (); + + //------------------------------------------------------------------ + /// Get accessor to the pthread condition object. + /// + /// @return + /// A pointer to the condition variable owned by this object. + //------------------------------------------------------------------ + pthread_cond_t * + GetCondition (); + + //------------------------------------------------------------------ + /// Unblocks one thread waiting for the condition variable + /// + /// @return + /// The return value from \c pthread_cond_signal() + //------------------------------------------------------------------ + int + Signal (); + + //------------------------------------------------------------------ + /// Wait for the condition variable to be signaled. + /// + /// The Wait() function atomically blocks the current thread + /// waiting on this object's condition variable, and unblocks + /// \a mutex. The waiting thread unblocks only after another thread + /// signals or broadcasts this object's condition variable. + /// + /// If \a abstime is non-NULL, this function will return when the + /// system time reaches the time specified in \a abstime if the + /// condition variable doesn't get unblocked. If \a abstime is NULL + /// this function will wait for an infinite amount of time for the + /// condition variable to be unblocked. + /// + /// The current thread re-acquires the lock on \a mutex following + /// the wait. + /// + /// @param[in] mutex + /// The mutex to use in the \c pthread_cond_timedwait() or + /// \c pthread_cond_wait() calls. + /// + /// @param[in] abstime + /// An absolute time at which to stop waiting if non-NULL, else + /// wait an infinite amount of time for the condition variable + /// toget signaled. + /// + /// @param[out] timed_out + /// If not NULL, will be set to true if the wait timed out, and + // false otherwise. + /// + /// @see Condition::Broadcast() + /// @see Condition::Signal() + //------------------------------------------------------------------ + int + Wait (pthread_mutex_t *mutex, const TimeValue *abstime = NULL, bool *timed_out = NULL); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + pthread_cond_t m_condition; ///< The condition variable. +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif + diff --git a/lldb/include/lldb/Host/Endian.h b/lldb/include/lldb/Host/Endian.h new file mode 100644 index 00000000000..5d1e848ef31 --- /dev/null +++ b/lldb/include/lldb/Host/Endian.h @@ -0,0 +1,19 @@ +//===-- Endian.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_host_endian_h_ +#define liblldb_host_endian_h_ + +// TODO: come up with a more lldb specific solution instead of relying on +// macosx <machine/endian.h>.... + +#include <machine/endian.h> + +#endif // liblldb_host_endian_h_ + diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h new file mode 100644 index 00000000000..5f52085ae6d --- /dev/null +++ b/lldb/include/lldb/Host/Host.h @@ -0,0 +1,281 @@ +//===-- Host.h --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Host_h_ +#define liblldb_Host_h_ +#if defined(__cplusplus) + + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Host Host.h "lldb/Host/Host.h" +/// @brief A class that provides host computer information. +/// +/// Host is a class that answers information about the host operating +/// system. +//---------------------------------------------------------------------- +class Host +{ +public: + typedef bool (*MonitorChildProcessCallback) (void *callback_baton, + lldb::pid_t pid, + int signal, // Zero for no signal + int status); // Exit value of process if signal is zero + + //------------------------------------------------------------------ + /// Start monitoring a child process. + /// + /// Allows easy monitoring of child processes. \a callback will be + /// called when the child process exits or if it gets a signal. The + /// callback will only be called with signals if \a monitor_signals + /// is \b true. \a callback will usually be called from another + /// thread so the callback function must be thread safe. + /// + /// When the callback gets called, the return value indicates if + /// minotoring should stop. If \b true is returned from \a callback + /// the information will be removed. If \b false is returned then + /// monitoring will continue. If the child process exits, the + /// monitoring will automatically stop after the callback returned + /// ragardless of the callback return value. + /// + /// @param[in] callback + /// A function callback to call when a child receives a signal + /// (if \a monitor_signals is true) or a child exits. + /// + /// @param[in] callback_baton + /// A void * of user data that will be pass back when + /// \a callback is called. + /// + /// @param[in] pid + /// The process ID of a child process to monitor, -1 for all + /// processes. + /// + /// @param[in] monitor_signals + /// If \b true the callback will get called when the child + /// process gets a signal. If \b false, the callback will only + /// get called if the child process exits. + /// + /// @return + /// A unique handle to the process monitoring information that + /// can be used to stop monitoring a child process. + /// + /// @see static void Host::StopMonitoringChildProcess (uint32_t) + //------------------------------------------------------------------ + static uint32_t + StartMonitoringChildProcess (MonitorChildProcessCallback callback, + void *callback_baton, + lldb::pid_t pid, + bool monitor_signals); + + //------------------------------------------------------------------ + /// Stop monitoring a child process. + /// + /// @param[in] handle + /// A unique handle returned from a previous call to + /// Host::StartMonitoringChildProcess(...). + /// + /// @return + /// \b true if the the handle was found and disabled, \b false + /// if the monitor map with handle of \a handle was not found. + /// + /// @see static int Host::StartMonitoringChildProcess (MonitorChildProcessCallback *, void *, lldb::pid_t, bool) + //------------------------------------------------------------------ + static bool + StopMonitoringChildProcess (uint32_t handle); + + //------------------------------------------------------------------ + /// Get the host page size. + /// + /// @return + /// The size in bytes of a VM page on the host system. + //------------------------------------------------------------------ + static size_t + GetPageSize(); + + //------------------------------------------------------------------ + /// Returns the endianness of the host system. + /// + /// @return + /// Returns the endianness of the host system as a lldb::ByteOrder + /// enumeration. + //------------------------------------------------------------------ + static lldb::ByteOrder + GetByteOrder (); + + //------------------------------------------------------------------ + /// Gets the host kernel architecture. + /// + /// @return + /// A const architecture object that represents the host kernel + /// architecture. + //------------------------------------------------------------------ + static const ArchSpec & + GetArchitecture (); + + //------------------------------------------------------------------ + /// Gets the host vendor string. + /// + /// @return + /// A const string object containing the host vendor name. + //------------------------------------------------------------------ + static const ConstString & + GetVendorString (); + + //------------------------------------------------------------------ + /// Gets the host Operating System (OS) string. + /// + /// @return + /// A const string object containing the host OS name. + //------------------------------------------------------------------ + static const ConstString & + GetOSString (); + + //------------------------------------------------------------------ + /// Gets the host target triple as a const string. + /// + /// @return + /// A const string object containing the host target triple. + //------------------------------------------------------------------ + static const ConstString & + GetTargetTriple (); + + //------------------------------------------------------------------ + /// Get the process ID for the calling process. + /// + /// @return + /// The process ID for the current process. + //------------------------------------------------------------------ + static lldb::pid_t + GetCurrentProcessID (); + + //------------------------------------------------------------------ + /// Get the thread ID for the calling thread in the current process. + /// + /// @return + /// The thread ID for the calling thread in the current process. + //------------------------------------------------------------------ + static lldb::pid_t + GetCurrentThreadID (); + + static const char * + GetSignalAsCString (int signo); + + static void + WillTerminate (); + //------------------------------------------------------------------ + /// Host specific thread created function call. + /// + /// This function call lets the current host OS do any thread + /// specific initialization that it needs, including naming the + /// thread. No cleanup routine is exptected to be called + /// + /// @param[in] name + /// The current thread's name in the current process. + //------------------------------------------------------------------ + static void + ThreadCreated (const char *name); + + static lldb::thread_t + ThreadCreate (const char *name, + lldb::thread_func_t function, + lldb::thread_arg_t thread_arg, + Error *err); + + static bool + ThreadCancel (lldb::thread_t thread, + Error *error); + + static bool + ThreadDetach (lldb::thread_t thread, + Error *error); + static bool + ThreadJoin (lldb::thread_t thread, + lldb::thread_result_t *thread_result_ptr, + Error *error); + + //------------------------------------------------------------------ + /// Gets the name of a thread in a process. + /// + /// This function will name a thread in a process using it's own + /// thread name pool, and also will attempt to set a thread name + /// using any supported host OS APIs. + /// + /// @param[in] pid + /// The process ID in which we are trying to get the name of + /// a thread. + /// + /// @param[in] tid + /// The thread ID for which we are trying retrieve the name of. + /// + /// @return + /// A NULL terminate C string name that is owned by a static + /// global string pool, or NULL if there is no matching thread + /// name. This string does not need to be freed. + //------------------------------------------------------------------ + static const char * + GetThreadName (lldb::pid_t pid, lldb::tid_t tid); + + //------------------------------------------------------------------ + /// Sets the name of a thread in the current process. + /// + /// @param[in] pid + /// The process ID in which we are trying to name a thread. + /// + /// @param[in] tid + /// The thread ID which we are trying to name. + /// + /// @param[in] name + /// The current thread's name in the current process to \a name. + /// + /// @return + /// \b true if the thread name was able to be set, \b false + /// otherwise. + //------------------------------------------------------------------ + static void + SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name); + + //------------------------------------------------------------------ + /// Gets the FileSpec of the current process (the process that + /// that is running the LLDB code). + /// + /// @return + /// \b A file spec with the program name. + //------------------------------------------------------------------ + static FileSpec + GetProgramFileSpec (); + + //------------------------------------------------------------------ + /// Given an address in the current process (the process that + /// is running the LLDB code), return the name of the module that + /// it comes from. This can be useful when you need to know the + /// path to the shared library that your code is running in for + /// loading resources that are relative to your binary. + /// + /// @param[in] host_addr + /// The pointer to some code in the current process. + /// + /// @return + /// \b A file spec with the module that contains \a host_addr, + /// which may be invalid if \a host_addr doesn't fall into + /// any valid module address range. + //------------------------------------------------------------------ + static FileSpec + GetModuleFileSpecForHostAddress (const void *host_addr); + + static bool + ResolveExecutableInBundle (FileSpec *file); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Host_h_ diff --git a/lldb/include/lldb/Host/Mutex.h b/lldb/include/lldb/Host/Mutex.h new file mode 100644 index 00000000000..19f613a86f6 --- /dev/null +++ b/lldb/include/lldb/Host/Mutex.h @@ -0,0 +1,242 @@ +//===-- Mutex.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Mutex_h_ +#define liblldb_Mutex_h_ +#if defined(__cplusplus) + +#include <pthread.h> +#include <assert.h> + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Mutex Mutex.h "lldb/Host/Mutex.h" +/// @brief A C++ wrapper class for pthread mutexes. +//---------------------------------------------------------------------- +class Mutex +{ +public: + enum Type + { + eMutexTypeNormal, ///< Mutex that can't recursively entered by the same thread + eMutexTypeRecursive, ///< Mutex can be recursively entered by the same thread + }; + + //------------------------------------------------------------------ + /// @class Mutex::Locker + /// + /// A scoped locking class that allows a variety of pthread mutex + /// objects to have a mutex locked when an Mutex::Locker + /// object is created, and unlocked when it goes out of scope or + /// when the Mutex::Locker::Reset(pthread_mutex_t *) + /// is called. This provides an exception safe way to lock a mutex + /// in a scope. + //------------------------------------------------------------------ + class Locker + { + public: + //-------------------------------------------------------------- + /// Default constructor. + /// + /// This will create a scoped mutex locking object that doesn't + /// have a mutex to lock. One will need to be provided using the + /// Mutex::Locker::Reset(pthread_mutex_t *) method. + /// + /// @see Mutex::Locker::Reset(pthread_mutex_t *) + //-------------------------------------------------------------- + Locker(); + + //-------------------------------------------------------------- + /// Constructor with a Mutex object. + /// + /// This will create a scoped mutex locking object that extracts + /// the mutex owned by \a m and locks it. + /// + /// @param[in] m + /// An instance of a Mutex object that contains a + /// valid mutex object. + //-------------------------------------------------------------- + Locker(Mutex& m); + + //-------------------------------------------------------------- + /// Constructor with a Mutex object pointer. + /// + /// This will create a scoped mutex locking object that extracts + /// the mutex owned by a m and locks it. + /// + /// @param[in] m + /// A pointer to instance of a Mutex object that + /// contains a valid mutex object. + //-------------------------------------------------------------- + Locker(Mutex* m); + + //-------------------------------------------------------------- + /// Constructor with a raw pthread mutex object pointer. + /// + /// This will create a scoped mutex locking object that locks + /// \a mutex. + /// + /// @param[in] mutex + /// A pointer to a pthread_mutex_t that will get locked if + /// non-NULL. + //-------------------------------------------------------------- + Locker(pthread_mutex_t *mutex); + + //-------------------------------------------------------------- + /// Desstructor + /// + /// Unlocks any valid pthread_mutex_t that this object may + /// contain. + //-------------------------------------------------------------- + ~Locker(); + + //-------------------------------------------------------------- + /// Change the contained mutex. + /// + /// Unlock the current mutex in this object (if it contains a + /// valid mutex) and lock the new \a mutex object if it is + /// non-NULL. + //-------------------------------------------------------------- + void + Reset(pthread_mutex_t *mutex = NULL); + + //-------------------------------------------------------------- + /// Change the contained mutex only if the mutex can be locked. + /// + /// Unlock the current mutex in this object (if it contains a + /// valid mutex) and try to lock \a mutex. If \a mutex can be + /// locked this object will take ownership of the lock and will + /// unlock it when it goes out of scope or Reset or TryLock are + /// called again. If the mutex is already locked, this object + /// will not take ownership of the mutex. + /// + /// @return + /// Returns \b true if the lock was aquired and the this + /// object will unlock the mutex when it goes out of scope, + /// returns \b false otherwise. + //-------------------------------------------------------------- + bool + TryLock (pthread_mutex_t *mutex); + + protected: + //-------------------------------------------------------------- + /// Member variables + //-------------------------------------------------------------- + pthread_mutex_t *m_mutex_ptr; ///< A pthread mutex that is locked when + ///< acquired and unlocked when destroyed + ///< or reset. + + private: + Locker(const Locker&); + const Locker& operator=(const Locker&); + }; + + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Creates a pthread mutex with no attributes. + //------------------------------------------------------------------ + Mutex(); + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Creates a pthread mutex with \a type as the mutex type. + /// Valid values for \a type include: + /// @li Mutex::Type::eMutexTypeNormal + /// @li Mutex::Type::eMutexTypeRecursive + /// + /// @param[in] type + /// The type of the mutex. + /// + /// @see ::pthread_mutexattr_settype() + //------------------------------------------------------------------ + Mutex(Mutex::Type type); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// Destroys the mutex owned by this object. + //------------------------------------------------------------------ + ~Mutex(); + + //------------------------------------------------------------------ + /// Mutex get accessor. + /// + /// @return + /// A pointer to the pthread mutex object owned by this object. + //------------------------------------------------------------------ + pthread_mutex_t * + GetMutex(); + + //------------------------------------------------------------------ + /// Lock the mutex. + /// + /// Locks the mutex owned by this object. If the mutex is already + /// locked, the calling thread will block until the mutex becomes + /// available. + /// + /// @return + /// The error code from \c pthread_mutex_lock(). + //------------------------------------------------------------------ + int + Lock(); + + //------------------------------------------------------------------ + /// Try to lock the mutex. + /// + /// Attempts to lock the mutex owned by this object without blocking. + /// If the mutex is already locked, TryLock() will not block waiting + /// for the mutex, but will return an error condition. + /// + /// @return + /// The error code from \c pthread_mutex_trylock(). + //------------------------------------------------------------------ + int + TryLock(); + + //------------------------------------------------------------------ + /// Unlock the mutex. + /// + /// If the current thread holds the lock on the owned mutex, then + /// Unlock() will unlock the mutex. Calling Unlock() on this object + /// when the calling thread does not hold the lock will result in + /// undefined behavior. + /// + /// @return + /// The error code from \c pthread_mutex_unlock(). + //------------------------------------------------------------------ + int + Unlock(); + + static + int Lock (pthread_mutex_t *mutex_ptr); + + static + int TryLock (pthread_mutex_t *mutex_ptr); + + static + int Unlock (pthread_mutex_t *mutex_ptr); + +protected: + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + pthread_mutex_t m_mutex; ///< The pthread mutex object. +private: + Mutex(const Mutex&); + const Mutex& operator=(const Mutex&); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif diff --git a/lldb/include/lldb/Host/Predicate.h b/lldb/include/lldb/Host/Predicate.h new file mode 100644 index 00000000000..9c3f10bceae --- /dev/null +++ b/lldb/include/lldb/Host/Predicate.h @@ -0,0 +1,411 @@ +//===-- Predicate.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Predicate_h_ +#define liblldb_Predicate_h_ +#if defined(__cplusplus) + +#include "lldb/Host/Mutex.h" +#include "lldb/Host/Condition.h" +#include <stdint.h> +#include <time.h> + +//#define DB_PTHREAD_LOG_EVENTS + +//---------------------------------------------------------------------- +/// Enumerations for broadcasting. +//---------------------------------------------------------------------- +namespace lldb_private { + +typedef enum +{ + eBroadcastNever, ///< No broadcast will be sent when the value is modified. + eBroadcastAlways, ///< Always send a broadcast when the value is modified. + eBroadcastOnChange ///< Only broadcast if the value changes when the value is modified. + +} PredicateBroadcastType; + +//---------------------------------------------------------------------- +/// @class Predicate Predicate.h "lldb/Host/Predicate.h" +/// @brief A C++ wrapper class for providing threaded access to a value +/// of type T. +/// +/// A templatized class that provides multi-threaded access to a value +/// of type T. Threads can efficiently wait for bits within T to be set +/// or reset, or wait for T to be set to be equal/not equal to a +/// specified values. +//---------------------------------------------------------------------- +template <class T> +class Predicate +{ +public: + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initializes the mutex, condition and value with their default + /// constructors. + //------------------------------------------------------------------ + Predicate () : + m_mutex(), + m_condition(), + m_value() + { + } + + //------------------------------------------------------------------ + /// Construct with initial T value \a initial_value. + /// + /// Initializes the mutex and condition with their default + /// constructors, and initializes the value with \a initial_value. + /// + /// @param[in] initial_value + /// The initial value for our T object. + //------------------------------------------------------------------ + Predicate (T initial_value) : + m_mutex(), + m_condition(), + m_value(initial_value) + { + } + + //------------------------------------------------------------------ + /// Destructor. + /// + /// Destrory the condition, mutex, and T objects. + //------------------------------------------------------------------ + ~Predicate () + { + } + + + //------------------------------------------------------------------ + /// Value get accessor. + /// + /// Copies the current \a m_value in a thread safe manor and returns + /// the copied value. + /// + /// @return + /// A copy of the current value. + //------------------------------------------------------------------ + T + GetValue () const + { + Mutex::Locker locker(m_mutex); + T value = m_value; + return value; + } + + //------------------------------------------------------------------ + /// Value set accessor. + /// + /// Set the contained \a m_value to \a new_value in a thread safe + /// way and broadcast if needed. + /// + /// @param[in] value + /// The new value to set. + /// + /// @param[in] broadcast_type + /// A value indicating when and if to broadast. See the + /// PredicateBroadcastType enumeration for details. + /// + /// @see Predicate::Broadcast() + //------------------------------------------------------------------ + void + SetValue (T value, PredicateBroadcastType broadcast_type) + { + Mutex::Locker locker(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (value = 0x%8.8x, broadcast_type = %i)", __FUNCTION__, value, broadcast_type); +#endif + const T old_value = m_value; + m_value = value; + + Broadcast(old_value, broadcast_type); + } + + //------------------------------------------------------------------ + /// Set some bits in \a m_value. + /// + /// Logically set the bits \a bits in the contained \a m_value in a + /// thread safe way and broadcast if needed. + /// + /// @param[in] bits + /// The bits to set in \a m_value. + /// + /// @param[in] broadcast_type + /// A value indicating when and if to broadast. See the + /// PredicateBroadcastType enumeration for details. + /// + /// @see Predicate::Broadcast() + //------------------------------------------------------------------ + void + SetValueBits (T bits, PredicateBroadcastType broadcast_type) + { + Mutex::Locker locker(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, broadcast_type = %i)", __FUNCTION__, bits, broadcast_type); +#endif + const T old_value = m_value; + m_value |= bits; + + Broadcast(old_value, broadcast_type); + } + + //------------------------------------------------------------------ + /// Reset some bits in \a m_value. + /// + /// Logically reset (clear) the bits \a bits in the contained + /// \a m_value in a thread safe way and broadcast if needed. + /// + /// @param[in] bits + /// The bits to clear in \a m_value. + /// + /// @param[in] broadcast_type + /// A value indicating when and if to broadast. See the + /// PredicateBroadcastType enumeration for details. + /// + /// @see Predicate::Broadcast() + //------------------------------------------------------------------ + void + ResetValueBits (T bits, PredicateBroadcastType broadcast_type) + { + Mutex::Locker locker(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, broadcast_type = %i)", __FUNCTION__, bits, broadcast_type); +#endif + const T old_value = m_value; + m_value &= ~bits; + + Broadcast(old_value, broadcast_type); + } + + //------------------------------------------------------------------ + /// Wait for bits to be set in \a m_value. + /// + /// Waits in a thread safe way for any bits in \a bits to get + /// logically set in \a m_value. If any bits are already set in + /// \a m_value, this function will return without waiting. + /// + /// @param[in] bits + /// The bits we are waiting to be set in \a m_value. + /// + /// @param[in] abstime + /// If non-NULL, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @return + /// Any bits of the requested bits that actually were set within + /// the time specified. Zero if a timeout or unrecoverable error + /// occurred. + //------------------------------------------------------------------ + T + WaitForSetValueBits (T bits, const TimeValue *abstime = NULL) + { + int err = 0; + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (Mutex::Locker) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + Mutex::Locker locker(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x", __FUNCTION__, bits, abstime, m_value); +#endif + while (err == 0 && ((m_value & bits) == 0)) + { + err = m_condition.Wait (m_mutex.GetMutex(), abstime); + } +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x, returning 0x%8.8x", __FUNCTION__, bits, m_value, m_value & bits); +#endif + + return m_value & bits; + } + + //------------------------------------------------------------------ + /// Wait for bits to be reset in \a m_value. + /// + /// Waits in a thread safe way for any bits in \a bits to get + /// logically reset in \a m_value. If all bits are already reset in + /// \a m_value, this function will return without waiting. + /// + /// @param[in] bits + /// The bits we are waiting to be reset in \a m_value. + /// + /// @param[in] abstime + /// If non-NULL, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @return + /// Zero on successful waits, or non-zero if a timeout or + /// unrecoverable error occurs. + //------------------------------------------------------------------ + T + WaitForResetValueBits (T bits, const TimeValue *abstime = NULL) + { + int err = 0; + + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (Mutex::Locker) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + Mutex::Locker locker(m_mutex); + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x, abstime = %p), m_value = 0x%8.8x", __FUNCTION__, bits, abstime, m_value); +#endif + while (err == 0 && (m_value & bits != 0)) + { + err = m_condition.Wait (m_mutex.GetMutex(), abstime); + } + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (bits = 0x%8.8x), m_value = 0x%8.8x", __FUNCTION__, bits, m_value); +#endif + return m_value & bits; + } + + //------------------------------------------------------------------ + /// Wait for \a m_value to be equal to \a value. + /// + /// Waits in a thread safe way for \a m_value to be equal to \a + /// value. If \a m_value is already equal to \a value, this + /// function will return without waiting. + /// + /// @param[in] value + /// The value we want \a m_value to be equal to. + /// + /// @param[in] abstime + /// If non-NULL, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @param[out] timed_out + /// If not null, set to true if we return because of a time out, + /// and false if the value was set. + /// + /// @return + /// @li \b true if the \a m_value is equal to \a value + /// @li \b false otherwise + //------------------------------------------------------------------ + bool + WaitForValueEqualTo (T value, const TimeValue *abstime = NULL, bool *timed_out = NULL) + { + int err = 0; + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (Mutex::Locker) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + Mutex::Locker locker(m_mutex); + +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x", __FUNCTION__, value, abstime, m_value); +#endif + while (err == 0 && m_value != value) + { + err = m_condition.Wait (m_mutex.GetMutex(), abstime, timed_out); + } + + return m_value == value; + } + + //------------------------------------------------------------------ + /// Wait for \a m_value to not be equal to \a value. + /// + /// Waits in a thread safe way for \a m_value to not be equal to \a + /// value. If \a m_value is already not equal to \a value, this + /// function will return without waiting. + /// + /// @param[in] value + /// The value we want \a m_value to not be equal to. + /// + /// @param[out] new_value + /// The new value if \b true is returned. + /// + /// @param[in] abstime + /// If non-NULL, the absolute time at which we should stop + /// waiting, else wait an infinite amount of time. + /// + /// @return + /// @li \b true if the \a m_value is equal to \a value + /// @li \b false otherwise + //------------------------------------------------------------------ + bool + WaitForValueNotEqualTo (T value, T &new_value, const TimeValue *abstime = NULL) + { + int err = 0; + // pthread_cond_timedwait() or pthread_cond_wait() will atomically + // unlock the mutex and wait for the condition to be set. When either + // function returns, they will re-lock the mutex. We use an auto lock/unlock + // class (Mutex::Locker) to allow us to return at any point in this + // function and not have to worry about unlocking the mutex. + Mutex::Locker locker(m_mutex); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (value = 0x%8.8x, abstime = %p), m_value = 0x%8.8x", __FUNCTION__, value, abstime, m_value); +#endif + while (err == 0 && m_value == value) + { + err = m_condition.Wait (m_mutex.GetMutex(), abstime); + } + + if (m_value != value) + { + new_value = m_value; + return true; + } + return false; + } + +protected: + //---------------------------------------------------------------------- + // pthread condition and mutex variable to controll access and allow + // blocking between the main thread and the spotlight index thread. + //---------------------------------------------------------------------- + T m_value; ///< The templatized value T that we are protecting access to + mutable Mutex m_mutex; ///< The mutex to use when accessing the data + Condition m_condition; ///< The pthread condition variable to use for signaling that data available or changed. + +private: + + //------------------------------------------------------------------ + /// Broadcast if needed. + /// + /// Check to see if we need to broadcast to our condition variable + /// depedning on the \a old_value and on the \a broadcast_type. + /// + /// If \a broadcast_type is eBroadcastNever, no broadcast will be + /// sent. + /// + /// If \a broadcast_type is eBroadcastAlways, the condition variable + /// will always be broadcast. + /// + /// If \a broadcast_type is eBroadcastOnChange, the condition + /// variable be broadcast if the owned value changes. + //------------------------------------------------------------------ + void + Broadcast (T old_value, PredicateBroadcastType broadcast_type) + { + bool broadcast = (broadcast_type == eBroadcastAlways) || ((broadcast_type == eBroadcastOnChange) && old_value != m_value); +#ifdef DB_PTHREAD_LOG_EVENTS + printf("%s (old_value = 0x%8.8x, broadcast_type = %i) m_value = 0x%8.8x, broadcast = %u", __FUNCTION__, old_value, broadcast_type, m_value, broadcast); +#endif + if (broadcast) + m_condition.Broadcast(); + } + + + DISALLOW_COPY_AND_ASSIGN(Predicate); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // #ifndef liblldb_Predicate_h_ diff --git a/lldb/include/lldb/Host/Symbols.h b/lldb/include/lldb/Host/Symbols.h new file mode 100644 index 00000000000..7359dda8a6d --- /dev/null +++ b/lldb/include/lldb/Host/Symbols.h @@ -0,0 +1,37 @@ +//===-- Symbols.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Symbols_h_ +#define liblldb_Symbols_h_ + +// C Includes +#include <stdint.h> +#include <sys/time.h> + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/FileSpec.h" + +namespace lldb_private { + +class Symbols +{ +public: + static FileSpec + LocateExecutableObjectFile (const FileSpec *in_exec, const ArchSpec* arch, const UUID *uuid); + + static FileSpec + LocateExecutableSymbolFile (const FileSpec *in_exec, const ArchSpec* arch, const UUID *uuid); +}; + +} // namespace lldb_private + + +#endif // liblldb_Symbols_h_ diff --git a/lldb/include/lldb/Host/TimeValue.h b/lldb/include/lldb/Host/TimeValue.h new file mode 100644 index 00000000000..623660e2908 --- /dev/null +++ b/lldb/include/lldb/Host/TimeValue.h @@ -0,0 +1,90 @@ +//===-- TimeValue.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TimeValue_h_ +#define liblldb_TimeValue_h_ + +// C Includes +#include <stdint.h> +#include <sys/time.h> + +// C++ Includes +// Other libraries and framework includes +// Project includes + +namespace lldb_private { + +class TimeValue +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + TimeValue(); + TimeValue(const TimeValue& rhs); + TimeValue(const struct timespec& ts); + TimeValue(const struct timeval& tv); + ~TimeValue(); + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const TimeValue& + operator=(const TimeValue& rhs); + + void + Clear (); + + uint64_t + GetAsNanoSecondsSinceJan1_1970() const; + + uint64_t + GetAsMicroSecondsSinceJan1_1970() const; + + struct timespec + GetAsTimeSpec () const; + + struct timeval + GetAsTimeVal () const; + + bool + IsValid () const; + + void + OffsetWithSeconds (uint32_t sec); + + void + OffsetWithMicroSeconds (uint32_t usec); + + void + OffsetWithNanoSeconds (uint32_t nsec); + + static TimeValue + Now(); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from TimeValue can see and modify these + //------------------------------------------------------------------ + uint64_t m_nano_seconds; +}; + +bool operator == (const TimeValue &lhs, const TimeValue &rhs); +bool operator != (const TimeValue &lhs, const TimeValue &rhs); +bool operator < (const TimeValue &lhs, const TimeValue &rhs); +bool operator <= (const TimeValue &lhs, const TimeValue &rhs); +bool operator > (const TimeValue &lhs, const TimeValue &rhs); +bool operator >= (const TimeValue &lhs, const TimeValue &rhs); + +uint64_t operator -(const TimeValue &lhs, const TimeValue &rhs); + +} // namespace lldb_private + + +#endif // liblldb_TimeValue_h_ diff --git a/lldb/include/lldb/Host/Types.h b/lldb/include/lldb/Host/Types.h new file mode 100644 index 00000000000..1fa791cf692 --- /dev/null +++ b/lldb/include/lldb/Host/Types.h @@ -0,0 +1,98 @@ +//===-- Types.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#if 0 +#ifndef liblldb_host_types_h_ +#define liblldb_host_types_h_ + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// MACOSX START +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- + +#include <assert.h> +#include <mach/mach_types.h> +#include <machine/endian.h> +#include <pthread.h> +#include <signal.h> +#include <stdint.h> +#include <stdbool.h> +#include <sys/syslimits.h> +#include <unistd.h> + +#ifndef NO_RTTI + +//---------------------------------------------------------------------- +// And source files that may not have RTTI enabled during their +// compilation will want to do a "#define NO_RTTI" before including the +// lldb-include.h file. +//---------------------------------------------------------------------- + +#include <tr1/memory> // for std::tr1::shared_ptr + +#endif + +//---------------------------------------------------------------------- +// All host systems must define: +// liblldb::condition_t The native condition type (or a substitute class) for conditions on the host system. +// liblldb::mutex_t The native mutex type for mutex objects on the host system. +// liblldb::thread_t The native thread type for spawned threads on the system +// liblldb::thread_arg_t The type of the one any only thread creation argument for the host system +// liblldb::thread_result_t The return type that gets returned when a thread finishes. +// liblldb::thread_func_t The function prototype used to spawn a thread on the host system. +// liblldb::SharedPtr The template that wraps up the host version of a reference counted pointer (like boost::shared_ptr) +// #define LLDB_INVALID_PROCESS_ID ... +// #define LLDB_INVALID_THREAD_ID ... +// #define LLDB_INVALID_HOST_THREAD ... +//---------------------------------------------------------------------- + +// TODO: Add a bunch of ifdefs to determine the host system and what +// things should be defined. Currently MacOSX is being assumed by default +// since that is what lldb was first developed for. + +namespace lldb_private { + //---------------------------------------------------------------------- + // MacOSX Types + //---------------------------------------------------------------------- + typedef ::pthread_mutex_t mutex_t; + typedef pthread_cond_t condition_t; + typedef pthread_t thread_t; // Host thread type + typedef void * thread_arg_t; // Host thread argument type + typedef void * thread_result_t; // Host thread result type + typedef void * (*thread_func_t)(void *); // Host thread function type + +#ifndef NO_RTTI + // The template below can be used in a few useful ways: + // + // // Make a single shared pointer a class Foo + // lldb::SharePtr<Foo>::Type foo_sp; + // + // // Make a typedef to a Foo shared pointer + // typedef lldb::SharePtr<Foo>::Type FooSP; + // + template<typename _Tp> + struct SharedPtr + { + typedef std::tr1::shared_ptr<_Tp> Type; + }; +#endif + +} // namespace lldb_private + +#define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL) +#define LLDB_INVALID_HOST_TIME { 0, 0 } + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// MACOSX END +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- + +#endif // liblldb_host_types_h_ +#endif diff --git a/lldb/include/lldb/Interpreter/CommandCompletions.h b/lldb/include/lldb/Interpreter/CommandCompletions.h new file mode 100644 index 00000000000..98cba48f08a --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -0,0 +1,240 @@ +//===-- CommandCompletions.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_CommandCompletions_h_ +#define lldb_CommandCompletions_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Core/RegularExpression.h" + +namespace lldb_private +{ +class CommandCompletions +{ +public: + + //---------------------------------------------------------------------- + // This is the command completion callback that is used to complete the argument of the option + // it is bound to (in the OptionDefinition table below). Return the total number of matches. + //---------------------------------------------------------------------- + typedef int (*CompletionCallback) (const char *completion_str, // This is the argument we are completing + int match_start_point, // This is the point in the list of matches that you should start returning elements + int max_return_elements, // This is the number of matches requested. + lldb_private::CommandInterpreter *interpreter, // The command interpreter running this command. + lldb_private::SearchFilter *searcher, // A search filter to limit the search... + lldb_private::StringList &matches); // The array of matches we return. + typedef enum + { + eNoCompletion = 0, + eSourceFileCompletion = (1 << 0), + eDiskFileCompletion = (1 << 1), + eSymbolCompletion = (1 << 2), + eModuleCompletion = (1 << 3), + eCustomCompletion = (1 << 4) // This item serves two purposes. It is the last element in the enum, + // so you can add custom enums starting from here in your Option class. + // Also if you & in this bit the base code will not process the option. + + } CommonCompletionTypes; + + struct CommonCompletionElement + { + CommonCompletionTypes type; + CompletionCallback callback; + }; + + static bool InvokeCommonCompletionCallbacks (uint32_t completion_mask, + const char *completion_str, + int match_start_point, + int max_return_elements, + lldb_private::CommandInterpreter *interpreter, + SearchFilter *searcher, + StringList &matches); + + //---------------------------------------------------------------------- + // These are the generic completer functions: + //---------------------------------------------------------------------- + static int + SourceFiles (const char *partial_file_name, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + SearchFilter *searcher, + StringList &matches); + + static int + Modules (const char *partial_file_name, + int match_start_point, + int max_return_elements, + lldb_private::CommandInterpreter *interpreter, + SearchFilter *searcher, + lldb_private::StringList &matches); + + static int + Symbols (const char *partial_file_name, + int match_start_point, + int max_return_elements, + lldb_private::CommandInterpreter *interpreter, + SearchFilter *searcher, + lldb_private::StringList &matches); + + //---------------------------------------------------------------------- + // The Completer class is a convenient base class for building searchers + // that go along with the SearchFilter passed to the standard Completer + // functions. + //---------------------------------------------------------------------- + class Completer : public Searcher + { + public: + Completer (const char *completion_str, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + virtual ~Completer (); + + virtual CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool complete) = 0; + + virtual Depth + GetDepth () = 0; + + virtual size_t + DoCompletion (SearchFilter *filter) = 0; + + protected: + std::string m_completion_str; + int m_match_start_point; + int m_max_return_elements; + CommandInterpreter *m_interpreter; + StringList &m_matches; + private: + DISALLOW_COPY_AND_ASSIGN (Completer); + }; + + //---------------------------------------------------------------------- + // SouceFileCompleter implements the source file completer + //---------------------------------------------------------------------- + class SourceFileCompleter : public Completer + { + public: + + SourceFileCompleter (bool include_support_files, + const char *completion_str, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + virtual Searcher::Depth GetDepth (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool complete); + + size_t + DoCompletion (SearchFilter *filter); + + private: + bool m_include_support_files; + FileSpecList m_matching_files; + const char *m_file_name; + const char *m_dir_name; + DISALLOW_COPY_AND_ASSIGN (SourceFileCompleter); + + }; + + //---------------------------------------------------------------------- + // ModuleCompleter implements the module completer + //---------------------------------------------------------------------- + class ModuleCompleter : public Completer + { + public: + + ModuleCompleter (const char *completion_str, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + virtual Searcher::Depth GetDepth (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool complete); + + size_t + DoCompletion (SearchFilter *filter); + + private: + const char *m_file_name; + const char *m_dir_name; + DISALLOW_COPY_AND_ASSIGN (ModuleCompleter); + + }; + + //---------------------------------------------------------------------- + // SymbolCompleter implements the symbol completer + //---------------------------------------------------------------------- + class SymbolCompleter : public Completer + { + public: + + SymbolCompleter (const char *completion_str, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + virtual Searcher::Depth GetDepth (); + + virtual Searcher::CallbackReturn + SearchCallback (SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool complete); + + size_t + DoCompletion (SearchFilter *filter); + + private: + struct NameCmp { + bool operator() (const ConstString& lhs, const ConstString& rhs) const + { + return lhs < rhs; + } + }; + + RegularExpression m_regex; + typedef std::set<ConstString, NameCmp> collection; + collection m_match_set; + DISALLOW_COPY_AND_ASSIGN (SymbolCompleter); + + }; + +private: + static CommonCompletionElement g_common_completions[]; + +}; + +}; // namespace lldb_private +#endif // lldb_CommandCompletions_h_ diff --git a/lldb/include/lldb/Interpreter/CommandContext.h b/lldb/include/lldb/Interpreter/CommandContext.h new file mode 100644 index 00000000000..69bd27e2472 --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandContext.h @@ -0,0 +1,43 @@ +//===-- CommandContext.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandContext_h_ +#define liblldb_CommandContext_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/ValueObjectList.h" + +namespace lldb_private { + +class CommandContext +{ +public: + CommandContext (); + + ~CommandContext (); + + void + Update (ExecutionContext *override_context = NULL); + + Target * + GetTarget(); + + ExecutionContext & + GetExecutionContext(); + +private: + ExecutionContext m_exe_ctx; +}; + +} // namespace lldb_private + +#endif // liblldb_CommandContext_h_ diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h new file mode 100644 index 00000000000..933fce47ff0 --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -0,0 +1,264 @@ +//===-- CommandInterpreter.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandInterpreter_h_ +#define liblldb_CommandInterpreter_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Log.h" +#include "lldb/Interpreter/CommandContext.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Interpreter/StateVariable.h" +#include "lldb/Core/Event.h" +#include "lldb/Core/Args.h" +#include "lldb/Core/StringList.h" + +namespace lldb_private { + +class CommandInterpreter : public Broadcaster +{ +public: + typedef std::map<std::string, lldb::StateVariableSP> VariableMap; + typedef std::map<std::string, OptionArgVectorSP> OptionArgMap; + + enum + { + eBroadcastBitThreadShouldExit = (1 << 0), + eBroadcastBitResetPrompt = (1 << 1), + eBroadcastBitQuitCommandReceived = (1 << 2) // User entered quit + }; + + void + SourceInitFile (bool in_cwd, CommandReturnObject &result); + + CommandInterpreter (lldb::ScriptLanguage script_language, + bool synchronous_execution, + Listener *listener, // In case this is asked to create or attach to a process + SourceManager& source_manager); + + virtual + ~CommandInterpreter (); + + lldb::CommandObjectSP + GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL); + + CommandObject * + GetCommandObject (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL); + + StateVariable * + GetStateVariable(const char *name); + + bool + CommandExists (const char *cmd); + + bool + AliasExists (const char *cmd); + + bool + UserCommandExists (const char *cmd); + + void + AddAlias (const char *alias_name, lldb::CommandObjectSP& command_obj_sp); + + bool + RemoveAlias (const char *alias_name); + + bool + RemoveUser (const char *alias_name); + + OptionArgVectorSP + GetAliasOptions (const char *alias_name); + + void + RemoveAliasOptions (const char *alias_name); + + void + AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp); + + bool + HandleCommand (const char *command_line, bool add_to_history, CommandReturnObject &result, + ExecutionContext *override_context = NULL); + + // This handles command line completion. You are given a pointer to the command string buffer, to the current cursor, + // and to the end of the string (in case it is not NULL terminated). + // You also passed in an Args object to fill with the returns. + // The first element of the array will be filled with the string that you would need to insert at + // the cursor point to complete the cursor point to the longest common matching prefix. + // If you want to limit the number of elements returned, set max_return_elements to the number of elements + // you want returned. Otherwise set max_return_elements to -1. + // If you want to start some way into the match list, then set match_start_point to the desired start + // point. + // Returns the total number of completions, or -1 if the completion character should be inserted, or + // INT_MAX if the number of matches is > max_return_elements, but it is expensive to compute. + // + // FIXME: Only max_return_elements == -1 is supported at present. + + int + HandleCompletion (const char *current_line, + const char *cursor, + const char *last_char, + int match_start_point, + int max_return_elements, + StringList &matches); + + // This version just returns matches, and doesn't compute the substring. It is here so the + // Help command can call it for the first argument. + + int + HandleCompletionMatches (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + StringList &matches); + + + int + GetCommandNamesMatchingPartialString (const char *cmd_cstr, bool include_aliases, StringList &matches); + + void + GetHelp (CommandReturnObject &result); + + void + GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string); + + void + OutputFormattedHelpText (Stream &stream, + const char *command_word, + const char *separator, + const char *help_text, + uint32_t max_word_len); + + void + ShowVariableValues (CommandReturnObject &result); + + void + ShowVariableHelp (CommandReturnObject &result); + + CommandContext * + Context(); + + const Args * + GetProgramArguments (); + + const Args * + GetEnvironmentVariables (); + + const char * + ProcessEmbeddedScriptCommands (const char *arg); + + Listener * + GetListener (); + + SourceManager & + GetSourceManager (); + + const char * + GetPrompt (); + + void + SetPrompt (const char *); + + void + LoadCommandDictionary (); + + void + Initialize (); + + void + InitializeVariables (); + + void + CrossRegisterCommand (const char * dest_cmd, const char * object_type); + + void + SetScriptLanguage (lldb::ScriptLanguage lang); + + + bool + HasCommands (); + + bool + HasAliases (); + + bool + HasUserCommands (); + + bool + HasAliasOptions (); + + bool + HasInterpreterVariables (); + + void + BuildAliasCommandArgs (CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, + CommandReturnObject &result); + + int + GetOptionArgumentPosition (const char *in_string); + + ScriptInterpreter * + GetScriptInterpreter (); + + bool + GetSynchronous (); + +#ifndef SWIG + void + AddLogChannel (const char *name, const Log::Callbacks &log_callbacks); + + bool + GetLogChannelCallbacks (const char *channel, Log::Callbacks &log_callbacks); + + bool + RemoveLogChannel (const char *name); +#endif + + std::string + FindLongestCommandWord (CommandObject::CommandMap &dict); + + void + FindCommandsForApropos (const char *word, StringList &commands_found, StringList &commands_help); + + void + AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word, + StringList &commands_found, StringList &commands_help); + +protected: + friend class Debugger; + + void + SetSynchronous (bool value); + +private: + + lldb::ScriptLanguage m_script_language; + CommandContext m_current_context; + bool m_synchronous_execution; + Listener *m_listener; + SourceManager& m_source_manager; + + CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten). + CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands + CommandObject::CommandMap m_user_dict; // Stores user-defined commands + VariableMap m_variables; + OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias. + std::vector<std::string> m_command_history; +}; + + +} // namespace lldb_private + +#endif // liblldb_CommandInterpreter_h_ diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h new file mode 100644 index 00000000000..ae050983e34 --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -0,0 +1,194 @@ +//===-- CommandObject.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObject_h_ +#define liblldb_CommandObject_h_ + +#include <map> +#include <set> +#include <string> +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/Args.h" +#include "lldb/Core/StringList.h" +#include "lldb/Core/Flags.h" + +namespace lldb_private { + +class CommandObject +{ +public: + typedef std::map<std::string, lldb::CommandObjectSP> CommandMap; + + + CommandObject (const char *name, + const char *help = NULL, + const char *syntax = NULL, + uint32_t flags = 0); + + virtual + ~CommandObject (); + + const char * + GetHelp (); + + const char * + GetHelpLong (); + + const char * + GetSyntax (); + + const char * + Translate (); + + const char * + GetCommandName (); + + void + SetHelp (const char * str); + + void + SetHelpLong (const char * str); + + void + SetSyntax (const char *str); + + virtual void + AddObject (const char *obj_name) {} + + virtual bool + IsCrossRefObject () { return false; } + + virtual bool + IsMultiwordObject () { return false; } + + virtual bool + WantsRawCommandString() { return false; } + + virtual Options * + GetOptions (); + + enum + { + eFlagProcessMustBeLaunched = (1 << 0), + eFlagProcessMustBePaused = (1 << 1) + }; + + // Do not override this + bool + ExecuteCommandString (const char *command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + bool + ParseOptions(Args& args, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + bool + ExecuteWithOptions (Args& command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + virtual bool + ExecuteRawCommandString (const char *command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result) + { + return false; + } + + + virtual bool + Execute (Args& command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result) = 0; + + void + SetCommandName (const char *name); + + // This function really deals with CommandObjectLists, but we didn't make a + // CommandObjectList class, so I'm sticking it here. But we really should have + // such a class. Anyway, it looks up the commands in the map that match the partial + // string cmd_str, inserts the matches into matches, and returns the number added. + + static int + AddNamesMatchingPartialString (CommandMap &in_map, const char *cmd_str, StringList &matches); + + // The input array contains a parsed version of the line. The insertion + // point is given by cursor_index (the index in input of the word containing + // the cursor) and cursor_char_position (the position of the cursor in that word.) + // This default version handles calling option argument completions and then calls + // HandleArgumentCompletion if the cursor is on an argument, not an option. + // Don't override this method, override HandleArgumentCompletion instead unless + // you have special reasons. + virtual int + HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + // The input array contains a parsed version of the line. The insertion + // point is given by cursor_index (the index in input of the word containing + // the cursor) and cursor_char_position (the position of the cursor in that word.) + // We've constructed the map of options and their arguments as well if that is + // helpful for the completion. + + virtual int + HandleArgumentCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + + bool + HelpTextContainsWord (const char *search_word); + + //------------------------------------------------------------------ + /// The flags accessor. + /// + /// @return + /// A reference to the Flags member variable. + //------------------------------------------------------------------ + Flags& + GetFlags(); + + //------------------------------------------------------------------ + /// The flags const accessor. + /// + /// @return + /// A const reference to the Flags member variable. + //------------------------------------------------------------------ + const Flags& + GetFlags() const; + +protected: + std::string m_cmd_name; + std::string m_cmd_help_short; + std::string m_cmd_help_long; + std::string m_cmd_syntax; + Flags m_flags; +}; + +} // namespace lldb_private + + +#endif // liblldb_CommandObject_h_ diff --git a/lldb/include/lldb/Interpreter/CommandObjectCrossref.h b/lldb/include/lldb/Interpreter/CommandObjectCrossref.h new file mode 100644 index 00000000000..c1e8e595363 --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandObjectCrossref.h @@ -0,0 +1,60 @@ +//===-- CommandObjectCrossref.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectCrossref_h_ +#define liblldb_CommandObjectCrossref_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Core/Args.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// CommandObjectCrossref +//------------------------------------------------------------------------- + +class CommandObjectCrossref : public CommandObject +{ +public: + CommandObjectCrossref (const char *name, + const char *help = NULL, + const char *syntax = NULL); + + virtual + ~CommandObjectCrossref (); + + void + GenerateHelpText (CommandReturnObject &result); + + virtual bool + Execute (Args& command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + virtual bool + IsCrossRefObject (); + + virtual void + AddObject (const char *obj_name); + + const char ** + GetObjectTypes () const; + +private: + Args m_crossref_object_types; +}; + +} // namespace lldb_private + +#endif // liblldb_CommandObjectCrossref_h_ diff --git a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h new file mode 100644 index 00000000000..90f9fd0b8df --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -0,0 +1,73 @@ +//===-- CommandObjectMultiword.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectMultiword_h_ +#define liblldb_CommandObjectMultiword_h_ + +// C Includes +// C++ Includes +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/CommandObject.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// CommandObjectMultiword +//------------------------------------------------------------------------- + +class CommandObjectMultiword : public CommandObject +{ +public: + CommandObjectMultiword (const char *name, + const char *help = NULL, + const char *syntax = NULL, + uint32_t flags = 0); + + virtual + ~CommandObjectMultiword (); + + virtual bool + IsMultiwordObject () { return true; } + + bool + LoadSubCommand (lldb::CommandObjectSP command_obj, const char *cmd_name, CommandInterpreter *interpreter); + + void + GenerateHelpText (CommandReturnObject &result, CommandInterpreter *interpreter); + + lldb::CommandObjectSP + GetSubcommandSP (const char *sub_cmd, StringList *matches = NULL); + + CommandObject * + GetSubcommandObject (const char *sub_cmd, StringList *matches = NULL); + + virtual bool + Execute (Args& command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + virtual int + HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + CommandInterpreter *interpreter, + StringList &matches); + + CommandObject::CommandMap m_subcommand_dict; +}; + +} // namespace lldb_private + +#endif // liblldb_CommandObjectMultiword_h_ diff --git a/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h b/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h new file mode 100644 index 00000000000..0c38f5b4fab --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h @@ -0,0 +1,73 @@ +//===-- CommandObjectRegexCommand.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectRegexCommand_h_ +#define liblldb_CommandObjectRegexCommand_h_ + +// C Includes +// C++ Includes +#include <list> + +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Core/RegularExpression.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// CommandObjectRegexCommand +//------------------------------------------------------------------------- + +class CommandObjectRegexCommand : public CommandObject +{ +public: + + CommandObjectRegexCommand (const char *name, const char *help, const char *syntax, uint32_t max_matches); + + virtual + ~CommandObjectRegexCommand (); + + virtual bool + Execute (Args& command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + virtual bool + WantsRawCommandString() { return true; } + + virtual bool + ExecuteRawCommandString (const char *command, + CommandContext *context, + CommandInterpreter *interpreter, + CommandReturnObject &result); + + + bool + AddRegexCommand (const char *re_cstr, const char *command_cstr); + +protected: + typedef struct Entry + { + RegularExpression regex; + std::string command; + }; + + typedef std::list<Entry> EntryCollection; + const uint32_t m_max_matches; + EntryCollection m_entries; + +private: + DISALLOW_COPY_AND_ASSIGN (CommandObjectRegexCommand); +}; + +} // namespace lldb_private + +#endif // liblldb_CommandObjectRegexCommand_h_ diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h new file mode 100644 index 00000000000..c95caa26002 --- /dev/null +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -0,0 +1,90 @@ +//===-- CommandReturnObject.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandReturnObject_h_ +#define liblldb_CommandReturnObject_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/STLUtils.h" +#include "lldb/Core/StreamString.h" + +namespace lldb_private { + + +class CommandReturnObject +{ +public: + + CommandReturnObject (); + + ~CommandReturnObject (); + + StreamString & + GetOutputStream (); + + StreamString & + GetErrorStream (); + + void + Clear(); + + void + AppendMessage (const char *in_string, int len = -1); + + void + AppendMessageWithFormat (const char *format, ...); + + void + AppendRawWarning (const char *in_string, int len = -1); + + void + AppendWarning (const char *in_string, int len = -1); + + void + AppendWarningWithFormat (const char *format, ...); + + void + AppendError (const char *in_string, int len = -1); + + void + AppendRawError (const char *in_string, int len = -1); + + void + AppendErrorWithFormat (const char *format, ...); + + lldb::ReturnStatus + GetStatus(); + + void + SetStatus (lldb::ReturnStatus status); + + bool + Succeeded (); + + bool + HasResult (); + + bool GetDidChangeProcessState (); + + void SetDidChangeProcessState (bool b); + +private: + StreamString m_output_stream; + StreamString m_error_stream; + lldb::ReturnStatus m_status; + bool m_did_change_process_state; +}; + +} // namespace lldb_private + +#endif // liblldb_CommandReturnObject_h_ diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h new file mode 100644 index 00000000000..aad6e30087b --- /dev/null +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -0,0 +1,103 @@ +//===-- ScriptInterpreter.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ScriptInterpreter_h_ +#define liblldb_ScriptInterpreter_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/Broadcaster.h" +#include "PseudoTerminal.h" + +namespace lldb_private { + +class ScriptInterpreter +{ +public: + + typedef enum + { + eCharPtr, + eBool, + eShortInt, + eShortIntUnsigned, + eInt, + eIntUnsigned, + eLongInt, + eLongIntUnsigned, + eLongLong, + eLongLongUnsigned, + eFloat, + eDouble, + eChar + } ReturnType; + + + ScriptInterpreter (lldb::ScriptLanguage script_lang); + + virtual ~ScriptInterpreter (); + + virtual void + ExecuteOneLine (const std::string&, FILE *, FILE *) = 0; + + virtual void + ExecuteInterpreterLoop (FILE *, FILE *) = 0; + + virtual bool + ExecuteOneLineWithReturn (const char *in_string, ReturnType return_type, void *ret_value) + { + return true; + } + + virtual bool + ExecuteMultipleLines (const char *in_string) + { + return true; + } + + virtual bool + ExportFunctionDefinitionToInterpreter (StringList &function_def) + { + return false; + } + + virtual bool + GenerateBreakpointCommandCallbackData (StringList &input, StringList &output) + { + return false; + } + + virtual void + CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CommandReturnObject &result); + + const char * + GetScriptInterpreterPtyName (); + + int + GetMasterFileDescriptor (); + + CommandInterpreter * + GetCommandInterpreter (); + +private: + lldb::ScriptLanguage m_script_lang; + + // Scripting languages may need to use stdin for their interactive loops; + // however we don't want them to grab the real system stdin because that + // resource needs to be shared among the debugger UI, the inferior process and these + // embedded scripting loops. Therefore we need to set up a pseudoterminal and use that + // as stdin for the script interpreter interactive loops/prompts. + + lldb_utility::PseudoTerminal m_interpreter_pty; + std::string m_pty_slave_name; +}; + +} // namespace lldb_private + +#endif // #ifndef liblldb_ScriptInterpreter_h_ diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterNone.h b/lldb/include/lldb/Interpreter/ScriptInterpreterNone.h new file mode 100644 index 00000000000..919e17fa956 --- /dev/null +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterNone.h @@ -0,0 +1,35 @@ +//===-- ScriptInterpreterNone.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ScriptInterpreterNone_h_ +#define liblldb_ScriptInterpreterNone_h_ + +#include "lldb/Interpreter/ScriptInterpreter.h" + +namespace lldb_private { + +class ScriptInterpreterNone : public ScriptInterpreter +{ +public: + + ScriptInterpreterNone (); + + ~ScriptInterpreterNone (); + + virtual void + ExecuteOneLine (const std::string &line, FILE *out, FILE *err); + + virtual void + ExecuteInterpreterLoop (FILE *out, FILE *err); + +}; + +} // namespace lldb_private + +#endif // #ifndef liblldb_ScriptInterpreterNone_h_ diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h new file mode 100644 index 00000000000..3eceb829a97 --- /dev/null +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -0,0 +1,86 @@ +//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_ScriptInterpreterPython_h_ +#define liblldb_ScriptInterpreterPython_h_ + +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Core/InputReader.h" + +#include <Python.h> + +namespace lldb_private { + +class ScriptInterpreterPython : public ScriptInterpreter +{ +public: + + ScriptInterpreterPython (); + + ~ScriptInterpreterPython (); + + void + ExecuteOneLine (const std::string &line, FILE *out, FILE *err); + + void + ExecuteInterpreterLoop (FILE *out, FILE *err); + + bool + ExecuteOneLineWithReturn (const char *in_string, + ScriptInterpreter::ReturnType return_type, + void *ret_value); + + bool + ExecuteMultipleLines (const char *in_string); + + bool + ExportFunctionDefinitionToInterpreter (StringList &function_def); + + bool + GenerateBreakpointCommandCallbackData (StringList &input, StringList &output); + + static size_t + GenerateBreakpointOptionsCommandCallback (void *baton, + InputReader *reader, + lldb::InputReaderAction notification, + const char *bytes, + size_t bytes_len); + + static bool + BreakpointCallbackFunction (void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + void + CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CommandReturnObject &result); + + StringList + ReadCommandInputFromUser (FILE *in_file); + +private: + + static size_t + InputReaderCallback (void *baton, + InputReader *reader, + lldb::InputReaderAction notification, + const char *bytes, + size_t bytes_len); + + PyObject *m_compiled_module; + struct termios m_termios; + bool m_termios_valid; +}; + +} // namespace lldb_private + + +#endif // #ifndef liblldb_ScriptInterpreterPython_h_ diff --git a/lldb/include/lldb/Interpreter/StateVariable.h b/lldb/include/lldb/Interpreter/StateVariable.h new file mode 100644 index 00000000000..34be0eedc43 --- /dev/null +++ b/lldb/include/lldb/Interpreter/StateVariable.h @@ -0,0 +1,145 @@ +//===-- StateVariable.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_InterpreterStateVariable_h_ +#define liblldb_InterpreterStateVariable_h_ + +// C Includes +// C++ Includes +#include <string> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Args.h" + +namespace lldb_private { + +class StateVariable +{ +public: + + // NOTE: If you add more types to this enumeration list, you need to check for them and "do the right thing" + // in CommandObjectSet::Execute. + typedef enum + { + eTypeBoolean, + eTypeInteger, + eTypeString, + eTypeStringArray + } Type; + + + typedef bool (*Callback) (CommandInterpreter *, + void *, + CommandReturnObject &); + + StateVariable (const char *name, + const char *value, + bool can_append = false, + const char *help_text = "", + Callback func_ptr = NULL); + + StateVariable (const char *name, + bool value, + const char *help_text = "", + Callback func_ptr = NULL); + + StateVariable (const char *name, + int value, + const char *help_text = "", + Callback func_ptr = NULL); + + StateVariable (const char *name, + const Args *value, + const char *help_text = "", + Callback func_ptr = NULL); + + virtual + ~StateVariable (); + + + const char * + GetName () const; + + Type + GetType () const; + + int + GetIntValue () const; + + bool + GetBoolValue () const; + + const char * + GetStringValue () const; + + Args & + GetArgs (); + + const Args & + GetArgs () const; + + const char * + GetHelp () const; + + void + SetHelp (const char *); + + void + AppendVariableInformation (CommandReturnObject &result); + + void + SetStringValue (const char *); + + void + SetIntValue (int); + + void + SetBoolValue (bool); + + void + ArrayAppendValue (const char *); + + void + ArrayClearValues (); + + void + AppendStringValue (const char *new_string); + + bool + VerifyValue (CommandInterpreter *interpreter, + void *data, + CommandReturnObject &result); + + bool + HasVerifyFunction (); + + static bool + VerifyScriptLanguage (CommandInterpreter *interpreter, + void *data, + CommandReturnObject &result); + + static bool + BroadcastPromptChange (CommandInterpreter *interpreter, + void *data, + CommandReturnObject &result); + +private: + std::string m_name; + Type m_type; + int m_int_value; + Args m_string_values; + std::string m_help_text; + Callback m_verification_func_ptr; +}; + + +} // namespace lldb_private + +#endif // liblldb_InterpreterStateVariable_h_ diff --git a/lldb/include/lldb/Symbol/Block.h b/lldb/include/lldb/Symbol/Block.h new file mode 100644 index 00000000000..1e2b23aa2f7 --- /dev/null +++ b/lldb/include/lldb/Symbol/Block.h @@ -0,0 +1,721 @@ +//===-- Block.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Block_h_ +#define liblldb_Block_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/UserID.h" +#include "lldb/Core/VMRange.h" +#include "lldb/Symbol/LineEntry.h" +#include "lldb/Symbol/SymbolContext.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Block Block.h "lldb/Symbol/Block.h" +/// @brief A class that describes a single lexical block. +/// +/// A Function object owns a BlockList object which owns one or more +/// Block objects. The BlockList object contains a section offset +/// address range, and Block objects contain one or more ranges +/// which are offsets into that range. Blocks are can have discontiguous +/// ranges within the BlockList adress range, and each block can +/// contain child blocks each with their own sets of ranges. +/// +/// Each block has a variable list that represents local, argument, and +/// static variables that are scoped to the block. +/// +/// Inlined functions are representated by attaching a +/// InlineFunctionInfo shared pointer object to a block. Inlined +/// functions are represented as named blocks. +//---------------------------------------------------------------------- +class Block : + public UserID, + public SymbolContextScope +{ +public: + friend class Function; + friend class BlockList; + //------------------------------------------------------------------ + /// Enumeration values for special and invalid Block User ID + /// values. + //------------------------------------------------------------------ + typedef enum + { + RootID = LLDB_INVALID_UID - 1, ///< The Block UID for the root block + InvalidID = LLDB_INVALID_UID ///< Invalid Block UID. + }; + + //------------------------------------------------------------------ + /// Construct with a User ID \a uid, \a depth. + /// + /// Initialize this block with the specified UID \a uid. The + /// \a depth in the \a block_list is used to represent the parent, + /// sibling, and child block information and also allows for partial + /// parsing at the block level. + /// + /// @param[in] uid + /// The UID for a given block. This value is given by the + /// SymbolFile plug-in and can be any value that helps the + /// SymbolFile plug-in to match this block back to the debug + /// information data that it parses for further or more in + /// depth parsing. Common values would be the index into a + /// table, or an offset into the debug information. + /// + /// @param[in] depth + /// The integer depth of this block in the block list hierarchy. + /// + /// @param[in] block_list + /// The block list that this object belongs to. + /// + /// @see BlockList + //------------------------------------------------------------------ + Block (lldb::user_id_t uid, uint32_t depth, BlockList* block_list); + + //------------------------------------------------------------------ + /// Copy constructor. + /// + /// Makes a copy of the another Block object \a rhs. + /// + /// @param[in] rhs + /// A const Block object reference to copy. + //------------------------------------------------------------------ + Block (const Block& rhs); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Block (); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies the block value from another Block object \a rhs + /// into \a this object. + /// + /// @param[in] rhs + /// A const Block object reference to copy. + /// + /// @return + /// A const Block object reference to \a this. + //------------------------------------------------------------------ + const Block& + operator= (const Block& rhs); + + //------------------------------------------------------------------ + /// Add a child to this object. + /// + /// @param[in] uid + /// The UID for a given block. This value is given by the + /// SymbolFile plug-in and can be any value that helps the + /// SymbolFile plug-in to match this block back to the debug + /// information data that it parses for further or more in + /// depth parsing. Common values would be the index into a + /// table, or an offset into the debug information. + /// + /// @return + /// Returns \a uid if the child was successfully added to this + /// block, or Block::InvalidID on failure. + //------------------------------------------------------------------ + lldb::user_id_t + AddChild (lldb::user_id_t uid); + + //------------------------------------------------------------------ + /// Add a new offset range to this block. + /// + /// @param[in] start_offset + /// An offset into this Function's address range that + /// describes the start address of a range for this block. + /// + /// @param[in] end_offset + /// An offset into this Function's address range that + /// describes the end address of a range for this block. + //------------------------------------------------------------------ + void + AddRange(lldb::addr_t start_offset, lldb::addr_t end_offset); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext(SymbolContext* sc); + + //------------------------------------------------------------------ + /// Check if an offset is in one of the block offset ranges. + /// + /// @param[in] range_offset + /// An offset into the Function's address range. + /// + /// @return + /// Returns \b true if \a range_offset falls in one of this + /// block's ranges, \b false otherwise. + //------------------------------------------------------------------ + bool + Contains (lldb::addr_t range_offset) const; + + //------------------------------------------------------------------ + /// Check if a offset range is in one of the block offset ranges. + /// + /// @param[in] range + /// An offset range into the Function's address range. + /// + /// @return + /// Returns \b true if \a range falls in one of this + /// block's ranges, \b false otherwise. + //------------------------------------------------------------------ + bool + Contains (const VMRange& range) const; + + bool + ContainsBlockWithID (lldb::user_id_t block_id) const; + + //------------------------------------------------------------------ + /// Dump the block contents. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] base_addr + /// The resolved start address of the Function's address + /// range. This should be resolved as the file or load address + /// prior to passing the value into this function for dumping. + /// + /// @param[in] depth + /// Limit the number of levels deep that this function should + /// print as this block can contain child blocks. Specify + /// INT_MAX to dump all child blocks. + /// + /// @param[in] show_context + /// If \b true, variables will dump their context information. + //------------------------------------------------------------------ + void + Dump (Stream *s, lldb::addr_t base_addr, int32_t depth, bool show_context) const; + + void + DumpStopContext (Stream *s, const SymbolContext *sc); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext(Stream *s); + + //------------------------------------------------------------------ + /// Get the parent block's UID. + /// + /// @return + /// The UID of the parent block, or Block::InvalidID + /// if this block has no parent. + //------------------------------------------------------------------ + lldb::user_id_t + GetParentUID () const; + + //------------------------------------------------------------------ + /// Get the sibling block's UID. + /// + /// @return + /// The UID of the sibling block, or Block::InvalidID + /// if this block has no sibling. + //------------------------------------------------------------------ + lldb::user_id_t + GetSiblingUID () const; + + //------------------------------------------------------------------ + /// Get the first child block's UID. + /// + /// @return + /// The UID of the first child block, or Block::InvalidID + /// if this block has no first child. + //------------------------------------------------------------------ + lldb::user_id_t + GetFirstChildUID () const; + + //------------------------------------------------------------------ + /// Get the variable list for this block and optionally all child + /// blocks if \a get_child_variables is \b true. + /// + /// @param[in] get_child_variables + /// If \b true, all variables from all child blocks will be + /// added to the variable list. + /// + /// @param[in] can_create + /// If \b true, the variables can be parsed if they already + /// haven't been, else the current state of the block will be + /// returned. Passing \b true for this parameter can be used + /// to see the current state of what has been parsed up to this + /// point. + /// + /// @return + /// A variable list shared pointer that contains all variables + /// for this block. + //------------------------------------------------------------------ + lldb::VariableListSP + GetVariableList (bool get_child_variables, bool can_create); + + + //------------------------------------------------------------------ + /// Appends the variables from this block, and optionally from all + /// parent blocks, to \a variable_list. + /// + /// @param[in] can_create + /// If \b true, the variables can be parsed if they already + /// haven't been, else the current state of the block will be + /// returned. Passing \b true for this parameter can be used + /// to see the current state of what has been parsed up to this + /// point. + /// + /// @param[in] get_parent_variables + /// If \b true, all variables from all parent blocks will be + /// added to the variable list. + /// + /// @param[in/out] variable_list + /// All variables in this block, and optionally all parent + /// blocks will be added to this list. + /// + /// @return + /// The number of variable that were appended to \a + /// variable_list. + //------------------------------------------------------------------ + uint32_t + AppendVariables(bool can_create, bool get_parent_variables, VariableList *variable_list); + + //------------------------------------------------------------------ + /// Get accessor for any inlined function information. + /// + /// @return + /// A pointer to any inlined function information, or NULL if + /// this is a regular block. + //------------------------------------------------------------------ + InlineFunctionInfo* + InlinedFunctionInfo (); + + //------------------------------------------------------------------ + /// Get const accessor for any inlined function information. + /// + /// @return + /// A cpmst pointer to any inlined function information, or NULL + /// if this is a regular block. + //------------------------------------------------------------------ + const InlineFunctionInfo* + InlinedFunctionInfo () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Returns the cost of this object plus any owned objects from the + /// ranges, variables, and inline function information. + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t + MemorySize() const; + + //------------------------------------------------------------------ + /// Set accessor for any inlined function information. + /// + /// @param[in] name + /// The method name for the inlined function. This value should + /// not be NULL. + /// + /// @param[in] mangled + /// The mangled method name for the inlined function. This can + /// be NULL if there is no mangled name for an inlined function + /// or if the name is the same as \a name. + /// + /// @param[in] decl_ptr + /// A optional pointer to declaration information for the + /// inlined function information. This value can be NULL to + /// indicate that no declaration information is available. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + void + SetInlinedFunctionInfo (const char *name, + const char *mangled, + const Declaration *decl_ptr, + const Declaration *call_decl_ptr); + + //------------------------------------------------------------------ + /// Set accessor for the variable list. + /// + /// Called by the SymbolFile plug-ins after they have parsed the + /// variable lists and are ready to hand ownership of the list over + /// to this object. + /// + /// @param[in] variable_list_sp + /// A shared pointer to a VariableList. + //------------------------------------------------------------------ + void + SetVariableList (lldb::VariableListSP& variable_list_sp); + +protected: + //------------------------------------------------------------------ + /// Get accessor for the integer block depth value. + /// + /// @return + /// The integer depth of this block in the block hiearchy. + //------------------------------------------------------------------ + uint32_t Depth () const; + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + BlockList *m_block_list; ///< The block list, one of which is this one + uint32_t m_depth; ///< The depth of this block where zero is the root block + VMRange::collection m_ranges; ///< A list of address offset ranges relative to the function's section/offset address. + lldb::InlineFunctionInfoSP m_inlineInfoSP; ///< Inlined function information. + lldb::VariableListSP m_variables; ///< The variable list for all local, static and paramter variables scoped to this block. + // TOOD: add a Type* list +}; + +//---------------------------------------------------------------------- +/// @class BlockList Block.h "lldb/Symbol/Block.h" +/// @brief A class that contains a heirachical collection of lexical +/// block objects where one block is the root. +/// +/// A collection of Block objects is managed by this class. All access +/// to the block data is made through the block_uid of each block. This +/// facilitates partial parsing and can enable block specific data to +/// only be parsed when the data is asked for (variables, params, types, +/// etc). +//---------------------------------------------------------------------- + +class BlockList +{ +public: + friend class Block; + typedef std::vector<Block> collection;///< Our block collection type. + + //------------------------------------------------------------------ + /// Construct with \a function and section offset based address + /// range. + /// + /// @param[in] function + /// A const Function object that owns this block list. + /// + /// @param[in] range + /// A section offset based address range object. + //------------------------------------------------------------------ + BlockList (Function *function, const AddressRange& range); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~BlockList (); + + //------------------------------------------------------------------ + /// Add a child block to a parent block. + /// + /// Adds a new child to a parent block. The UID values for + /// blocks are created by the SymbolFile plug-ins and should have + /// values that facilitate correlating an existing Block object + /// with information in the debug information file. Typically + /// a table index, or a debug information offset is used. + /// + /// @param[in] parent_uid + /// The UID for a the existing parent block that will have + /// a new child, whose UID is \a child_uid, added to its + /// child list. + /// + /// @param[in] child_uid + /// The UID for the new child block. + /// + /// @return + /// Returns \a child_uid if the child was successfully added + /// to the parent \a parent_uid, or Block::InvalidID on + /// failure (if the parent doesn't exist). + //------------------------------------------------------------------ + lldb::user_id_t + AddChild (lldb::user_id_t parent_uid, lldb::user_id_t child_uid); + + //------------------------------------------------------------------ + /// Add a child block to a parent block. + /// + /// Adds a new child to a parent block. The UID values for + /// blocks are created by the SymbolFile plug-ins and should have + /// values that facilitate correlating an existing Block object + /// with information in the debug information file. Typically + /// a table index, or a debug information offset is used. + /// + /// @param[in] block_uid + /// The UID for a the existing block that will get the + /// new range. + /// + /// @param[in] start_offset + /// An offset into this object's address range that + /// describes the start address of a range for \a block_uid. + /// + /// @param[in] end_offset + /// An offset into this object's address range that + /// describes the end address of a range for for \a block_uid. + /// + /// @return + /// Returns \b true if the range was successfully added to + /// the block whose UID is \a block_uid, \b false otherwise. + //------------------------------------------------------------------ + bool + AddRange (lldb::user_id_t block_uid, lldb::addr_t start_offset, lldb::addr_t end_offset); + +// const Block * +// FindDeepestBlockForAddress (const Address &addr); + + //------------------------------------------------------------------ + /// Get accessor for the section offset based address range. + /// + /// All Block objects contained in a BlockList are relative to + /// the base address in this object. + /// + /// @return + /// Returns a reference to the section offset based address + /// range object. + //------------------------------------------------------------------ + AddressRange & + GetAddressRange (); + + //------------------------------------------------------------------ + /// Get const accessor for the section offset based address range. + /// + /// All Block objects contained in a BlockList are relative to + /// the base address in this object. + /// + /// @return + /// Returns a const reference to the section offset based + /// address range object. + //------------------------------------------------------------------ + const AddressRange & + GetAddressRange () const; + + //------------------------------------------------------------------ + /// Dump the block list contents. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] block_uid + /// The UID of the block in the block list to dump. If this + /// value is Block::RootID, then the entire block list will + /// dumped as long as \a depth is set to a large enough value. + /// + /// @param[in] depth + /// Limit the number of levels deep that this function should + /// print as the block whose UID is \a block_uid can contain + /// child blocks. Specify INT_MAX to dump all child blocks. + /// + /// @param[in] show_context + /// If \b true, variables will dump their context information. + //------------------------------------------------------------------ + void + Dump (Stream *s, lldb::user_id_t block_uid, uint32_t depth, bool show_context) const; + + //------------------------------------------------------------------ + /// Get a block object pointer by block UID. + /// + /// @param[in] block_uid + /// The UID of the block to retrieve. + /// + /// @return + /// A pointer to the block object, or NULL if \a block_uid + /// doesn't exist in the block list. + //------------------------------------------------------------------ + Block * + GetBlockByID (lldb::user_id_t block_uid); + + //------------------------------------------------------------------ + /// Get a const block object pointer by block UID. + /// + /// @param[in] block_uid + /// The UID of the block to retrieve. + /// + /// @return + /// A const pointer to the block object, or NULL if \a block_uid + /// doesn't exist in the block list. + //------------------------------------------------------------------ + const Block * + GetBlockByID (lldb::user_id_t block_uid) const; + + //------------------------------------------------------------------ + /// Get a function object pointer for the block list. + /// + /// @return + /// A pointer to the function object. + //------------------------------------------------------------------ + Function * + GetFunction (); + + //------------------------------------------------------------------ + /// Get a const function object pointer for the block list. + /// + /// @return + /// A const pointer to the function object. + //------------------------------------------------------------------ + const Function * + GetFunction () const; + + //------------------------------------------------------------------ + /// Get the first child block UID for the block whose UID is \a + /// block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to access information for. + /// + /// @return + /// The UID of the first child block, or Block::InvalidID + /// if this block has no children, or if \a block_uid is not + /// a valid block ID for this block list. + //------------------------------------------------------------------ + lldb::user_id_t + GetFirstChild (lldb::user_id_t block_uid) const; + + //------------------------------------------------------------------ + /// Get the parent block UID for the block whose UID is \a + /// block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to access information for. + /// + /// @return + /// The UID of the parent block, or Block::InvalidID + /// if this block has no parent, or if \a block_uid is not + /// a valid block ID for this block list. + //------------------------------------------------------------------ + lldb::user_id_t + GetParent (lldb::user_id_t block_uid) const; + + //------------------------------------------------------------------ + /// Get the sibling block UID for the block whose UID is \a + /// block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to access information for. + /// + /// @return + /// The UID of the sibling block, or Block::InvalidID + /// if this block has no sibling, or if \a block_uid is not + /// a valid block ID for this block list. + //------------------------------------------------------------------ + lldb::user_id_t + GetSibling (lldb::user_id_t block_uid) const; + + //------------------------------------------------------------------ + /// Get the variable list for the block whose UID is \a block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to access information for. + /// + /// @param[in] can_create + /// If \b true, the variable list can be parsed on demand. If + /// \b false, the variable list contained in this object will + /// be returned. + /// + /// @return + /// The variable list shared pointer which may contain a NULL + /// variable list object. + //------------------------------------------------------------------ + lldb::VariableListSP + GetVariableList (lldb::user_id_t block_uid, bool get_child_variables, bool can_create); + + //------------------------------------------------------------------ + /// Check if the block list is empty. + /// + /// @return + /// Returns \b true if the block list is empty, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + IsEmpty () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// Returns the cost of this object plus any owned objects (address + /// range, and contains Block objects). + /// + /// @return + /// The number of bytes that this object occupies in memory. + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Set the variable list for the block whose UID is \a block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to set information for. + /// + /// @param[in] variable_list_sp + /// A shared pointer to list of variables. + /// + /// @return + /// Returns \b true if the variable list was successfully added + /// to the block, \b false otherwise. + //------------------------------------------------------------------ + bool + SetVariableList (lldb::user_id_t block_uid, lldb::VariableListSP& variable_list_sp); + + //------------------------------------------------------------------ + /// Set the inlined function info for the block whose UID is \a + /// block_uid. + /// + /// @param[in] block_uid + /// The UID of the block we wish to set information for. + /// + /// @param[in] name + /// The method name for the inlined function. This value should + /// not be NULL. + /// + /// @param[in] mangled + /// The mangled method name for the inlined function. This can + /// be NULL if there is no mangled name for an inlined function + /// or if the name is the same as \a name. + /// + /// @param[in] decl_ptr + /// A optional pointer to declaration information for the + /// inlined function information. This value can be NULL to + /// indicate that no declaration information is available. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + /// + /// @return + /// Returns \b true if the inline function info was successfully + /// associated with the block, \b false otherwise. + //------------------------------------------------------------------ + bool + SetInlinedFunctionInfo (lldb::user_id_t block_uid, const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + Function *m_function; ///< A pointer to the function that owns this block list. + AddressRange m_range; ///< The section offset based address range. + collection m_blocks; ///< A contiguous array of block objects. + + bool + BlockContainsBlockWithID (const lldb::user_id_t block_id, const lldb::user_id_t find_block_id) const; + +private: + + DISALLOW_COPY_AND_ASSIGN (BlockList); +}; + +} // namespace lldb_private + +#endif // liblldb_Block_h_ diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h new file mode 100644 index 00000000000..56e583c1280 --- /dev/null +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -0,0 +1,417 @@ +//===-- ClangASTContext.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangASTContext_h_ +#define liblldb_ClangASTContext_h_ + +// C Includes +// C++ Includes +#include <string> +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-enumerations.h" +#include "lldb/Core/ClangForward.h" + + +namespace lldb_private { + +class Declaration; + +class ClangASTContext +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ +// ClangASTContext(Module *module); + + ClangASTContext(const char *target_triple); + +// ClangASTContext(const ConstString &target_triple); + + ~ClangASTContext(); + + clang::ASTContext * + getASTContext(); + + clang::Builtin::Context * + getBuiltinContext(); + + clang::IdentifierTable * + getIdentifierTable(); + + clang::LangOptions * + getLanguageOptions(); + + clang::SelectorTable * + getSelectorTable(); + + clang::SourceManager * + getSourceManager(); + + clang::Diagnostic * + getDiagnostic(); + + clang::TargetOptions * + getTargetOptions(); + + clang::TargetInfo * + getTargetInfo(); + + void + Clear(); + + const char * + GetTargetTriple (); + + void + SetTargetTriple (const char *target_triple); + + //------------------------------------------------------------------ + // Basic Types + //------------------------------------------------------------------ + + void * + GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, + uint32_t bit_size); + + static void * + GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast_context, + lldb::Encoding encoding, + uint32_t bit_size); + + void * + GetBuiltinTypeForDWARFEncodingAndBitSize ( + const char *type_name, + uint32_t dw_ate, + uint32_t bit_size); + + void * + GetVoidBuiltInType(); + + void * + GetCStringType(bool is_const); + + void * + GetVoidPtrType(bool is_const); + + static void * + GetVoidPtrType(clang::ASTContext *ast_context, bool is_const); + + static void * + CopyType(clang::ASTContext *dest_context, + clang::ASTContext *source_context, + void * clang_type); + + //------------------------------------------------------------------ + // CVR modifiers + //------------------------------------------------------------------ + + static void * + AddConstModifier (void * clang_type); + + static void * + AddRestrictModifier (void * clang_type); + + static void * + AddVolatileModifier (void * clang_type); + + //------------------------------------------------------------------ + // Structure, Unions, Classes + //------------------------------------------------------------------ + + void * + CreateRecordType ( + const char *name, + int kind, + clang::DeclContext *decl_ctx); + + bool + AddFieldToRecordType ( + void * record_qual_type, + const char *name, + void * field_type, + int access, + uint32_t bitfield_bit_size); + + bool + FieldIsBitfield ( + clang::FieldDecl* field, + uint32_t& bitfield_bit_size); + + static bool + FieldIsBitfield ( + clang::ASTContext *ast_context, + clang::FieldDecl* field, + uint32_t& bitfield_bit_size); + + static bool + RecordHasFields (const clang::RecordDecl *record_decl); + + void + SetDefaultAccessForRecordFields ( + void * clang_qual_type, + int default_accessibility, + int *assigned_accessibilities, + size_t num_assigned_accessibilities); + + //------------------------------------------------------------------ + // Aggregate Types + //------------------------------------------------------------------ + static bool + IsAggregateType (void * clang_type); + + static uint32_t + GetNumChildren ( + void * clang_type, + bool omit_empty_base_classes); + + void * + GetChildClangTypeAtIndex ( + const char *parent_name, + void * parent_clang_type, + uint32_t idx, + bool transparent_pointers, + bool omit_empty_base_classes, + std::string& child_name, + uint32_t &child_byte_size, + int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset); + + static void * + GetChildClangTypeAtIndex ( + clang::ASTContext *ast_context, + const char *parent_name, + void * parent_clang_type, + uint32_t idx, + bool transparent_pointers, + bool omit_empty_base_classes, + std::string& child_name, + uint32_t &child_byte_size, + int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset); + + // Lookup a child given a name. This function will match base class names + // and member member names in "clang_type" only, not descendants. + static uint32_t + GetIndexOfChildWithName (clang::ASTContext *ast_context, + void *clang_type, + const char *name, + bool omit_empty_base_classes); + + // Lookup a child member given a name. This function will match member names + // only and will descend into "clang_type" children in search for the first + // member in this class, or any base class that matches "name". + // TODO: Return all matches for a given name by returning a vector<vector<uint32_t>> + // so we catch all names that match a given child name, not just the first. + static size_t + GetIndexOfChildMemberWithName (clang::ASTContext *ast_context, + void *clang_type, + const char *name, + bool omit_empty_base_classes, + std::vector<uint32_t>& child_indexes); + + //------------------------------------------------------------------ + // clang::TagType + //------------------------------------------------------------------ + + bool + SetTagTypeKind ( + void * tag_qual_type, + int kind); + + //------------------------------------------------------------------ + // C++ Base Classes + //------------------------------------------------------------------ + + clang::CXXBaseSpecifier * + CreateBaseClassSpecifier ( + void * base_class_type, + int access, + bool is_virtual, + bool base_of_class); + + bool + SetBaseClassesForClassType ( + void * class_clang_type, + clang::CXXBaseSpecifier const * const *base_classes, + unsigned num_base_classes); + + //------------------------------------------------------------------ + // DeclContext Functions + //------------------------------------------------------------------ + + static clang::DeclContext * + GetDeclContextForType (void * qual_type); + + //------------------------------------------------------------------ + // Namespace Declarations + //------------------------------------------------------------------ + + clang::NamespaceDecl * + GetUniqueNamespaceDeclaration ( + const char *name, + const Declaration &decl, + clang::DeclContext *decl_ctx); + + //------------------------------------------------------------------ + // Function Types + //------------------------------------------------------------------ + + clang::FunctionDecl * + CreateFunctionDeclaration ( + const char *name, + void * function_Type, + int storage, + bool is_inline); + + void * + CreateFunctionType ( + void * result_type, + void **args, + unsigned num_args, + bool isVariadic, + unsigned TypeQuals); + + clang::ParmVarDecl * + CreateParmeterDeclaration ( + const char *name, + void * return_type, + int storage); + + void + SetFunctionParameters ( + clang::FunctionDecl *function_decl, + clang::ParmVarDecl **params, + unsigned num_params); + + //------------------------------------------------------------------ + // Array Types + //------------------------------------------------------------------ + + void * + CreateArrayType ( + void * element_type, + size_t element_count, + uint32_t bit_stride); + + //------------------------------------------------------------------ + // Tag Declarations + //------------------------------------------------------------------ + bool + StartTagDeclarationDefinition (void * qual_type); + + bool + CompleteTagDeclarationDefinition (void * qual_type); + + //------------------------------------------------------------------ + // Enumeration Types + //------------------------------------------------------------------ + void * + CreateEnumerationType (const Declaration &decl, const char *name); + + bool + AddEnumerationValueToEnumerationType ( + void * enum_qual_type, + void * enumerator_qual_type, + const Declaration &decl, + const char *name, + int64_t enum_value, + uint32_t enum_value_bit_size); + + //------------------------------------------------------------------ + // Pointers & References + //------------------------------------------------------------------ + void * + CreatePointerType (void * clang_type); + + void * + CreateLValueReferenceType (void * clang_type); + + void * + CreateRValueReferenceType (void * clang_type); + + size_t + GetPointerBitSize (); + + static size_t + GetTypeBitSize (clang::ASTContext *ast_context, void * clang_type); + + static size_t + GetTypeBitAlign (clang::ASTContext *ast_context, void * clang_type); + + static bool + IsIntegerType (void * clang_type, bool &is_signed); + + static bool + IsPointerType (void * clang_type, void **target_type = NULL); + + static bool + IsPointerOrReferenceType (void * clang_type, void **target_type = NULL); + + static bool + IsCStringType (void * clang_type, uint32_t &length); + + static bool + IsArrayType (void * clang_type, void **member_type = NULL, uint64_t *size = NULL); + + //------------------------------------------------------------------ + // Typedefs + //------------------------------------------------------------------ + void * + CreateTypedefType ( + const char *name, + void * clang_type, + clang::DeclContext *decl_ctx); + + //------------------------------------------------------------------ + // Type names + //------------------------------------------------------------------ + static std::string + GetTypeName(void *clang_type); + + static bool + IsFloatingPointType (void * clang_type, uint32_t &count, bool &is_complex); + + //static bool + //ConvertFloatValueToString (clang::ASTContext *ast_context, void * clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str); + + static size_t + ConvertStringToFloatValue (clang::ASTContext *ast_context, void * clang_type, const char *s, uint8_t *dst, size_t dst_size); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from ClangASTContext can see and modify these + //------------------------------------------------------------------ + std::string m_target_triple; + std::auto_ptr<clang::ASTContext> m_ast_context_ap; + std::auto_ptr<clang::LangOptions> m_language_options_ap; + std::auto_ptr<clang::SourceManager> m_source_manager_ap; + std::auto_ptr<clang::Diagnostic> m_diagnostic_ap; + std::auto_ptr<clang::TargetOptions> m_target_options_ap; + std::auto_ptr<clang::TargetInfo> m_target_info_ap; + std::auto_ptr<clang::IdentifierTable> m_identifier_table_ap; + std::auto_ptr<clang::SelectorTable> m_selector_table_ap; + std::auto_ptr<clang::Builtin::Context> m_builtins_ap; + +private: + //------------------------------------------------------------------ + // For ClangASTContext only + //------------------------------------------------------------------ + ClangASTContext(const ClangASTContext&); + const ClangASTContext& operator=(const ClangASTContext&); +}; + +} // namespace lldb_private + +#endif // liblldb_ClangASTContext_h_ diff --git a/lldb/include/lldb/Symbol/CompileUnit.h b/lldb/include/lldb/Symbol/CompileUnit.h new file mode 100644 index 00000000000..15c3714a731 --- /dev/null +++ b/lldb/include/lldb/Symbol/CompileUnit.h @@ -0,0 +1,395 @@ +//===-- CompileUnit.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CompUnit_h_ +#define liblldb_CompUnit_h_ + +#include "lldb/Symbol/Function.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Core/Language.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/UserID.h" + +namespace lldb_private { +//---------------------------------------------------------------------- +/// @class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h" +/// @brief A class that describes a compilation unit. +/// +/// A representation of a compilation unit, or compiled source file. +/// The UserID of the compile unit is specified by the SymbolFile +/// plug-in and can have any value as long as the value is unique +/// within the Module that owns this compile units. +/// +/// Each compile unit has a list of functions, global and static +/// variables, support file list (include files and inlined source +/// files), and a line table. +//---------------------------------------------------------------------- +class CompileUnit : + public ModuleChild, + public FileSpec, + public UserID, + public Language, + public SymbolContextScope +{ +public: + //------------------------------------------------------------------ + /// Construct with a module, path, UID and language. + /// + /// Initialize the compile unit given the owning \a module, a path + /// to convert into a FileSpec, the SymbolFile plug-in supplied + /// \a uid, and the source language type. + /// + /// @param[in] module + /// The parent module that owns this compile unit. This value + /// must be a valid pointer value. + /// + /// @param[in] user_data + /// User data where the SymbolFile parser can store data. + /// + /// @param[in] pathname + /// The path to the source file for this compile unit. + /// + /// @param[in] uid + /// The user ID of the compile unit. This value is supplied by + /// the SymbolFile plug-in and should be a value that allows + /// the SymbolFile plug-in to easily locate and parse additional + /// information for the compile unit. + /// + /// @param[in] language + /// A language enumeration type that describes the main language + /// of this compile unit. + /// + /// @see Language::Type + //------------------------------------------------------------------ + CompileUnit(Module *module, void *user_data, const char *pathname, lldb::user_id_t uid, Language::Type language); + + //------------------------------------------------------------------ + /// Construct with a module, file spec, UID and language. + /// + /// Initialize the compile unit given the owning \a module, a path + /// to convert into a FileSpec, the SymbolFile plug-in supplied + /// \a uid, and the source language type. + /// + /// @param[in] module + /// The parent module that owns this compile unit. This value + /// must be a valid pointer value. + /// + /// @param[in] user_data + /// User data where the SymbolFile parser can store data. + /// + /// @param[in] file_spec + /// The file specification for the source file of this compile + /// unit. + /// + /// @param[in] uid + /// The user ID of the compile unit. This value is supplied by + /// the SymbolFile plug-in and should be a value that allows + /// the plug-in to easily locate and parse + /// additional information for the compile unit. + /// + /// @param[in] language + /// A language enumeration type that describes the main language + /// of this compile unit. + /// + /// @see Language::Type + //------------------------------------------------------------------ + CompileUnit(Module *module, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, Language::Type language); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~CompileUnit(); + + //------------------------------------------------------------------ + /// Add a function to this compile unit. + /// + /// Typically called by the SymbolFile plug-ins as they partially + /// parse the debug information. + /// + /// @param[in] function_sp + /// A shared pointer to the a Function object. + //------------------------------------------------------------------ + void + AddFunction(lldb::FunctionSP& function_sp); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext(SymbolContext* sc); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext(Stream *s); + + //------------------------------------------------------------------ + /// Get a shared pointer to a function in this compile unit by + /// index. + /// + /// Typically called when iterating though all functions in a + /// compile unit after all functions have been parsed. This provides + /// raw access to the function shared pointer list and will not + /// cause the SymbolFile plug-in to parse any unparsed functions. + /// + /// @param[in] idx + /// An index into the function list. + /// + /// @return + /// A shared pointer to a function that might contain a NULL + /// Function class pointer. + //------------------------------------------------------------------ + lldb::FunctionSP + GetFunctionAtIndex (size_t idx); + + //------------------------------------------------------------------ + /// Dump the compile unit contents to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] show_context + /// If \b true, variables will dump their symbol context + /// information. + //------------------------------------------------------------------ + void + Dump (Stream *s, bool show_context) const; + + //------------------------------------------------------------------ + /// Find the line entry by line and optional inlined file spec. + /// + /// Finds the first line entry that has an index greater than + /// \a start_idx that matches \a line. If \a file_spec_ptr + /// is NULL, then the search matches line entries whose file matches + /// the file for the compile unit. If \a file_spec_ptr is + /// not NULL, line entries must match the specified file spec (for + /// inlined line table entries). + /// + /// Multiple calls to this function can find all entries that match + /// a given file and line by starting with \a start_idx equal to zero, + /// and calling this function back with the return valeu + 1. + /// + /// @param[in] start_idx + /// The zero based index at which to start looking for matches. + /// + /// @param[in] line + /// The line number to search for. + /// + /// @param[in] file_spec_ptr + /// If non-NULL search for entries that match this file spec, + /// else if NULL, search for line entries that match the compile + /// unit file. + /// + /// @param[out] line_entry + /// If non-NULL, a copy of the line entry that was found. + /// + /// @return + /// The zero based index of a matching line entry, or UINT32_MAX + /// if no matching line entry is found. + //------------------------------------------------------------------ + uint32_t + FindLineEntry (uint32_t start_idx, + uint32_t line, + const FileSpec* file_spec_ptr, + LineEntry *line_entry); + + //------------------------------------------------------------------ + /// Get the line table for the compile unit. + /// + /// Called by clients and the SymbolFile plug-in. The SymbolFile + /// plug-ins use this function to determine if the line table has + /// be parsed yet. Clients use this function to get the line table + /// from a compile unit. + /// + /// @return + /// The line table object pointer, or NULL if this line table + /// hasn't been parsed yet. + //------------------------------------------------------------------ + LineTable* + GetLineTable (); + + //------------------------------------------------------------------ + /// Get the compile unit's support file list. + /// + /// The support file list is used by the line table, and any objects + /// that have valid Declaration objects. + /// + /// @return + /// A support file list object. + //------------------------------------------------------------------ + FileSpecList& + GetSupportFiles (); + + //------------------------------------------------------------------ + /// Get the SymbolFile plug-in user data. + /// + /// SymbolFile plug-ins can store user data to internal state or + /// objects to quickly allow them to parse more information for a + /// given object. + /// + /// @return + /// The user data stored with the CompileUnit when it was + /// constructed. + //------------------------------------------------------------------ + void * + GetUserData () const; + + //------------------------------------------------------------------ + /// Get the variable list for a compile unit. + /// + /// Called by clients to get the variable list for a compile unit. + /// The variable list will contain all global and static variables + /// that were defined at the compile unit level. + /// + /// @param[in] can_create + /// If \b true, the variable list will be parsed on demand. If + /// \b false, the current variable list will be returned even + /// if it contains a NULL VariableList object (typically + /// called by dumping routines that want to display only what + /// has currently been parsed). + /// + /// @return + /// A shared pointer to a variable list, that can contain NULL + /// VariableList pointer if there are no global or static + /// variables. + //------------------------------------------------------------------ + lldb::VariableListSP + GetVariableList (bool can_create); + + //------------------------------------------------------------------ + /// Finds a function by user ID. + /// + /// Typically used by SymbolFile plug-ins when partially parsing + /// the debug information to see if the function has been parsed + /// yet. + /// + /// @param[in] uid + /// The user ID of the function to find. This value is supplied + /// by the SymbolFile plug-in and should be a value that + /// allows the plug-in to easily locate and parse additional + /// information in the function. + /// + /// @return + /// A shared pointer to the function object that might contain + /// a NULL Function pointer. + //------------------------------------------------------------------ + lldb::FunctionSP + FindFunctionByUID (lldb::user_id_t uid); + + //------------------------------------------------------------------ + /// Set the line table for the compile unit. + /// + /// Called by the SymbolFile plug-in when if first parses the line + /// table and hands ownership of the line table to this object. The + /// compile unit owns the line table object and will delete the + /// object when it is deleted. + /// + /// @param[in] line_table + /// A line table object pointer that this object now owns. + //------------------------------------------------------------------ + void + SetLineTable(LineTable* line_table); + + //------------------------------------------------------------------ + /// Set accessor for the variable list. + /// + /// Called by the SymbolFile plug-ins after they have parsed the + /// variable lists and are ready to hand ownership of the list over + /// to this object. + /// + /// @param[in] variable_list_sp + /// A shared pointer to a VariableList. + //------------------------------------------------------------------ + void + SetVariableList (lldb::VariableListSP& variable_list_sp); + + //------------------------------------------------------------------ + /// Resolve symbol contexts by file and line. + /// + /// Given a file in \a file_spec, and a line number, find all + /// instances and append them to the supplied symbol context list + /// \a sc_list. + /// + /// @param[in] file_spec + /// A file specification. If \a file_spec contains no directory + /// information, only the basename will be used when matching + /// contexts. If the directory in \a file_spec is valid, a + /// complete file specification match will be performed. + /// + /// @param[in] line + /// The line number to match against the compile unit's line + /// tables. + /// + /// @param[in] check_inlines + /// If \b true this function will also match any inline + /// file and line matches. If \b false, the compile unit's + /// file specification must match \a file_spec for any matches + /// to be returned. + /// + /// @param[in] exact + /// If true, only resolve the context if \a line exists in the line table. + /// If false, resolve the context to the closest line greater than \a line + /// in the line table. + /// + /// @param[in] resolve_scope + /// For each matching line entry, this bitfield indicates what + /// values within each SymbolContext that gets added to \a + /// sc_list will be resolved. See the SymbolContext::Scope + /// enumeration for a list of all available bits that can be + /// resolved. Only SymbolContext entries that can be resolved + /// using a LineEntry base address will be able to be resolved. + /// + /// @param[out] sc_list + /// A SymbolContext list class that willl get any matching + /// entries appended to. + /// + /// @return + /// The number of new matches that were added to \a sc_list. + /// + /// @see enum SymbolContext::Scope + //------------------------------------------------------------------ + uint32_t + ResolveSymbolContext (const FileSpec& file_spec, + uint32_t line, + bool check_inlines, + bool exact, + uint32_t resolve_scope, + SymbolContextList &sc_list); + + +protected: + void *m_user_data; ///< User data for the SymbolFile parser to store information into. + Flags m_flags; ///< Compile unit flags that help with partial parsing. + std::vector<lldb::FunctionSP> m_functions; ///< The sparsely populated list of shared pointers to functions + ///< that gets populated as functions get partially parsed. + FileSpecList m_support_files; ///< Files associated with this compile unit's line table and declarations. + std::auto_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand. + lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand. + +private: + enum + { + flagsParsedAllFunctions = (1 << 0), ///< Have we already parsed all our functions + flagsParsedVariables = (1 << 1), ///< Have we already parsed globals and statics? + flagsParsedSupportFiles = (1 << 2), ///< Have we already parsed the support files for this compile unit? + flagsParsedLineTable = (1 << 3), ///< Have we parsed the line table already? + }; + + DISALLOW_COPY_AND_ASSIGN (CompileUnit); +}; + +} // namespace lldb_private + +#endif // liblldb_CompUnit_h_ diff --git a/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h b/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h new file mode 100644 index 00000000000..08dc42e2d1d --- /dev/null +++ b/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -0,0 +1,312 @@ +//===-- DWARFCallFrameInfo.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DWARFCallFrameInfo_h_ +#define liblldb_DWARFCallFrameInfo_h_ + +// C Includes +// C++ Includes +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/VMRange.h" +#include "lldb/Core/dwarf.h" + +namespace lldb_private { +//---------------------------------------------------------------------- +// DWARFCallFrameInfo +// +// State that describes all register locations for a given address +// range. +//---------------------------------------------------------------------- + +class DWARFCallFrameInfo +{ +public: + enum + { + CFI_AUG_MAX_SIZE = 8, + CFI_HEADER_SIZE = 8 + }; + + class Row; + + class RegisterLocation + { + public: + + typedef enum Type + { + unspecified, // not specified, we may be able to assume this is the same register. + // gcc doesn't specify all initial values so we really don't know... + isUndefined, // reg is not available + isSame, // reg is unchanged + atCFAPlusOffset,// reg = deref(CFA + offset) + isCFAPlusOffset,// reg = CFA + offset + inOtherRegister,// reg = other reg + atDWARFExpression, // reg = deref(eval(dwarf_expr)) + isDWARFExpression // reg = eval(dwarf_expr) + }; + + RegisterLocation(); + + bool + operator == (const RegisterLocation& rhs) const; + + void + Dump(Stream *s, const DWARFCallFrameInfo &cfi, Thread *thread, const Row *row, uint32_t reg_num) const; + + void + SetUnspecified(); + + void + SetUndefined(); + + void + SetSame() ; + + void + SetAtCFAPlusOffset (int64_t offset); + + void + SetIsCFAPlusOffset (int64_t offset); + + void + SetInRegister (uint32_t reg_num); + + void + SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len); + + void + SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len); + + protected: + Type m_type; // How do we locate this register? + union + { + // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset + int32_t offset; + // For m_type == inOtherRegister + uint32_t reg_num; // The register number + // For m_type == atDWARFExpression or m_type == isDWARFExpression + struct { + const uint8_t *opcodes; + uint32_t length; + } expr; + } m_location; + }; + + class Row + { + public: + + Row (); + + ~Row (); + + void + Clear(); + + void + Dump(Stream* s, const DWARFCallFrameInfo &cfi, Thread *thread, lldb::addr_t base_addr) const; + + bool + GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const; + + void + SetRegisterInfo (uint32_t reg_num, const RegisterLocation& register_location); + + lldb::addr_t + GetOffset() const + { + return m_offset; + } + + void + SetOffset(lldb::addr_t offset) + { + m_offset = offset; + } + + void + SlideOffset (lldb::addr_t slide) + { + m_offset += slide; + } + + uint32_t + GetCFARegister () const + { + return m_cfa_reg_num; + } + + void + SetCFARegister (uint32_t reg_num) + { + m_cfa_reg_num = reg_num; + } + + int32_t + GetCFAOffset () const + { + return m_cfa_offset; + } + + void + SetCFAOffset (int32_t offset) + { + m_cfa_offset = offset; + } + + protected: + typedef std::map<uint32_t, RegisterLocation> collection; + lldb::addr_t m_offset; // The an offset into the DBAddressRange that owns this row. + uint32_t m_cfa_reg_num; // The Call Frame Address register number + int32_t m_cfa_offset; // The offset from the CFA for this row + collection m_register_locations; + }; + + //------------------------------------------------------------------ + // Common Information Entry (CIE) + //------------------------------------------------------------------ +protected: + + struct CIE + { + typedef lldb::SharedPtr<CIE>::Type shared_ptr; + dw_offset_t cie_offset; + uint8_t version; + char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short. If we ever run into the limit, make this a NSData pointer + uint32_t code_align; + int32_t data_align; + uint32_t return_addr_reg_num; + dw_offset_t inst_offset; // offset of CIE instructions in mCFIData + uint32_t inst_length; // length of CIE instructions in mCFIData + uint8_t ptr_encoding; + + CIE(dw_offset_t offset); + ~CIE(); + + void + Dump(Stream *s, Thread* threadState, const ArchSpec *arch, uint32_t reg_kind) const; + }; + + //------------------------------------------------------------------ + // Frame Description Entry (FDE) + //------------------------------------------------------------------ +public: + + class FDE + { + public: + typedef lldb::SharedPtr<FDE>::Type shared_ptr; + + FDE (uint32_t offset, const AddressRange &range); + ~FDE(); + + const AddressRange & + GetAddressRange() const; + + void + AppendRow (const Row &row); + + bool + IsValidRowIndex (uint32_t idx) const; + + void + Dump (Stream *s, const DWARFCallFrameInfo &cfi, Thread* thread) const; + + const Row& + GetRowAtIndex (uint32_t idx); + + protected: + typedef std::vector<Row> collection; + uint32_t m_fde_offset; + AddressRange m_range; + collection m_row_list; + private: + DISALLOW_COPY_AND_ASSIGN (FDE); + }; + + DWARFCallFrameInfo(ObjectFile *objfile, lldb_private::Section *section, uint32_t reg_kind); + + ~DWARFCallFrameInfo(); + + bool + IsEHFrame() const; + + const ArchSpec * + GetArchitecture() const; + + uint32_t + GetRegisterKind () const; + + void + SetRegisterKind (uint32_t reg_kind); + + void + Index (); + +// bool UnwindRegister (const uint32_t reg_num, const Thread* currState, const Row* row, Thread* unwindState); +// uint32_t UnwindThreadState(const Thread* curr_state, bool is_first_frame, Thread* unwound_state); + const FDE * + FindFDE(const Address &addr); + + void + Dump(Stream *s, Thread *thread) const; + + void + ParseAll(); +protected: + + enum + { + eFlagParsedIndex = (1 << 0) + }; + + typedef std::map<off_t, CIE::shared_ptr> cie_map_t; + struct FDEInfo + { + off_t fde_offset; + FDE::shared_ptr fde_sp; + FDEInfo (off_t offset); + FDEInfo (); + + }; + typedef std::map<VMRange, FDEInfo> fde_map_t; + + ObjectFile * m_objfile; + lldb_private::Section * m_section; + uint32_t m_reg_kind; + Flags m_flags; + DataExtractor m_cfi_data; + cie_map_t m_cie_map; + fde_map_t m_fde_map; + + const CIE* + GetCIE (uint32_t offset); + + void + ParseInstructions(const CIE *cie, FDE *fde, uint32_t instr_offset, uint32_t instr_length); + + CIE::shared_ptr + ParseCIE (const uint32_t cie_offset); + + FDE::shared_ptr + ParseFDE (const uint32_t fde_offset); +}; + +} // namespace lldb_private + +#endif // liblldb_DWARFCallFrameInfo_h_ diff --git a/lldb/include/lldb/Symbol/Declaration.h b/lldb/include/lldb/Symbol/Declaration.h new file mode 100644 index 00000000000..ba0c68d43e6 --- /dev/null +++ b/lldb/include/lldb/Symbol/Declaration.h @@ -0,0 +1,204 @@ +//===-- Declaration.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Declaration_h_ +#define liblldb_Declaration_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/FileSpec.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Declaration Declaration.h "lldb/Symbol/Declaration.h" +/// @brief A class that describes the declaration location of a +/// lldb object. +/// +/// The declarations include the file specification, line number, and +/// the column info and can help track where functions, blocks, inlined +/// functions, types, variables, any many other debug core objects were +/// declared. +//---------------------------------------------------------------------- +class Declaration +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + //------------------------------------------------------------------ + Declaration (); + + //------------------------------------------------------------------ + /// Construct with file specification, and optional line and column. + /// + /// @param[in] file_spec + /// The file specification that describes where this was + /// declared. + /// + /// @param[in] line + /// The line number that describes where this was declared. Set + /// to zero if there is no line number information. + /// + /// @param[in] column + /// The column number that describes where this was declared. + /// Set to zero if there is no column number information. + //------------------------------------------------------------------ + Declaration (const FileSpec& file_spec, uint32_t line = 0, uint32_t column = 0); + + //------------------------------------------------------------------ + /// Construct with a reference to another Declaration object. + //------------------------------------------------------------------ + Declaration (const Declaration& rhs); + + //------------------------------------------------------------------ + /// Construct with a pointer to another Declaration object. + //------------------------------------------------------------------ + Declaration (const Declaration* rhs_ptr); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the file specification to be empty, and the line and column + /// to zero. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Compare two declaration objects. + /// + /// Compares the two file specifications from \a lhs and \a rhs. If + /// the file specifications are equal, then continue to compare the + /// line number and column numbers respectively. + /// + /// @param[in] lhs + /// The Left Hand Side const Declaration object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const Declaration object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int + Compare (const Declaration& lhs, const Declaration& rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + void + DumpStopContext (Stream *s) const; + //------------------------------------------------------------------ + /// Get accessor for the declaration column number. + /// + /// @return + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + //------------------------------------------------------------------ + uint32_t + GetColumn () const; + + //------------------------------------------------------------------ + /// Get accessor for file specification. + /// + /// @return + /// A reference to the file specification object. + //------------------------------------------------------------------ + FileSpec& + GetFile (); + + //------------------------------------------------------------------ + /// Get const accessor for file specification. + /// + /// @return + /// A const reference to the file specification object. + //------------------------------------------------------------------ + const FileSpec& + GetFile () const; + + //------------------------------------------------------------------ + /// Get accessor for the declaration line number. + /// + /// @return + /// Non-zero indicates a valid line number, zero indicates no + /// line information is available. + //------------------------------------------------------------------ + uint32_t + GetLine () const; + + + bool + IsValid() const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t + MemorySize () const; + + //------------------------------------------------------------------ + /// Set accessor for the declaration column number. + /// + /// @param[in] column + /// Non-zero indicates a valid column number, zero indicates no + /// column information is available. + //------------------------------------------------------------------ + void + SetColumn (uint32_t column); + + //------------------------------------------------------------------ + /// Set accessor for the declaration file specification. + /// + /// @param[in] file_spec + /// The new declaration file specifciation. + //------------------------------------------------------------------ + void + SetFile (const FileSpec& file_spec); + + //------------------------------------------------------------------ + /// Set accessor for the declaration line number. + /// + /// @param[in] line + /// Non-zero indicates a valid line number, zero indicates no + /// line information is available. + //------------------------------------------------------------------ + void + SetLine (uint32_t line); +protected: + //------------------------------------------------------------------ + /// Member variables. + //------------------------------------------------------------------ + FileSpec m_file; ///< The file specification that points to the + ///< source file where the declaration occurred. + uint32_t m_line; ///< Non-zero values indicates a valid line number, + ///< zero indicates no line number information is available. + uint32_t m_column; ///< Non-zero values indicates a valid column number, + ///< zero indicates no column information is available. +}; + +} // namespace lldb_private + +#endif // liblldb_Declaration_h_ diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h new file mode 100644 index 00000000000..74029da1e06 --- /dev/null +++ b/lldb/include/lldb/Symbol/Function.h @@ -0,0 +1,587 @@ +//===-- Function.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Function_h_ +#define liblldb_Function_h_ + +#include "lldb/Core/AddressRange.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Declaration.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Core/Mangled.h" +#include "lldb/Core/UserID.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class FunctionInfo Function.h "lldb/Symbol/Function.h" +/// @brief A class that contains generic function information. +/// +/// This provides generic function information that gets resused between +/// inline functions and function types. +//---------------------------------------------------------------------- +class FunctionInfo +{ +public: + //------------------------------------------------------------------ + /// Construct with the function method name and optional declaration + /// information. + /// + /// @param[in] name + /// A C string name for the method name for this function. This + /// value should not be the mangled named, but the simple method + /// name. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + //------------------------------------------------------------------ + FunctionInfo (const char *name, const Declaration *decl_ptr); + + //------------------------------------------------------------------ + /// Construct with the function method name and optional declaration + /// information. + /// + /// @param[in] name + /// A name for the method name for this function. This value + /// should not be the mangled named, but the simple method name. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + //------------------------------------------------------------------ + FunctionInfo (const ConstString& name, const Declaration *decl_ptr); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since classes inherit from this class. + //------------------------------------------------------------------ + virtual + ~FunctionInfo (); + + //------------------------------------------------------------------ + /// Compare two function information objects. + /// + /// First compares the method names, and if equal, then compares + /// the declaration information. + /// + /// @param[in] lhs + /// The Left Hand Side const FunctionInfo object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const FunctionInfo object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int + Compare (const FunctionInfo& lhs, const FunctionInfo& rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Get accessor for the declaration information. + /// + /// @return + /// A reference to the declaration object. + //------------------------------------------------------------------ + Declaration& + GetDeclaration (); + + //------------------------------------------------------------------ + /// Get const accessor for the declaration information. + /// + /// @return + /// A const reference to the declaration object. + //------------------------------------------------------------------ + const Declaration& + GetDeclaration () const; + + //------------------------------------------------------------------ + /// Get accessor for the method name. + /// + /// @return + /// A const reference to the method name object. + //------------------------------------------------------------------ + const ConstString& + GetName () const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + virtual size_t + MemorySize () const; + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + ConstString m_name; ///< Function method name (not a mangled name). + Declaration m_declaration; ///< Information describing where this function information was defined. +}; + + +//---------------------------------------------------------------------- +/// @class InlineFunctionInfo Function.h "lldb/Symbol/Function.h" +/// @brief A class that describes information for an inlined function. +//---------------------------------------------------------------------- +class InlineFunctionInfo : public FunctionInfo +{ +public: + //------------------------------------------------------------------ + /// Construct with the function method name, mangled name, and + /// optional declaration information. + /// + /// @param[in] name + /// A C string name for the method name for this function. This + /// value should not be the mangled named, but the simple method + /// name. + /// + /// @param[in] mangled + /// A C string name for the mangled name for this function. This + /// value can be NULL if there is no mangled information. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + InlineFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); + + //------------------------------------------------------------------ + /// Construct with the function method name, mangled name, and + /// optional declaration information. + /// + /// @param[in] name + /// A name for the method name for this function. This value + /// should not be the mangled named, but the simple method name. + /// + /// @param[in] mangled + /// A name for the mangled name for this function. This value + /// can be empty if there is no mangled information. + /// + /// @param[in] decl_ptr + /// Optional declaration information that describes where the + /// function was declared. This can be NULL. + /// + /// @param[in] call_decl_ptr + /// Optional calling location declaration information that + /// describes from where this inlined function was called. + //------------------------------------------------------------------ + InlineFunctionInfo(const ConstString& name, const Mangled &mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~InlineFunctionInfo(); + + //------------------------------------------------------------------ + /// Compare two inlined function information objects. + /// + /// First compares the FunctionInfo objects, and if equal, + /// compares the mangled names. + /// + /// @param[in] lhs + /// The Left Hand Side const InlineFunctionInfo object + /// reference. + /// + /// @param[in] rhs + /// The Right Hand Side const InlineFunctionInfo object + /// reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + int + Compare(const InlineFunctionInfo& lhs, const InlineFunctionInfo& rhs); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump(Stream *s) const; + + void + DumpStopContext (Stream *s) const; + + //------------------------------------------------------------------ + /// Get accessor for the call site declaration information. + /// + /// @return + /// A reference to the declaration object. + //------------------------------------------------------------------ + Declaration& + GetCallSite (); + + //------------------------------------------------------------------ + /// Get const accessor for the call site declaration information. + /// + /// @return + /// A const reference to the declaration object. + //------------------------------------------------------------------ + const Declaration& + GetCallSite () const; + + //------------------------------------------------------------------ + /// Get accessor for the mangled name object. + /// + /// @return + /// A reference to the mangled name object. + //------------------------------------------------------------------ + Mangled& + GetMangled(); + + //------------------------------------------------------------------ + /// Get const accessor for the mangled name object. + /// + /// @return + /// A const reference to the mangled name object. + //------------------------------------------------------------------ + const Mangled& + GetMangled() const; + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + virtual size_t + MemorySize() const; + +private: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + Mangled m_mangled; ///< Mangled inlined function name (can be empty if there is no mangled information). + Declaration m_call_decl; +}; + +//---------------------------------------------------------------------- +/// @class Function Function.h "lldb/Symbol/Function.h" +/// @brief A class that describes a function. +/// +/// Functions belong to CompileUnit objects (Function::m_comp_unit), +/// have unique user IDs (Function::UserID), know how to reconstruct +/// their symbol context (Function::SymbolContextScope), have a +/// specific function type (Function::m_type_uid), have a simple +/// method name (FunctionInfo::m_name), be declared at a specific +/// location (FunctionInfo::m_declaration), possibly have mangled +/// names (Function::m_mangled), an optional return type +/// (Function::m_type), and contains lexical blocks +/// (Function::m_blocks). +/// +/// The function inforation is split into a few pieces: +/// @li The concrete instance information +/// @li The abstract information +/// +/// The abstract information is found in the function type (Type) that +/// describes a function information, return type and parameter types. +/// +/// The concreate information is the address range information and +/// specific locations for an instance of this function. +//---------------------------------------------------------------------- +class Function : + public UserID, + public SymbolContextScope +{ +public: + //------------------------------------------------------------------ + /// Construct with a compile unit, function UID, function type UID, + /// optional mangled name, function type, and a section offset + /// based address range. + /// + /// @param[in] comp_unit + /// The compile unit to which this function belongs. + /// + /// @param[in] func_uid + /// The UID for this function. This value is provided by the + /// SymbolFile plug-in and can be any value that allows + /// the plug-in to quickly find and parse more detailed + /// information when and if more information is needed. + /// + /// @param[in] func_type_uid + /// The type UID for the function Type to allow for lazy type + /// parsing from the debug information. + /// + /// @param[in] mangled + /// The optional mangled name for this function. If empty, there + /// is no mangled information. + /// + /// @param[in] func_type + /// The optional function type. If NULL, the function type will + /// be parsed on demand when accessed using the + /// Function::GetType() function by asking the SymbolFile + /// plug-in to get the type for \a func_type_uid. + /// + /// @param[in] range + /// The section offset based address for this function. + //------------------------------------------------------------------ + Function ( + CompileUnit *comp_unit, + lldb::user_id_t func_uid, + lldb::user_id_t func_type_uid, + const Mangled &mangled, + Type * func_type, + const AddressRange& range); + + //------------------------------------------------------------------ + /// Construct with a compile unit, function UID, function type UID, + /// optional mangled name, function type, and a section offset + /// based address range. + /// + /// @param[in] comp_unit + /// The compile unit to which this function belongs. + /// + /// @param[in] func_uid + /// The UID for this function. This value is provided by the + /// SymbolFile plug-in and can be any value that allows + /// the plug-in to quickly find and parse more detailed + /// information when and if more information is needed. + /// + /// @param[in] func_type_uid + /// The type UID for the function Type to allow for lazy type + /// parsing from the debug information. + /// + /// @param[in] mangled + /// The optional mangled name for this function. If empty, there + /// is no mangled information. + /// + /// @param[in] func_type + /// The optional function type. If NULL, the function type will + /// be parsed on demand when accessed using the + /// Function::GetType() function by asking the SymbolFile + /// plug-in to get the type for \a func_type_uid. + /// + /// @param[in] range + /// The section offset based address for this function. + //------------------------------------------------------------------ + Function ( + CompileUnit *comp_unit, + lldb::user_id_t func_uid, + lldb::user_id_t func_type_uid, + const char *mangled, + Type * func_type, + const AddressRange& range); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~Function (); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext(SymbolContext* sc); + + const AddressRange & + GetAddressRange(); + + //------------------------------------------------------------------ + /// Get accessor for the block list. + /// + /// @return + /// The block list object that describes all lexical blocks + /// in the function. + /// + /// @see BlockList + //------------------------------------------------------------------ + BlockList& + GetBlocks (bool can_create); + + //------------------------------------------------------------------ + /// Get accessor for the compile unit that owns this function. + /// + /// @return + /// A compile unit object pointer. + //------------------------------------------------------------------ + CompileUnit* + GetCompileUnit(); + + //------------------------------------------------------------------ + /// Get const accessor for the compile unit that owns this function. + /// + /// @return + /// A const compile unit object pointer. + //------------------------------------------------------------------ + const CompileUnit* + GetCompileUnit() const; + + //------------------------------------------------------------------ + /// Get accessor for the frame base location. + /// + /// @return + /// A location expression that describes the function frame + /// base. + //------------------------------------------------------------------ + DWARFExpression & + GetFrameBaseExpression() + { + return m_frame_base; + } + + //------------------------------------------------------------------ + /// Get const accessor for the frame base location. + /// + /// @return + /// A const compile unit object pointer. + //------------------------------------------------------------------ + const DWARFExpression & + GetFrameBaseExpression() const + { + return m_frame_base; + } + + const Mangled & + GetMangled() const + { + return m_mangled; + } + + //------------------------------------------------------------------ + /// Get accessor for the type that describes the function + /// return value type, and paramter types. + /// + /// @return + /// A type object pointer. + //------------------------------------------------------------------ + Type* + GetType(); + + //------------------------------------------------------------------ + /// Get const accessor for the type that describes the function + /// return value type, and paramter types. + /// + /// @return + /// A const type object pointer. + //------------------------------------------------------------------ + const Type* + GetType() const; + + Type + GetReturnType (); + + // The Number of arguments, or -1 for an unprototyped function. + int + GetArgumentCount (); + + const Type + GetArgumentTypeAtIndex (size_t idx); + + const char * + GetArgumentNameAtIndex (size_t idx); + + bool + IsVariadic (); + + uint32_t + GetPrologueByteSize (); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] show_context + /// If \b true, variables will dump their symbol context + /// information. + //------------------------------------------------------------------ + void + Dump(Stream *s, bool show_context) const; + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext(Stream *s); + + //------------------------------------------------------------------ + /// Get the memory cost of this object. + /// + /// @return + /// The number of bytes that this object occupies in memory. + /// The returned value does not include the bytes for any + /// shared string values. + /// + /// @see ConstString::StaticMemorySize () + //------------------------------------------------------------------ + size_t + MemorySize () const; + +protected: + + enum + { + flagsCalculatedPrologueSize = (1 << 0), ///< Have we already tried to calculate the prologue size? + }; + + + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + CompileUnit *m_comp_unit; ///< The compile unit that owns this function. + lldb::user_id_t m_type_uid; ///< The user ID of for the prototype Type for this function. + Type * m_type; ///< The function prototype type for this function that include the function info (FunctionInfo), return type and parameters. + Mangled m_mangled; ///< The mangled function name if any, if empty, there is no mangled information. + BlockList m_blocks; ///< All lexical blocks contained in this function. + DWARFExpression m_frame_base; ///< The frame base expression for variables that are relative to the frame pointer. + Flags m_flags; + uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it +private: + DISALLOW_COPY_AND_ASSIGN(Function); +}; + +} // namespace lldb_private + +#endif // liblldb_Function_h_ diff --git a/lldb/include/lldb/Symbol/LineEntry.h b/lldb/include/lldb/Symbol/LineEntry.h new file mode 100644 index 00000000000..e0e6d2941d1 --- /dev/null +++ b/lldb/include/lldb/Symbol/LineEntry.h @@ -0,0 +1,170 @@ +//===-- LineEntry.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_LineEntry_h_ +#define liblldb_LineEntry_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/FileSpec.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class LineEntry LineEntry.h "lldb/Symbol/LineEntry.h" +/// @brief A line table entry class. +//---------------------------------------------------------------------- +struct LineEntry +{ + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all member variables to invalid values. + //------------------------------------------------------------------ + LineEntry (); + + LineEntry + ( + Section *section, + lldb::addr_t section_offset, + lldb::addr_t byte_size, + const FileSpec &file, + uint32_t _line, + uint16_t _column, + bool _is_start_of_statement, + bool _is_start_of_basic_block, + bool _is_prologue_end, + bool _is_epilogue_begin, + bool _is_terminal_entry + ); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Clears all member variables to invalid values. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] comp_unit + /// The compile unit object that contains the support file + /// list so the line entry can dump the file name (since this + /// object contains a file index into the support file list). + /// + /// @param[in] show_file + /// If \b true, display the filename with the line entry which + /// requires that the compile unit object \a comp_unit be a + /// valid pointer. + /// + /// @param[in] style + /// The display style for the section offset address. + /// + /// @return + /// Returns \b true if the address was able to be displayed + /// using \a style. File and load addresses may be unresolved + /// and it may not be possible to display a valid address value. + /// Returns \b false if the address was not able to be properly + /// dumped. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + bool + Dump (Stream *s, Process *process, bool show_file, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_range) const; + + bool + GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Process *process) const; + + //------------------------------------------------------------------ + /// Dumps information specific to a process that stops at this + /// line entry to the supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] comp_unit + /// The compile unit object that contains the support file + /// list so the line entry can dump the file name (since this + /// object contains a file index into the support file list). + /// + /// @return + /// Returns \b true if the file and line were properly dumped, + /// \b false otherwise. + //------------------------------------------------------------------ + bool + DumpStopContext (Stream *s) const; + + //------------------------------------------------------------------ + /// Check if a line entry object is valid. + /// + /// @return + /// Returns \b true if the line entry contains a valid section + /// offset address, file index, and line number, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + IsValid () const; + + //------------------------------------------------------------------ + /// Compare two LineEntry objects. + /// + /// @param[in] lhs + /// The Left Hand Side const LineEntry object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const LineEntry object reference. + /// + /// @return + /// @li -1 if lhs < rhs + /// @li 0 if lhs == rhs + /// @li 1 if lhs > rhs + //------------------------------------------------------------------ + static int + Compare (const LineEntry& lhs, const LineEntry& rhs); + + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + AddressRange range; ///< The section offset address range for this line entry. + FileSpec file; + uint32_t line; ///< The source line number, or zero if there is no line number information. + uint16_t column; ///< The column number of the source line, or zero if there is no column information. + uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement. + is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block. + is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function. + is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function. + is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions. +}; + +//------------------------------------------------------------------ +/// Less than operator. +/// +/// @param[in] lhs +/// The Left Hand Side const LineEntry object reference. +/// +/// @param[in] rhs +/// The Right Hand Side const LineEntry object reference. +/// +/// @return +/// Returns \b true if lhs < rhs, false otherwise. +//------------------------------------------------------------------ +bool operator<(const LineEntry& lhs, const LineEntry& rhs); + +} // namespace lldb_private + +#endif // liblldb_LineEntry_h_ diff --git a/lldb/include/lldb/Symbol/LineTable.h b/lldb/include/lldb/Symbol/LineTable.h new file mode 100644 index 00000000000..2329eea3720 --- /dev/null +++ b/lldb/include/lldb/Symbol/LineTable.h @@ -0,0 +1,333 @@ +//===-- LineTable.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_LineTable_h_ +#define liblldb_LineTable_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Symbol/LineEntry.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/Section.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class LineTable LineTable.h "lldb/Symbol/LineTable.h" +/// @brief A line table class. +//---------------------------------------------------------------------- +class LineTable +{ +public: + //------------------------------------------------------------------ + /// Construct with compile unit. + /// + /// @param[in] comp_unit + /// The compile unit to which this line table belongs. + //------------------------------------------------------------------ + LineTable (CompileUnit* comp_unit); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~LineTable (); + + //------------------------------------------------------------------ + /// Adds a new line entry to this line table. + /// + /// All line entries are maintained in file address order. + /// + /// @param[in] line_entry + /// A const reference to a new line_entry to add to this line + /// table. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ +// void +// AddLineEntry (const LineEntry& line_entry); + + // Called when you can guarantee the addresses are in increasing order + void + AppendLineEntry (lldb::SectionSP& section_sp, + lldb::addr_t section_offset, + uint32_t line, + uint16_t column, + uint16_t file_idx, + bool is_start_of_statement, + bool is_start_of_basic_block, + bool is_prologue_end, + bool is_epilogue_begin, + bool is_terminal_entry); + + // Called when you can't guarantee the addresses are in increasing order + void + InsertLineEntry (lldb::SectionSP& section_sp, + lldb::addr_t section_offset, + uint32_t line, + uint16_t column, + uint16_t file_idx, + bool is_start_of_statement, + bool is_start_of_basic_block, + bool is_prologue_end, + bool is_epilogue_begin, + bool is_terminal_entry); + + //------------------------------------------------------------------ + /// Dump all line entries in this line table to the stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] style + /// The display style for the address. + /// + /// @see Address::DumpStyle + //------------------------------------------------------------------ + void + Dump (Stream *s, Process *process, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_line_ranges); + + void + GetDescription (Stream *s, Process *process, lldb::DescriptionLevel level); + + //------------------------------------------------------------------ + /// Find a line entry that contains the section offset address \a + /// so_addr. + /// + /// @param[in] so_addr + /// A section offset address object containing the address we + /// are searching for. + /// + /// @param[out] line_entry + /// A copy of the line entry that was found if \b true is + /// returned, otherwise \a entry is left unmodified. + /// + /// @param[out] index_ptr + /// A pointer to a 32 bit integer that will get the actual line + /// entry index if it is not NULL. + /// + /// @return + /// Returns \b true if \a so_addr is contained in a line entry + /// in this line table, \b false otherwise. + //------------------------------------------------------------------ + bool + FindLineEntryByAddress (const Address &so_addr, LineEntry& line_entry, uint32_t *index_ptr = NULL); + + //------------------------------------------------------------------ + /// Find a line entry index that has a matching file index and + /// source line number. + /// + /// Finds the next line entry that has a matching \a file_idx and + /// source line number \a line starting at the \a start_idx entries + /// into the line entry collection. + /// + /// @param[in] start_idx + /// The number of entries to skip when starting the search. + /// + /// @param[out] file_idx + /// The file index to search for that should be found prior + /// to calling this function using the following functions: + /// CompileUnit::GetSupportFiles() + /// FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const + /// + /// @param[in] line + /// The source line to match. + /// + /// @param[in] exact + /// If true, match only if you find a line entry exactly matching \a line. + /// If false, return the closest line entry greater than \a line. + /// + /// @param[out] line_entry + /// A reference to a line entry object that will get a copy of + /// the line entry if \b true is returned, otherwise \a + /// line_entry is left untouched. + /// + /// @return + /// Returns \b true if a matching line entry is found in this + /// line table, \b false otherwise. + /// + /// @see CompileUnit::GetSupportFiles() + /// @see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const + //------------------------------------------------------------------ + uint32_t + FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, uint32_t line, bool exact, LineEntry* line_entry_ptr); + + //------------------------------------------------------------------ + /// Get the line entry from the line table at index \a idx. + /// + /// @param[in] idx + /// An index into the line table entry collection. + /// + /// @return + /// A valid line entry if \a idx is a valid index, or an invalid + /// line entry if \a idx is not valid. + /// + /// @see LineTable::GetSize() + /// @see LineEntry::IsValid() const + //------------------------------------------------------------------ + bool + GetLineEntryAtIndex(uint32_t idx, LineEntry& line_entry); + + //------------------------------------------------------------------ + /// Gets the size of the line table in number of line table entries. + /// + /// @return + /// The number of line table entries in this line table. + //------------------------------------------------------------------ + uint32_t + GetSize () const; + +protected: + + struct Entry + { + enum { kInvalidSectIdx = 255 }; + + Entry () : + sect_idx (kInvalidSectIdx), + sect_offset (0), + line (0), + column (0), + file_idx (0), + is_start_of_statement (false), + is_start_of_basic_block (false), + is_prologue_end (false), + is_epilogue_begin (false), + is_terminal_entry (false) + { + } + + Entry ( uint8_t _sect_idx, + lldb::addr_t _sect_offset, + uint32_t _line, + uint16_t _column, + uint16_t _file_idx, + bool _is_start_of_statement, + bool _is_start_of_basic_block, + bool _is_prologue_end, + bool _is_epilogue_begin, + bool _is_terminal_entry) : + sect_idx (_sect_idx), + sect_offset (_sect_offset), + line (_line), + column (_column), + file_idx (_file_idx), + is_start_of_statement (_is_start_of_statement), + is_start_of_basic_block (_is_start_of_basic_block), + is_prologue_end (_is_prologue_end), + is_epilogue_begin (_is_epilogue_begin), + is_terminal_entry (_is_terminal_entry) + { + // We have reserved 24 bits for the section offset which should + // be enough, but if it isn't then we need to make m_section_offset + // bigger + assert((_sect_offset & 0xffffffffff000000ull) == 0); + } + + int + bsearch_compare (const void *key, const void *arrmem); + + void + Clear () + { + sect_idx = kInvalidSectIdx; + sect_offset = 0; + line = 0; + column = 0; + file_idx = 0; + is_start_of_statement = false; + is_start_of_basic_block = false; + is_prologue_end = false; + is_epilogue_begin = false; + is_terminal_entry = false; + } + + static int + Compare (const Entry& lhs, const Entry& rhs) + { + // Compare the sections before calling + #define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1 + SCALAR_COMPARE (lhs.sect_offset, rhs.sect_offset); + SCALAR_COMPARE (lhs.line, rhs.line); + SCALAR_COMPARE (lhs.column, rhs.column); + SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement); + SCALAR_COMPARE (lhs.is_start_of_basic_block, rhs.is_start_of_basic_block); + // rhs and lhs reversed on purpose below. + SCALAR_COMPARE (rhs.is_prologue_end, lhs.is_prologue_end); + SCALAR_COMPARE (lhs.is_epilogue_begin, rhs.is_epilogue_begin); + // rhs and lhs reversed on purpose below. + SCALAR_COMPARE (rhs.is_terminal_entry, lhs.is_terminal_entry); + SCALAR_COMPARE (lhs.file_idx, rhs.file_idx); + #undef SCALAR_COMPARE; + return 0; + } + + + class LessThanBinaryPredicate + { + public: + LessThanBinaryPredicate(LineTable *line_table); + bool operator() (const LineTable::Entry& a, const LineTable::Entry& a) const; + protected: + LineTable *m_line_table; + }; + + static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs) + { + if (lhs.sect_idx == rhs.sect_idx) + return lhs.sect_offset < rhs.sect_offset; + return lhs.sect_idx < rhs.sect_idx; + } + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + uint32_t sect_idx:8, ///< The section index for this line entry. + sect_offset:24; ///< The offset into the section for this line entry. + uint32_t line; ///< The source line number, or zero if there is no line number information. + uint16_t column; ///< The column number of the source line, or zero if there is no column information. + uint16_t file_idx:11, ///< The file index into CompileUnit's file table, or zero if there is no file information. + is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement. + is_start_of_basic_block:1, ///< Indicates this entry is the beginning of a basic block. + is_prologue_end:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an entry breakpoint of a function. + is_epilogue_begin:1, ///< Indicates this entry is one (of possibly many) where execution should be suspended for an exit breakpoint of a function. + is_terminal_entry:1; ///< Indicates this entry is that of the first byte after the end of a sequence of target machine instructions. + }; + + struct EntrySearchInfo + { + LineTable* line_table; + lldb_private::Section *a_section; + Entry *a_entry; + }; + + //------------------------------------------------------------------ + // Types + //------------------------------------------------------------------ + typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the line entries. + typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries. + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to. + SectionList m_section_list; ///< The list of sections that at least one of the line entries exists in. + entry_collection m_entries; ///< The collection of line entries in this line table. + + bool + ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry); + + lldb_private::Section * + GetSectionForEntryIndex (uint32_t idx); +private: + DISALLOW_COPY_AND_ASSIGN (LineTable); +}; + +} // namespace lldb_private + +#endif // liblldb_LineTable_h_ diff --git a/lldb/include/lldb/Symbol/ObjectContainer.h b/lldb/include/lldb/Symbol/ObjectContainer.h new file mode 100644 index 00000000000..f5c6d0780f8 --- /dev/null +++ b/lldb/include/lldb/Symbol/ObjectContainer.h @@ -0,0 +1,232 @@ +//===-- ObjectContainer.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ObjectContainer_h_ +#define liblldb_ObjectContainer_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h" +/// @brief A plug-in interface definition class for object containers. +/// +/// Object containers contain object files from one or more +/// architectures, and also can contain one or more named objects. +/// +/// Typical object containers are static libraries (.a files) that +/// contain multiple named object files, and universal files that contain +/// multiple architectures. +//---------------------------------------------------------------------- +class ObjectContainer : + public PluginInterface, + public ModuleChild +{ +public: + //------------------------------------------------------------------ + /// Construct with a parent module, offset, and header data. + /// + /// Object files belong to modules and a valid module must be + /// supplied upon construction. The at an offset within a file for + /// objects that contain more than one architecture or object. + //------------------------------------------------------------------ + ObjectContainer (Module* module, + const FileSpec *file, + lldb::addr_t offset, + lldb::addr_t length, + lldb::DataBufferSP& headerDataSP) : + ModuleChild (module), + m_file (), // This file can be different than the module's file spec + m_offset (offset), + m_length (length), + m_data (headerDataSP, lldb::eByteOrderHost, 4) + { + if (file) + m_file = *file; + } + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + virtual + ~ObjectContainer() + { + } + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the current contents of this object + /// to the supplied stream \a s. The dumping should include the + /// section list if it has been parsed, and the symbol table + /// if it has been parsed. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + virtual void + Dump (Stream *s) const = 0; + + //------------------------------------------------------------------ + /// Gets the architecture given an index. + /// + /// Copies the architecture specification for index \a idx. + /// + /// @param[in] idx + /// The architecture index to extract. + /// + /// @param[out] arch + /// A architecture object that will be filled in if \a idx is a + /// architecture valid index. + /// + /// @return + /// Returns \b true if \a idx is valid and \a arch has been + /// filled in, \b false otherwise. + /// + /// @see ObjectContainer::GetNumArchitectures() const + //------------------------------------------------------------------ + virtual bool + GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const + { + return false; + } + + //------------------------------------------------------------------ + /// Returns the offset into a file at which this object resides. + /// + /// Some files contain many object files, and this function allows + /// access to an object's offset within the file. + /// + /// @return + /// The offset in bytes into the file. Defaults to zero for + /// simple object files that a represented by an entire file. + //------------------------------------------------------------------ + virtual lldb::addr_t + GetOffset () const + { return m_offset; } + + virtual lldb::addr_t + GetByteSize () const + { return m_length; } + + //------------------------------------------------------------------ + /// Get the number of objects within this object file (archives). + /// + /// @return + /// Zero for object files that are not archives, or the number + /// of objects contained in the archive. + //------------------------------------------------------------------ + virtual size_t + GetNumObjects () const + { return 0; } + + //------------------------------------------------------------------ + /// Get the number of architectures in this object file. + /// + /// The default implementation returns 1 as for object files that + /// contain a single architecture. ObjectContainer instances that + /// contain more than one architecture should override this function + /// and return an appropriate value. + /// + /// @return + /// The number of architectures contained in this object file. + //------------------------------------------------------------------ + virtual size_t + GetNumArchitectures () const + { return 0; } + + //------------------------------------------------------------------ + /// Attempts to parse the object header. + /// + /// This function is used as a test to see if a given plug-in + /// instance can parse the header data already contained in + /// ObjectContainer::m_data. If an object file parser does not + /// recognize that magic bytes in a header, false should be returned + /// and the next plug-in can attempt to parse an object file. + /// + /// @return + /// Returns \b true if the header was parsed succesfully, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool + ParseHeader () = 0; + + //------------------------------------------------------------------ + /// Selects an architecture in an object file. + /// + /// Object files that contain a single architecture should verify + /// that the specified \a arch matches the architecture in in + /// object file and return \b true or \b false accordingly. + /// + /// Object files that contain more than one architecture should + /// attempt to select that architecture, and if successful, clear + /// out any previous state from any previously selected architecture + /// and prepare to return information for the new architecture. + /// + /// @return + /// Returns a pointer to the object file of the requested \a + /// arch and optional \a name. Returns NULL of no such object + /// file exists in the container. + //------------------------------------------------------------------ + virtual ObjectFile * + GetObjectFile (const FileSpec *file) = 0; + + virtual bool + ObjectAtIndexIsContainer (uint32_t object_idx) + { + return false; + } + + virtual ObjectFile * + GetObjectFileAtIndex (uint32_t object_idx) + { + return NULL; + } + + virtual ObjectContainer * + GetObjectContainerAtIndex (uint32_t object_idx) + { + return NULL; + } + + virtual const char * + GetObjectNameAtIndex (uint32_t object_idx) const + { + return NULL; + } + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file). + lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory + lldb::addr_t m_length; ///< The size in bytes if known (can be zero). + DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. + +private: + DISALLOW_COPY_AND_ASSIGN (ObjectContainer); +}; + +} // namespace lldb_private + +#endif // liblldb_ObjectContainer_h_ diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h new file mode 100644 index 00000000000..f9e5c2da111 --- /dev/null +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -0,0 +1,309 @@ +//===-- ObjectFile.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ObjectFile_h_ +#define liblldb_ObjectFile_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/Symtab.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ObjectFile ObjectFile.h "lldb/Symbol/ObjectFile.h" +/// @brief A plug-in interface definition class for object file parsers. +/// +/// Object files belong to Module objects and know how to extract +/// information from executable, shared library, and object (.o) files +/// used by operating system runtime. The symbol table and section list +/// for an object file. +/// +/// Object files can be represented by the entire file, or by part of a +/// file. Examples of object files that are part of a file include +/// object files that contain information for multiple architectures in +/// the same file, or archive files that contain multiple objects +/// (ranlib archives) (possibly for multiple architectures as well). +/// +/// It is possible to determine how many architectures an object file +/// contains by using the ObjectFile::GetNumArchitectures() const +/// accessor function. The individual architectures can be extracted +/// using the +/// ObjectFile::GetArchitectureAtIndex (uint32_t, ArchSpec&) const +/// function. The object file can also be asked to select one of these +/// architectures using the +/// ObjectFile::SetArchitecture (const ArchSpec&) function. +/// +/// Object archive files (e.g. ranlib archives) can contain +/// multiple .o (object) files that must be selected by index or by name. +/// The number of objects that an ObjectFile contains can be determined +/// using the ObjectFile::GetNumObjects() const +/// function, and followed by a call to +/// ObjectFile::SelectObjectAtIndex (uint32_t) to change the currently +/// selected object. Objects can also be selected by name using the +/// ObjectFile::SelectObject(const char *) function. +/// +/// Once an architecture is selected (and an object is selected for +/// for archives), the object file information can be extracted from +/// this abstract class. +//---------------------------------------------------------------------- +class ObjectFile: + public PluginInterface, + public ModuleChild +{ +public: + //------------------------------------------------------------------ + /// Construct with a parent module, offset, and header data. + /// + /// Object files belong to modules and a valid module must be + /// supplied upon construction. The at an offset within a file for + /// objects that contain more than one architecture or object. + //------------------------------------------------------------------ + ObjectFile (Module* module, const FileSpec *file_spec_ptr, lldb::addr_t offset, lldb::addr_t length, lldb::DataBufferSP& headerDataSP) : + ModuleChild (module), + m_file (), // This file could be different from the original module's file + m_offset (offset), + m_length (length), + m_data (headerDataSP, lldb::eByteOrderHost, 4) + { + if (file_spec_ptr) + m_file = *file_spec_ptr; + } + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + virtual + ~ObjectFile() + { + } + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the current contents of this object + /// to the supplied stream \a s. The dumping should include the + /// section list if it has been parsed, and the symbol table + /// if it has been parsed. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + virtual void + Dump (Stream *s) = 0; + + //------------------------------------------------------------------ + /// Find a ObjectFile plug-in that can parse \a file_spec. + /// + /// Scans all loaded plug-in interfaces that implement versions of + /// the ObjectFile plug-in interface and returns the first + /// instance that can parse the file. + /// + /// @param[in] module + /// The parent module that owns this object file. + /// + /// @param[in] file_spec + /// A file specification that indicates which file to use as the + /// object file. + /// + /// @param[in] file_offset + /// The offset into the file at which to start parsing the + /// object. This is for files that contain multiple + /// architectures or objects. + /// + /// @param[in] file_size + /// The size of the current object file if it can be determined + /// or if it is known. This can be zero. + /// + /// @see ObjectFile::ParseHeader() + //------------------------------------------------------------------ + static ObjectFile* + FindPlugin (Module* module, + const FileSpec* file_spec, + lldb::addr_t file_offset, + lldb::addr_t file_size); + + //------------------------------------------------------------------ + /// Gets the address size in bytes for the current object file. + /// + /// @return + /// The size of an address in bytes for the currently selected + /// architecture (and object for archives). Returns zero if no + /// architecture or object has been selected. + //------------------------------------------------------------------ + virtual size_t + GetAddressByteSize () const = 0; + + //------------------------------------------------------------------ + /// Extract the dependent modules from an object file. + /// + /// If an object file has information about which other images it + /// depends on (such as shared libraries), this function will + /// provide the list. Since many executables or shared libraries + /// may depend on the same files, + /// FileSpecList::AppendIfUnique(const FileSpec &) should be + /// used to make sure any files that are added are not already in + /// the list. + /// + /// @param[out] file_list + /// A list of file specification objects that gets dependent + /// files appended to. + /// + /// @return + /// The number of new files that were appended to \a file_list. + /// + /// @see FileSpecList::AppendIfUnique(const FileSpec &) + //------------------------------------------------------------------ + virtual uint32_t + GetDependentModules (FileSpecList& file_list) = 0; + + //------------------------------------------------------------------ + /// Returns the offset into a file at which this object resides. + /// + /// Some files contain many object files, and this function allows + /// access to an object's offset within the file. + /// + /// @return + /// The offset in bytes into the file. Defaults to zero for + /// simple object files that a represented by an entire file. + //------------------------------------------------------------------ + virtual lldb::addr_t + GetOffset () const + { return m_offset; } + + virtual lldb::addr_t + GetByteSize () const + { return m_length; } + + //------------------------------------------------------------------ + /// Get accessor to the object file specification. + /// + /// @return + /// The file specification object pointer if there is one, or + /// NULL if this object is only from memory. + //------------------------------------------------------------------ + virtual FileSpec& + GetFileSpec() { return m_file; } + + //------------------------------------------------------------------ + /// Get const accessor to the object file specification. + /// + /// @return + /// The const file specification object pointer if there is one, + /// or NULL if this object is only from memory. + //------------------------------------------------------------------ + virtual const FileSpec& + GetFileSpec() const { return m_file; } + + //------------------------------------------------------------------ + /// Get the name of the cpu, vendor and OS for this object file. + /// + /// This value is a string that represents the target triple where + /// the cpu type, the vendor and the OS are encoded into a string. + /// + /// @param[out] target_triple + /// The string value of the target triple. + /// + /// @return + /// \b True if the target triple was able to be computed, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool + GetTargetTriple(ConstString &target_triple) = 0; + + //------------------------------------------------------------------ + /// Gets the section list for the currently selected architecture + /// (and object for archives). + /// + /// Section list parsing can be deferred by ObjectFile instances + /// until this accessor is called the first time. + /// + /// @return + /// The list of sections contained in this object file. + //------------------------------------------------------------------ + virtual SectionList * + GetSectionList () = 0; + + //------------------------------------------------------------------ + /// Gets the symbol table for the currently selected architecture + /// (and object for archives). + /// + /// Symbol table parsing can be deferred by ObjectFile instances + /// until this accessor is called the first time. + /// + /// @return + /// The symbol table for this object file. + //------------------------------------------------------------------ + virtual Symtab * + GetSymtab () = 0; + + //------------------------------------------------------------------ + /// Gets the UUID for this object file. + /// + /// If the object file format contains a UUID, the value should be + /// returned. Else ObjectFile instances should return the MD5 + /// checksum of all of the bytes for the object file (or memory for + /// memory based object files). + /// + /// @return + /// Returns \b true if a UUID was successfully extracted into + /// \a uuid, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + GetUUID (UUID* uuid) = 0; + + //------------------------------------------------------------------ + /// Gets wether endian swapping should occur when extracting data + /// from this object file. + /// + /// @return + /// Returns \b true if endian swapping is needed, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual lldb::ByteOrder + GetByteOrder () const = 0; + + //------------------------------------------------------------------ + /// Attempts to parse the object header. + /// + /// This function is used as a test to see if a given plug-in + /// instance can parse the header data already contained in + /// ObjectFile::m_data. If an object file parser does not + /// recognize that magic bytes in a header, false should be returned + /// and the next plug-in can attempt to parse an object file. + /// + /// @return + /// Returns \b true if the header was parsed succesfully, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual bool + ParseHeader () = 0; + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + FileSpec m_file; + lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory + lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined). + DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. + +private: + DISALLOW_COPY_AND_ASSIGN (ObjectFile); +}; + +} // namespace lldb_private + +#endif // liblldb_ObjectFile_h_ + diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h new file mode 100644 index 00000000000..ec5596fe0b0 --- /dev/null +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -0,0 +1,181 @@ +//===-- Symbol.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Symbol_h_ +#define liblldb_Symbol_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Mangled.h" +#include "lldb/Core/UserID.h" + +namespace lldb_private { + +class Symbol : + public UserID // Used to uniquely identify this symbol in its symbol table +{ +public: + // ObjectFile readers can classify their symbol table entries and searches can be made + // on specific types where the symbol values will have drastically different meanings + // and sorting requirements. + Symbol(); + + Symbol (lldb::user_id_t symID, + const char *name, + bool name_is_mangled, + lldb::SymbolType type, + bool external, + bool is_debug, + bool is_trampoline, + bool is_artificial, + const Section* section, + lldb::addr_t value, + uint32_t size, + uint32_t flags); + + Symbol (lldb::user_id_t symID, + const char *name, + bool name_is_mangled, + lldb::SymbolType type, + bool external, + bool is_debug, + bool is_trampoline, + bool is_artificial, + const AddressRange &range, + uint32_t flags); + + Symbol (const Symbol& rhs); + + const Symbol& + operator= (const Symbol& rhs); + + bool + Compare (const ConstString& name, lldb::SymbolType type) const; + + void + Dump (Stream *s, Process *process, uint32_t index) const; + + AddressRange * + GetAddressRangePtr (); + + const AddressRange * + GetAddressRangePtr () const; + + AddressRange & + GetAddressRangeRef(); + + const AddressRange & + GetAddressRangeRef() const; + + Mangled& + GetMangled (); + + const Mangled& + GetMangled () const; + + bool + GetSizeIsSibling () const; + + bool + GetSizeIsSynthesized() const; + + uint32_t + GetSiblingIndex () const; + + uint32_t + GetByteSize () const; + + lldb::SymbolType + GetType () const; + + void + SetType (lldb::SymbolType type); + + const char * + GetTypeAsString () const; + + uint32_t + GetFlags () const; + + void + SetFlags (uint32_t flags); + + Function * + GetFunction (); + + Address & + GetValue (); + + const Address & + GetValue () const; + + bool + IsSynthetic () const; + + void + SetIsSynthetic (bool b); + + void + SetSizeIsSynthesized(bool b); + + bool + IsDebug () const; + + void + SetDebug (bool b); + + bool + IsExternal () const; + + void + SetExternal (bool b); + + bool + IsTrampoline () const; + + void + SetByteSize (uint32_t size); + + void + SetSizeIsSibling (bool b); + + void + SetValue (Address &value); + + void + SetValue (const AddressRange &range); + + void + SetValue (lldb::addr_t value); + + // If m_type is "Code" or "Function" then this will return the prologue size + // in bytes, else it will return zero. + uint32_t + GetPrologueByteSize (); + +protected: + + Mangled m_mangled; // uniqued symbol name/mangled name pair + lldb::SymbolType m_type; // symbol type + uint16_t m_type_data; // data specific to m_type + uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated + m_is_synthetic:1, // non-zero if this symbol is not actually in the symbol table, but synthesized from other info in the object file. + m_is_debug:1, // non-zero if this symbol is debug information in a symbol + m_is_external:1, // non-zero if this symbol is globally visible + m_size_is_sibling:1, // m_size contains the index of this symbol's sibling + m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next + m_searched_for_function:1;// non-zero if we have looked for the function associated with this symbol already. + AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any) + uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these + Function * m_function; +}; + +} // namespace lldb_private + +#endif // liblldb_Symbol_h_ diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h new file mode 100644 index 00000000000..c0aff6ea4a7 --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -0,0 +1,328 @@ +//===-- SymbolContext.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_SymbolContext_h_ +#define liblldb_SymbolContext_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/Address.h" +#include "lldb/Symbol/LineEntry.h" + +namespace lldb_private { + +class SymbolContextScope; +//---------------------------------------------------------------------- +/// @class SymbolContext SymbolContext.h "lldb/Symbol/SymbolContext.h" +/// @brief Defines a symbol context baton that can be handed other debug +/// core functions. +/// +/// Many debugger functions require a context when doing lookups. This +/// class provides a common structure that can be used as the result +/// of a query that can contain a single result. Examples of such +/// queries include +/// @li Looking up a load address. +//---------------------------------------------------------------------- +class SymbolContext +{ +public: + + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize all pointer members to NULL and all struct members + /// to their default state. + //------------------------------------------------------------------ + SymbolContext (); + + //------------------------------------------------------------------ + /// Construct with an object that knows how to reconstruct its + /// symbol context. + /// + /// @param[in] sc_scope + /// A symbol context scope object that knows how to reconstruct + /// it's context. + //------------------------------------------------------------------ + explicit + SymbolContext (SymbolContextScope *sc_scope); + + //------------------------------------------------------------------ + /// Construct with module, and optional compile unit, function, + /// block, line table, line entry and symbol. + /// + /// Initialize all pointer to the specified values. + /// + /// @param[in] module + /// A Module pointer to the module for this context. + /// + /// @param[in] comp_unit + /// A CompileUnit pointer to the compile unit for this context. + /// + /// @param[in] function + /// A Function pointer to the function for this context. + /// + /// @param[in] block + /// A Block pointer to the deepest block for this context. + /// + /// @param[in] line_entry + /// A LineEntry pointer to the line entry for this context. + /// + /// @param[in] symbol + /// A Symbol pointer to the symbol for this context. + //------------------------------------------------------------------ + explicit + SymbolContext (const lldb::TargetSP &target_sp, + const lldb::ModuleSP &module_sp, + CompileUnit *comp_unit = NULL, + Function *function = NULL, + Block *block = NULL, + LineEntry *line_entry = NULL, + Symbol *symbol = NULL); + + // This version sets the target to a NULL TargetSP if you don't know it. + explicit + SymbolContext (const lldb::ModuleSP &module_sp, + CompileUnit *comp_unit = NULL, + Function *function = NULL, + Block *block = NULL, + LineEntry *line_entry = NULL, + Symbol *symbol = NULL); + + //------------------------------------------------------------------ + /// Copy constructor + /// + /// Makes a copy of the another SymbolContext object \a rhs. + /// + /// @param[in] rhs + /// A const SymbolContext object reference to copy. + //------------------------------------------------------------------ + SymbolContext (const SymbolContext& rhs); + + //------------------------------------------------------------------ + /// Assignment operator. + /// + /// Copies the address value from another SymbolContext object \a + /// rhs into \a this object. + /// + /// @param[in] rhs + /// A const SymbolContext object reference to copy. + /// + /// @return + /// A const SymbolContext object reference to \a this. + //------------------------------------------------------------------ + const SymbolContext& + operator= (const SymbolContext& rhs); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Resets all pointer members to NULL, and clears any class objects + /// to their default state. + //------------------------------------------------------------------ + void + Clear (); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s, Process *process) const; + + //------------------------------------------------------------------ + /// Dump the stop context in this object to a Stream. + /// + /// Dump the best description of this object to the stream. The + /// information displayed depends on the amount and quality of the + /// information in this context. If a module, function, file and + /// line number are available, they will be dumped. If only a + /// module and function or symbol name with offset is available, + /// that will be ouput. Else just the address at which the target + /// was stopped will be displayed. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + /// + /// @param[in] so_addr + /// The resolved section offset address. + //------------------------------------------------------------------ + void + DumpStopContext (Stream *s, + ExecutionContextScope *exe_scope, + const Address &so_addr, + bool show_module = true) const; + + //------------------------------------------------------------------ + /// Get the address range contained within a symbol context. + /// + /// Address range priority is as follows: + /// - line_entry address range if line_entry is valid + /// - function address range if function is not NULL + /// - symbol address range if symbol is not NULL + /// + /// @param[out] range + /// An address range object that will be filled in if \b true + /// is returned. + /// + /// @return + /// \b True if this symbol context contains items that describe + /// an address range, \b false otherwise. + //------------------------------------------------------------------ + bool + GetAddressRange (uint32_t scope, AddressRange &range) const; + + //------------------------------------------------------------------ + /// Find a function matching the given name, working out from this + /// symbol context. + /// + /// @return + /// A shared pointer to the function found. + //------------------------------------------------------------------ + Function * + FindFunctionByName (const char *name) const; + + //------------------------------------------------------------------ + /// Find a variable matching the given name, working out from this + /// symbol context. + /// + /// @return + /// A shared pointer to the variable found. + //------------------------------------------------------------------ + lldb::VariableSP + FindVariableByName (const char *name) const; + + //------------------------------------------------------------------ + /// Find a type matching the given name, working out from this + /// symbol context. + /// + /// @return + /// A shared pointer to the variable found. + //------------------------------------------------------------------ + lldb::TypeSP + FindTypeByName (const char *name) const; + + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + lldb::TargetSP target_sp; ///< The Target for a given query + lldb::ModuleSP module_sp; ///< The Module for a given query + CompileUnit * comp_unit; ///< The CompileUnit for a given query + Function * function; ///< The Function for a given query + Block * block; ///< The Block for a given query + LineEntry line_entry; ///< The LineEntry for a given query + Symbol * symbol; ///< The Symbol for a given query +}; + +//---------------------------------------------------------------------- +/// @class SymbolContextList SymbolContext.h "lldb/Symbol/SymbolContext.h" +/// @brief Defines a list of symbol context objects. +/// +/// This class provides a common structure that can be used to contain +/// the result of a query that can contain a multiple results. Examples +/// of such queries include: +/// @li Looking up a function by name. +/// @li Finding all addressses for a specified file and line number. +//---------------------------------------------------------------------- +class SymbolContextList +{ +public: + //------------------------------------------------------------------ + /// Default constructor. + /// + /// Initialize with an empty list. + //------------------------------------------------------------------ + SymbolContextList (); + + //------------------------------------------------------------------ + /// Destructor. + //------------------------------------------------------------------ + ~SymbolContextList (); + + //------------------------------------------------------------------ + /// Append a new symbol context to the list. + /// + /// @param[in] sc + /// A symbol context to append to the list. + //------------------------------------------------------------------ + void + Append(const SymbolContext& sc); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Clears the symbol context list. + //------------------------------------------------------------------ + void + Clear(); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of each symbol context in + /// the list to the supplied stream \a s. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump(Stream *s, Process *process) const; + + //------------------------------------------------------------------ + /// Get accessor for a symbol context at index \a idx. + /// + /// Dump a description of the contents of each symbol context in + /// the list to the supplied stream \a s. + /// + /// @param[in] idx + /// The zero based index into the symbol context list. + /// + /// @param[out] sc + /// A reference to the symbol context to fill in. + /// + /// @return + /// Returns \b true if \a idx was a valid index into this + /// symbol context list and \a sc was filled in, \b false + /// otherwise. + //------------------------------------------------------------------ + bool + GetContextAtIndex(uint32_t idx, SymbolContext& sc) const; + + bool + RemoveContextAtIndex (uint32_t idx); + //------------------------------------------------------------------ + /// Get accessor for a symbol context list size. + /// + /// @return + /// Returns the number of symbol context objects in the list. + //------------------------------------------------------------------ + uint32_t + GetSize() const; + +protected: + typedef std::vector<SymbolContext> collection; ///< The collection type for the list. + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + collection m_symbol_contexts; ///< The list of symbol contexts. +}; + +bool operator== (const SymbolContext& lhs, const SymbolContext& rhs); +bool operator!= (const SymbolContext& lhs, const SymbolContext& rhs); + +} // namespace lldb_private + +#endif // liblldb_SymbolContext_h_ diff --git a/lldb/include/lldb/Symbol/SymbolContextScope.h b/lldb/include/lldb/Symbol/SymbolContextScope.h new file mode 100644 index 00000000000..9b9b9d698ae --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolContextScope.h @@ -0,0 +1,79 @@ +//===-- SymbolContextScope.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SymbolContextScope_h_ +#define liblldb_SymbolContextScope_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h" +/// @brief Inherit from this if your object can reconstruct its symbol +/// context. +/// +/// Many objects that have pointers back to parent objects that own them +/// that all inherit from this pure virtual class can reconstruct their +/// symbol context without having to keep a complete SymbolContextScope +/// object in the object state. Examples of these objects include: +/// Module, CompileUnit, Function, and Block. +/// +/// Other objects can contain a valid pointer to an instance of this +/// class so they can reconstruct the symbol context in which they are +/// scoped. Example objects include: Variable and Type. Such objects +/// can be scoped at a variety of levels: +/// @li module level for a built built in types. +/// @li file level for compile unit types and variables. +/// @li function or block level for types and variables defined in +/// a function body. +/// +/// Objects that adhere to this protocol can reconstruct enough of a +/// symbol context to allow functions that take a symbol context to be +/// called. Lists can also be created using a SymbolContextScope* and +/// and object pairs that allow large collections of objects to be +/// passed around with minimal overhead. +//---------------------------------------------------------------------- +class SymbolContextScope +{ +public: + //------------------------------------------------------------------ + /// Reconstruct the object's symbolc context into \a sc. + /// + /// The object should fill in as much of the SymbolContext as it + /// can so function calls that require a symbol context can be made + /// for the given object. + /// + /// @param[out] sc + /// A symbol context object pointer that gets filled in. + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext (SymbolContext *sc) = 0; + + //------------------------------------------------------------------ + /// Dump the object's symbolc context to the stream \a s. + /// + /// The object should dump its symbol context to the stream \a s. + /// This function is widely used in the DumpDebug and verbose output + /// for lldb objets. + /// + /// @param[in] s + /// The stream to which to dump the object's symbol context. + //------------------------------------------------------------------ + virtual void + DumpSymbolContext (Stream *s) = 0; +}; + +} // namespace lldb_private + +#endif // liblldb_SymbolContextScope_h_ diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h new file mode 100644 index 00000000000..4af88c31b06 --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -0,0 +1,95 @@ +//===-- SymbolFile.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SymbolFile_h_ +#define liblldb_SymbolFile_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/Type.h" + +namespace lldb_private { + +class SymbolFile : + public PluginInterface +{ +public: + enum Abilities + { + Labels = (1 << 0), + AddressAcceleratorTable = (1 << 1), + FunctionAcceleratorTable = (1 << 2), + TypeAcceleratorTable = (1 << 3), + MacroInformation = (1 << 4), + CallFrameInformation = (1 << 5), + CompileUnits = (1 << 6), + LineTables = (1 << 7), + LineColumns = (1 << 8), + Functions = (1 << 9), + Blocks = (1 << 10), + GlobalVariables = (1 << 11), + LocalVariables = (1 << 12), + VariableTypes = (1 << 13) + }; + + static SymbolFile * + FindPlugin (ObjectFile* obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFile(ObjectFile* obj_file) : + m_obj_file(obj_file) + { + } + + virtual + ~SymbolFile() + { + } + + virtual uint32_t GetAbilities () = 0; + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + // Approach 1 - iterator + virtual uint32_t GetNumCompileUnits() = 0; + virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0; + + virtual size_t ParseCompileUnitFunctions (const SymbolContext& sc) = 0; + virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0; + virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0; + virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0; + virtual size_t ParseTypes (const SymbolContext& sc) = 0; + virtual size_t ParseVariablesForContext (const SymbolContext& sc) = 0; + virtual Type* ResolveTypeUID (lldb::user_id_t type_uid) = 0; + virtual clang::DeclContext* GetClangDeclContextForTypeUID (lldb::user_id_t type_uid) { return NULL; } + virtual uint32_t ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) = 0; + virtual uint32_t ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) = 0; + virtual uint32_t FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables) = 0; + virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables) = 0; + virtual uint32_t FindFunctions (const ConstString &name, bool append, SymbolContextList& sc_list) = 0; + virtual uint32_t FindFunctions (const RegularExpression& regex, bool append, SymbolContextList& sc_list) = 0; +// virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) = 0; +// virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types) = 0; + + ObjectFile* GetObjectFile() { return m_obj_file; } + const ObjectFile* GetObjectFile() const { return m_obj_file; } +protected: + ObjectFile* m_obj_file; // The object file that symbols can be extracted from. + +private: + DISALLOW_COPY_AND_ASSIGN (SymbolFile); +}; + + +} // namespace lldb_private + +#endif // liblldb_SymbolFile_h_ diff --git a/lldb/include/lldb/Symbol/SymbolVendor.h b/lldb/include/lldb/Symbol/SymbolVendor.h new file mode 100644 index 00000000000..a5bdb3b30b1 --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolVendor.h @@ -0,0 +1,193 @@ +//===-- SymbolVendor.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SymbolVendor_h_ +#define liblldb_SymbolVendor_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/ModuleChild.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Symbol/TypeList.h" + + +namespace lldb_private { + +//---------------------------------------------------------------------- +// The symbol vendor class is designed to abstract the process of +// searching for debug information for a given module. Platforms can +// subclass this class and provide extra ways to find debug information. +// Examples would be a subclass that would allow for locating a stand +// alone debug file, parsing debug maps, or runtime data in the object +// files. A symbol vendor can use multiple sources (SymbolFile +// objects) to provide the information and only parse as deep as needed +// in order to provide the information that is requested. +//---------------------------------------------------------------------- +class SymbolVendor : + public ModuleChild, + public PluginInterface +{ +public: + static bool + RegisterPlugin (const char *name, + const char *description, + SymbolVendorCreateInstance create_callback); + + static bool + UnregisterPlugin (SymbolVendorCreateInstance create_callback); + + + static SymbolVendor* + FindPlugin (Module* module); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolVendor(Module *module); + + virtual + ~SymbolVendor(); + + void + AddSymbolFileRepresendation(ObjectFile *obj_file); + + virtual void + Dump(Stream *s); + + virtual size_t + ParseCompileUnitFunctions (const SymbolContext& sc); + + virtual bool + ParseCompileUnitLineTable (const SymbolContext& sc); + + virtual bool + ParseCompileUnitSupportFiles (const SymbolContext& sc, + FileSpecList& support_files); + + virtual size_t + ParseFunctionBlocks (const SymbolContext& sc); + + virtual size_t + ParseTypes (const SymbolContext& sc); + + virtual size_t + ParseVariablesForContext (const SymbolContext& sc); + + virtual Type* + ResolveTypeUID(lldb::user_id_t type_uid); + + virtual uint32_t + ResolveSymbolContext (const Address& so_addr, + uint32_t resolve_scope, + SymbolContext& sc); + + virtual uint32_t + ResolveSymbolContext (const FileSpec& file_spec, + uint32_t line, + bool check_inlines, + uint32_t resolve_scope, + SymbolContextList& sc_list); + + virtual uint32_t + FindGlobalVariables(const ConstString &name, + bool append, + uint32_t max_matches, + VariableList& variables); + + virtual uint32_t + FindGlobalVariables(const RegularExpression& regex, + bool append, + uint32_t max_matches, + VariableList& variables); + + virtual uint32_t + FindFunctions(const ConstString &name, + bool append, + SymbolContextList& sc_list); + + virtual uint32_t + FindFunctions(const RegularExpression& regex, + bool append, + SymbolContextList& sc_list); + + virtual uint32_t + GetNumCompileUnits(); + + virtual bool + SetCompileUnitAtIndex (lldb::CompUnitSP& cu, + uint32_t index); + + virtual lldb::CompUnitSP + GetCompileUnitAtIndex(uint32_t idx); + + TypeList& + GetTypeList() + { + return m_type_list; + } + + const TypeList& + GetTypeList() const + { + return m_type_list; + } + + SymbolFile * + GetSymbolFile() + { + return m_sym_file_ap.get(); + } + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual const char * + GetPluginName(); + + virtual const char * + GetShortPluginName(); + + virtual uint32_t + GetPluginVersion(); + + virtual void + GetPluginCommandHelp (const char *command, Stream *strm); + + virtual Error + ExecutePluginCommand (Args &command, Stream *strm); + + virtual Log * + EnablePluginLogging (Stream *strm, Args &command); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from SymbolVendor can see and modify these + //------------------------------------------------------------------ + typedef std::vector<lldb::CompUnitSP> CompileUnits; + typedef CompileUnits::iterator CompileUnitIter; + typedef CompileUnits::const_iterator CompileUnitConstIter; + + mutable Mutex m_mutex; + TypeList m_type_list; // Uniqued types for all parsers owned by this module + CompileUnits m_compile_units; // The current compile units + std::auto_ptr<SymbolFile> m_sym_file_ap; // A single symbol file. Suclasses can add more of these if needed. + +private: + //------------------------------------------------------------------ + // For SymbolVendor only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (SymbolVendor); +}; + + +} // namespace lldb_private + +#endif // liblldb_SymbolVendor_h_ diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h new file mode 100644 index 00000000000..cb98db92713 --- /dev/null +++ b/lldb/include/lldb/Symbol/Symtab.h @@ -0,0 +1,77 @@ +//===-- Symtab.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_Symtab_h_ +#define liblldb_Symtab_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/UniqueCStringMap.h" +#include "lldb/Symbol/Symbol.h" + +namespace lldb_private { + +class Symtab +{ +public: + Symtab(ObjectFile *objfile); + ~Symtab(); + + void Reserve (uint32_t count); + Symbol * Resize (uint32_t count); + uint32_t AddSymbol(const Symbol& symbol); + size_t GetNumSymbols() const; + void Dump(Stream *s, Process *process) const; + void Dump(Stream *s, Process *process, std::vector<uint32_t>& indexes) const; + + Symbol * SymbolAtIndex (uint32_t idx); + const Symbol * SymbolAtIndex (uint32_t idx) const; + Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, uint32_t &start_idx); + const Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, uint32_t &start_idx) const; + uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT_MAX) const; + uint32_t AppendSymbolIndexesWithName (const ConstString& symbol_name, std::vector<uint32_t>& matches); + uint32_t AppendSymbolIndexesWithNameAndType (const ConstString& symbol_name, lldb::SymbolType symbol_type, std::vector<uint32_t>& matches); + uint32_t AppendSymbolIndexesMatchingRegExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes); + size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes); + size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, std::vector<uint32_t>& symbol_indexes); + Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type = lldb::eSymbolTypeAny); + Symbol * FindSymbolWithFileAddress (lldb::addr_t file_addr); +// Symbol * FindSymbolContainingAddress (const Address& value, const uint32_t* indexes, uint32_t num_indexes); +// Symbol * FindSymbolContainingAddress (const Address& value); + Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes); + Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr); + size_t CalculateSymbolSize (Symbol *symbol); + + void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const; + + static void DumpSymbolHeader (Stream *s); + +protected: + typedef std::vector<Symbol> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + static int CompareSymbolValueByIndex (void *thunk, const void *a, const void *b); + void InitNameIndexes (); + void InitAddressIndexes (); + + ObjectFile * m_objfile; + collection m_symbols; + std::vector<uint32_t> m_addr_indexes; + UniqueCStringMap<uint32_t> m_name_to_index; + +private: + DISALLOW_COPY_AND_ASSIGN (Symtab); +}; + +} // namespace lldb_private + +#endif // liblldb_Symtab_h_ diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h new file mode 100644 index 00000000000..9d7810af9c0 --- /dev/null +++ b/lldb/include/lldb/Symbol/Type.h @@ -0,0 +1,286 @@ +//===-- Type.h --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Type_h_ +#define liblldb_Type_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Core/ClangForward.h" +#include "lldb/Core/UserID.h" +#include "lldb/Symbol/Declaration.h" +#include <set> + +namespace lldb_private { + +class Type : public UserID +{ +public: + typedef enum + { + eTypeInvalid, + eIsTypeWithUID, ///< This type is the type whose UID is m_encoding_uid + eIsConstTypeWithUID, ///< This type is the type whose UID is m_encoding_uid with the const qualifier added + eIsRestrictTypeWithUID, ///< This type is the type whose UID is m_encoding_uid with the restrict qualifier added + eIsVolatileTypeWithUID, ///< This type is the type whose UID is m_encoding_uid with the volatile qualifier added + eTypedefToTypeWithUID, ///< This type is pointer to a type whose UID is m_encoding_uid + ePointerToTypeWithUID, ///< This type is pointer to a type whose UID is m_encoding_uid + eLValueReferenceToTypeWithUID, ///< This type is L value reference to a type whose UID is m_encoding_uid + eRValueReferenceToTypeWithUID, ///< This type is R value reference to a type whose UID is m_encoding_uid + eTypeUIDSynthetic + } EncodingUIDType; + + Type(lldb::user_id_t uid, + SymbolFile* symbol_file, + const ConstString &name, + uint64_t byte_size, + SymbolContextScope *context, + lldb::user_id_t encoding_uid, + EncodingUIDType encoding_type, + const Declaration& decl, + void *clang_qual_type); + + // This makes an invalid type. Used for functions that return a Type when they + // get an error. + Type(); + + const Type& + operator= (const Type& rhs); + + void + Dump(Stream *s, bool show_context); + + void + DumpTypeName(Stream *s); + + SymbolFile * + GetSymbolFile() + { + return m_symbol_file; + } + const SymbolFile * + GetSymbolFile() const + { + return m_symbol_file; + } + + TypeList* + GetTypeList(); + + const ConstString& + GetName(); + + uint64_t + GetByteSize(); + + uint32_t + GetNumChildren (bool omit_empty_base_classes); + + bool + IsAggregateType (); + + bool + IsValidType () + { + return m_encoding_uid_type != eTypeInvalid; + } + + void + SetByteSize(uint32_t byte_size); + + const ConstString & + GetName () const + { + return m_name; + } + + static ConstString + GetClangTypeName (void *clang_qual_type); + + static void + DumpValue(ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + void *clang_qual_type, + Stream *s, + lldb::Format format, + const DataExtractor &data, + uint32_t data_offset, + size_t data_byte_size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, + bool show_types, + bool show_summary, + bool verbose, + uint32_t depth); + + static void + DumpSummary (ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + void *clang_qual_type, + Stream *s, + const DataExtractor &data, + uint32_t data_offset, + size_t data_byte_size); + + + void + DumpValue(ExecutionContext *exe_ctx, + Stream *s, + const DataExtractor &data, + uint32_t data_offset, + bool show_type, + bool show_summary, + bool verbose, + lldb::Format format = lldb::eFormatDefault); + + bool + DumpValueInMemory(ExecutionContext *exe_ctx, + Stream *s, + lldb::addr_t address, + lldb::AddressType address_type, + bool show_types, + bool show_summary, + bool verbose); + + static bool + DumpTypeValue ( Stream *s, + clang::ASTContext *ast_context, + void *clang_qual_type, + lldb::Format format, + const DataExtractor &data, + uint32_t data_offset, + size_t data_byte_size, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset); + + static bool + GetValueAsScalar (clang::ASTContext *ast_context, + void *clang_qual_type, + const DataExtractor &data, + uint32_t data_offset, + size_t data_byte_size, + Scalar &value); + + static bool + SetValueFromScalar (clang::ASTContext *ast_context, + void *clang_qual_type, + const Scalar &value, + Stream &strm); + + bool + ReadFromMemory (ExecutionContext *exe_ctx, + lldb::addr_t address, + lldb::AddressType address_type, + DataExtractor &data); + + bool + WriteToMemory (ExecutionContext *exe_ctx, + lldb::addr_t address, + lldb::AddressType address_type, + DataExtractor &data); + + + static bool + ReadFromMemory (ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + void *clang_qual_type, + lldb::addr_t addr, + lldb::AddressType address_type, + DataExtractor &data); + + static bool + WriteToMemory (ExecutionContext *exe_ctx, + clang::ASTContext *ast_context, + void *clang_qual_type, + lldb::addr_t addr, + lldb::AddressType address_type, + StreamString &new_value); + + bool + GetIsDeclaration() const; + + void + SetIsDeclaration(bool b); + + bool + GetIsExternal() const; + + void + SetIsExternal(bool b); + + lldb::Format + GetFormat (); + + lldb::Encoding + GetEncoding (uint32_t &count); + + static lldb::Encoding + GetEncoding (void *clang_qual_type, uint32_t &count); + + SymbolContextScope * + GetSymbolContextScope() + { + return m_context; + } + const SymbolContextScope * + GetSymbolContextScope() const + { + return m_context; + } + void + SetSymbolContextScope(SymbolContextScope *context) + { + m_context = context; + } + + void * + GetOpaqueClangQualType (); + + clang::ASTContext * + GetClangAST (); + + ClangASTContext & + GetClangASTContext (); + + void * + GetChildClangTypeAtIndex (const char *parent_name, + uint32_t idx, + bool transparent_pointers, + bool omit_empty_base_classes, + ConstString& name, + uint32_t &child_byte_size, + int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, + uint32_t &child_bitfield_bit_offset); + + static int + Compare(const Type &a, const Type &b); + + static lldb::Format + GetFormat (void *clang_qual_type); + + static int + DumpClangTypeName(Stream *s, void *clang_qual_type); + +protected: + ConstString m_name; + uint64_t m_byte_size; + SymbolFile *m_symbol_file; + SymbolContextScope *m_context; // The symbol context in which this type is defined + lldb::user_id_t m_encoding_uid; + EncodingUIDType m_encoding_uid_type; + Declaration m_decl; + void *m_clang_qual_type; + + bool ResolveClangType(); +}; + +} // namespace lldb_private + +#endif // liblldb_Type_h_ + diff --git a/lldb/include/lldb/Symbol/TypeList.h b/lldb/include/lldb/Symbol/TypeList.h new file mode 100644 index 00000000000..9a488dbc8bf --- /dev/null +++ b/lldb/include/lldb/Symbol/TypeList.h @@ -0,0 +1,94 @@ +//===-- TypeList.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TypeList_h_ +#define liblldb_TypeList_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/Type.h" +#include <vector> + +namespace lldb_private { + +class TypeList +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + TypeList(const char *target_triple = NULL); + + virtual + ~TypeList(); + + void + Clear(); + + void + Dump(Stream *s, bool show_context); + + lldb::TypeSP + FindType(lldb::user_id_t uid); + + TypeList + FindTypes(const ConstString &name); + + lldb::TypeSP + InsertUnique(lldb::TypeSP& type); + + uint32_t + GetSize() const; + + lldb::TypeSP + GetTypeAtIndex(uint32_t idx); + + //------------------------------------------------------------------ + // Classes that inherit from TypeList can see and modify these + //------------------------------------------------------------------ + ClangASTContext & + GetClangASTContext (); + + void * + CreateClangPointerType (Type *type); + + void * + CreateClangTypedefType (Type *typedef_type, Type *base_type); + + // For C++98 references (&) + void * + CreateClangLValueReferenceType (Type *type); + + // For C++0x references (&&) + void * + CreateClangRValueReferenceType (Type *type); + + void * + GetConstClangType (Type *type); + + void * + GetRestrictClangType (Type *type); + + void * + GetVolatileClangType (Type *type); + +private: + typedef std::vector<lldb::TypeSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + ClangASTContext m_ast; ///< The type abtract syntax tree. + + collection m_types; + + DISALLOW_COPY_AND_ASSIGN (TypeList); +}; + +} // namespace lldb_private + +#endif // liblldb_TypeList_h_ diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h new file mode 100644 index 00000000000..0844943e9ca --- /dev/null +++ b/lldb/include/lldb/Symbol/Variable.h @@ -0,0 +1,123 @@ +//===-- Variable.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Variable_h_ +#define liblldb_Variable_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/Declaration.h" +#include "lldb/Core/UserID.h" + +namespace lldb_private { + +class Variable : public UserID +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + Variable(lldb::user_id_t uid, + const ConstString& name, Type *type, + lldb::ValueType scope, + SymbolContextScope *context, + Declaration* decl, + const DWARFExpression& location, + bool external, + bool artificial); + + virtual + ~Variable(); + + void + Dump(Stream *s, bool show_context) const; + + const Declaration& + GetDeclaration() const + { + return m_declaration; + } + + const ConstString& + GetName() const + { + return m_name; + } + + Type * + GetType() + { + return m_type; + } + + const Type * + GetType() const + { + return m_type; + } + + lldb::ValueType + GetScope() const + { + return m_scope; + } + + bool + IsExternal() const + { + return m_external; + } + + bool + IsArtificial() const + { + return m_artificial; + } + + DWARFExpression & + LocationExpression() + { + return m_location; + } + + const DWARFExpression & + LocationExpression() const + { + return m_location; + } + + size_t + MemorySize() const; + + void + CalculateSymbolContext (SymbolContext *sc); + + bool + IsInScope (StackFrame *frame); + +protected: + ConstString m_name; // Name of the variable + Type * m_type; // The type pointer of the variable (int, struct, class, etc) + lldb::ValueType m_scope; // global, parameter, local + SymbolContextScope *m_context;// The symbol file scope that this variable was defined in + Declaration m_declaration; // Declaration location for this item. + DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() + uint8_t m_external:1, // Visible outside the containing compile unit? + m_artificial:1; // Non-zero if the variable is not explicitly declared in source +private: + Variable(const Variable& rhs); + Variable& operator=(const Variable& rhs); +}; + +} // namespace lldb_private + +#endif // liblldb_Variable_h_ diff --git a/lldb/include/lldb/Symbol/VariableList.h b/lldb/include/lldb/Symbol/VariableList.h new file mode 100644 index 00000000000..53d21e659f8 --- /dev/null +++ b/lldb/include/lldb/Symbol/VariableList.h @@ -0,0 +1,74 @@ +//===-- VariableList.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_VariableList_h_ +#define liblldb_VariableList_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Variable.h" + +namespace lldb_private { + +class VariableList +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ +// VariableList(const SymbolContext &symbol_context); + VariableList(); + virtual ~VariableList(); + + void + AddVariable (lldb::VariableSP &var_sp); + + void + AddVariables(VariableList *variable_list); + + void + Clear(); + + void + Dump(Stream *s, bool show_context) const; + + lldb::VariableSP + GetVariableAtIndex(uint32_t idx); + + lldb::VariableSP + FindVariable(const ConstString& name); + +// const SymbolContext& +// GetSymbolContext() const +// { +// return m_symbol_context; +// } +// + size_t + MemorySize() const; + + size_t + GetSize() const; + +protected: + typedef std::vector<lldb::VariableSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + collection m_variables; +private: + //------------------------------------------------------------------ + // For VariableList only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (VariableList); +}; + +} // namespace lldb_private + +#endif // liblldb_VariableList_h_ diff --git a/lldb/include/lldb/Target/ABI.h b/lldb/include/lldb/Target/ABI.h new file mode 100644 index 00000000000..54b5dc52211 --- /dev/null +++ b/lldb/include/lldb/Target/ABI.h @@ -0,0 +1,67 @@ +//===-- ABI.h ---------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ABI_h_ +#define liblldb_ABI_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/PluginInterface.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class ABI : + public PluginInterface +{ +public: + virtual + ~ABI(); + + virtual size_t + GetRedZoneSize () const = 0; + + virtual bool + PrepareTrivialCall (Thread &thread, + lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + lldb::addr_t arg) const = 0; + + virtual bool + PrepareNormalCall (Thread &thread, + lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + ValueList &args) const = 0; + + virtual bool + GetArgumentValues (Thread &thread, + ValueList &values) const = 0; + + virtual bool + GetReturnValue (Thread &thread, + Value &value) const = 0; + + static ABI* + FindPlugin (const ConstString &triple); +protected: + //------------------------------------------------------------------ + // Classes that inherit from ABI can see and modify these + //------------------------------------------------------------------ + ABI(); +private: + DISALLOW_COPY_AND_ASSIGN (ABI); +}; + +} // namespace lldb_private + +#endif // liblldb_ABI_h_ diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h new file mode 100644 index 00000000000..9dc0cb6d9bb --- /dev/null +++ b/lldb/include/lldb/Target/DynamicLoader.h @@ -0,0 +1,154 @@ +//===-- DynamicLoader.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DynamicLoader_h_ +#define liblldb_DynamicLoader_h_ + +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class DynamicLoader DynamicLoader.h "lldb/Target/DynamicLoader.h" +/// @brief A plug-in interface definition class for dynamic loaders. +/// +/// Dynamic loader plug-ins track image (shared library) loading and +/// unloading. The class is initialized given a live process that is +/// halted at its entry point or just after attaching. +/// +/// Dynamic loader plug-ins can track the process by registering +/// callbacks using the: +/// Process::RegisterNotificationCallbacks (const Notifications&) +/// function. +/// +/// Breakpoints can also be set in the process which can register +/// functions that get called using: +/// Process::BreakpointSetCallback (lldb::user_id_t, BreakpointHitCallback, void *). +/// These breakpoint callbacks return a boolean value that indicates if +/// the process should continue or halt and should return the global +/// setting for this using: +/// DynamicLoader::StopWhenImagesChange() const. +//---------------------------------------------------------------------- +class DynamicLoader : + public PluginInterface +{ +public: + //------------------------------------------------------------------ + /// Find a dynamic loader plugin for a given process. + /// + /// Scans the installed DynamicLoader plug-ins and tries to find + /// an instance that can be used to track image changes in \a + /// process. + /// + /// @param[in] process + /// The process for which to try and locate a dynamic loader + /// plug-in instance. + /// + /// @param[in] plugin_name + /// An optional name of a specific dynamic loader plug-in that + /// should be used. If NULL, pick the best plug-in. + //------------------------------------------------------------------ + static DynamicLoader* + FindPlugin (Process *process, const char *plugin_name); + + //------------------------------------------------------------------ + /// Construct with a process. + //------------------------------------------------------------------ + DynamicLoader (Process *process); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + virtual + ~DynamicLoader (); + + //------------------------------------------------------------------ + /// Called after attaching a process. + /// + /// Allow DynamicLoader plug-ins to execute some code after + /// attaching to a process. + //------------------------------------------------------------------ + virtual void + DidAttach () = 0; + + //------------------------------------------------------------------ + /// Called after launching a process. + /// + /// Allow DynamicLoader plug-ins to execute some code after + /// the process has stopped for the first time on launch. + //------------------------------------------------------------------ + virtual void + DidLaunch () = 0; + + //------------------------------------------------------------------ + /// Get wether the process should stop when images change. + /// + /// When images (executables and shared libraries) get loaded or + /// unloaded, often debug sessions will want to try and resolve or + /// unresolve breakpoints that are set in these images. Any + /// breakpoints set by DynamicLoader plug-in instances should + /// return this value to ensure consistent debug session behaviour. + /// + /// @return + /// Returns \b true if the process should stop when images + /// change, \b false if the process should resume. + //------------------------------------------------------------------ + bool + GetStopWhenImagesChange () const; + + //------------------------------------------------------------------ + /// Set wether the process should stop when images change. + /// + /// When images (executables and shared libraries) get loaded or + /// unloaded, often debug sessions will want to try and resolve or + /// unresolve breakpoints that are set in these images. The default + /// is set so that the process stops when images change, but this + /// can be overridden using this function callback. + /// + /// @param[in] stop + /// Boolean value that indicates wether the process should stop + /// when images change. + //------------------------------------------------------------------ + void + SetStopWhenImagesChange (bool stop); + + //------------------------------------------------------------------ + /// Provides a plan to step through the dynamic loader trampoline + /// for the current state of \a thread. + /// + /// + /// @param[in] stop_others + /// Whether the plan should be set to stop other threads. + /// + /// @return + /// A pointer to the plan (caller owned) or NULL if we are not at such + /// a trampoline. + //------------------------------------------------------------------ + virtual lldb::ThreadPlanSP + GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; + +protected: + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + Process* m_process; ///< The process that this dynamic loader plug-in is tracking. + bool m_stop_when_images_change; ///< Boolean value that indicates if the process should stop when imamges change. +private: + DISALLOW_COPY_AND_ASSIGN (DynamicLoader); + +}; + +} // namespace lldb_private + +#endif // liblldb_DynamicLoader_h_ diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h new file mode 100644 index 00000000000..cc925cff997 --- /dev/null +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -0,0 +1,93 @@ +//===-- ExecutionContext.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_ExecutionContext_h_ +#define liblldb_ExecutionContext_h_ + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ExecutionContext ExecutionContext.h "lldb/Target/ExecutionContext.h" +/// @brief A class that contains an execution context. +/// +/// This baton object can be passed into any function that requires +/// a context that specifies a process, thread and frame. +/// +/// Many lldb functions can evaluate or act upon a specific +/// execution context. An expression could be evaluated for a specific +/// process, thread, and frame. The thread object contains frames and +/// can return StackFrame objects given a valid frame index using: +/// StackFrame * Thread::GetFrameAtIndex (uint32_t idx). +//---------------------------------------------------------------------- +class ExecutionContext +{ +public: + //------------------------------------------------------------------ + /// Default Constructor. + /// + /// Initialize with NULL process and thread, and invalid frame + /// index. + //------------------------------------------------------------------ + ExecutionContext(); + + + ExecutionContext (Target* t, bool fill_current_process_thread_frame = true); + //------------------------------------------------------------------ + /// Construct with process, thread, and frame index. + /// + /// Initialize with process \a p, thread \a t, and frame index \a f. + /// + /// @param[in] process + /// The process for this execution context. + /// + /// @param[in] thread + /// The thread for this execution context. + /// + /// @param[in] frame + /// The frame index for this execution context. + //------------------------------------------------------------------ + ExecutionContext (Process* process, + Thread *thread = NULL, + StackFrame * frame = NULL); + + + ExecutionContext (ExecutionContextScope *exe_scope); + + ExecutionContext (ExecutionContextScope &exe_scope); + + //------------------------------------------------------------------ + /// Clear the object's state. + /// + /// Sets the process and thread to NULL, and the frame index to an + /// invalid value. + //------------------------------------------------------------------ + void + Clear (); + + RegisterContext * + GetRegisterContext () const; + + + ExecutionContextScope * + GetBestExecutionContextScope () const; + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Target *target; ///< The target that owns the process/thread/frame + Process *process; ///< The process that owns the thread/frame + Thread *thread; ///< The thread that owns the frame + StackFrame *frame; ///< The stack frame in thread. +}; + +} // namespace lldb_private + +#endif // liblldb_ExecutionContext_h_ diff --git a/lldb/include/lldb/Target/ExecutionContextScope.h b/lldb/include/lldb/Target/ExecutionContextScope.h new file mode 100644 index 00000000000..f98e3276543 --- /dev/null +++ b/lldb/include/lldb/Target/ExecutionContextScope.h @@ -0,0 +1,71 @@ +//===-- ExecutionContextScope.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ExecutionContextScope_h_ +#define liblldb_ExecutionContextScope_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class ExecutionContextScope ExecutionContextScope.h "lldb/Symbol/ExecutionContextScope.h" +/// @brief Inherit from this if your object can reconstruct its +/// execution context. +/// +/// Many objects that have pointers back to parent execution context +/// objects can inherit from this pure virtual class can reconstruct +/// their execution context without having to keep a complete +/// ExecutionContext object in the object state. Examples of these +/// objects include: Process, Thread, RegisterContext and StackFrame. +/// +/// Bbjects can contain a valid pointer to an instance of this so they +/// can reconstruct the execution context. +/// +/// Objects that adhere to this protocol can reconstruct enough of a +/// execution context to allow functions that take a execution contexts +/// to be called. +//---------------------------------------------------------------------- +class ExecutionContextScope +{ +public: + virtual Target * + CalculateTarget () = 0; + + virtual Process * + CalculateProcess () = 0; + + virtual Thread * + CalculateThread () = 0; + + virtual StackFrame * + CalculateStackFrame () = 0; + + //------------------------------------------------------------------ + /// Reconstruct the object's execution context into \a sc. + /// + /// The object should fill in as much of the ExecutionContextScope as it + /// can so function calls that require a execution context can be made + /// for the given object. + /// + /// @param[out] exe_ctx + /// A reference to an execution context object that gets filled + /// in. + //------------------------------------------------------------------ + virtual void + Calculate (ExecutionContext &exe_ctx) = 0; +}; + +} // namespace lldb_private + +#endif // liblldb_ExecutionContextScope_h_ diff --git a/lldb/include/lldb/Target/ObjCObjectPrinter.h b/lldb/include/lldb/Target/ObjCObjectPrinter.h new file mode 100644 index 00000000000..3b7005b0962 --- /dev/null +++ b/lldb/include/lldb/Target/ObjCObjectPrinter.h @@ -0,0 +1,49 @@ +//===-- ObjCObjectPrinter.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ObjCObjectPrinter_h_ +#define liblldb_ObjCObjectPrinter_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Error.h" +// Project includes + +namespace lldb_private { + + class ObjCObjectPrinter + { + public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ObjCObjectPrinter (Process &process); + + virtual + ~ObjCObjectPrinter (); + + bool + PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx); + protected: + Process &m_process; + std::auto_ptr<Address> m_PrintForDebugger_addr; + + Address *GetPrintForDebuggerAddr(); + private: + //------------------------------------------------------------------ + // For ObjCObjectPrinter only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ObjCObjectPrinter); + }; + +} // namespace lldb_private + +#endif // liblldb_ObjCObjectPrinter_h_ diff --git a/lldb/include/lldb/Target/PathMappingList.h b/lldb/include/lldb/Target/PathMappingList.h new file mode 100644 index 00000000000..3881437ffd4 --- /dev/null +++ b/lldb/include/lldb/Target/PathMappingList.h @@ -0,0 +1,82 @@ +//===-- PathMappingList.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_PathMappingList_h_ +#define liblldb_PathMappingList_h_ + +// C Includes +// C++ Includes +#include <map> +#include <vector> +// Other libraries and framework includes +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Error.h" +// Project includes + +namespace lldb_private { + +class PathMappingList +{ +public: + + typedef void (*ChangedCallback) (const PathMappingList &path_list, + void *baton); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + PathMappingList (ChangedCallback callback, + void *callback_baton); + + virtual + ~PathMappingList (); + + void + Append (const ConstString &path, const ConstString &replacement, bool notify); + + void + Clear (bool notify); + + void + Dump (Stream *s); + + size_t + GetSize (); + + void + Insert (const ConstString &path, + const ConstString &replacement, + uint32_t insert_idx, + bool notify); + + bool + Remove (off_t index, bool notify); + + bool + RemapPath (const ConstString &path, ConstString &new_path); + +protected: + typedef std::pair <ConstString, ConstString> pair; + typedef std::vector <pair> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + collection m_pairs; + ChangedCallback m_callback; + void * m_callback_baton; +private: + //------------------------------------------------------------------ + // For PathMappingList only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (PathMappingList); +}; + +} // namespace lldb_private + +#endif // liblldb_PathMappingList_h_ diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h new file mode 100644 index 00000000000..30663bd1c52 --- /dev/null +++ b/lldb/include/lldb/Target/Process.h @@ -0,0 +1,1415 @@ +//===-- Process.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Process_h_ +#define liblldb_Process_h_ + +// C Includes +// C++ Includes +#include <list> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Event.h" +#include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Core/ThreadSafeSTLMap.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/Breakpoint/BreakpointSiteList.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/ObjCObjectPrinter.h" +#include "lldb/Target/ThreadList.h" +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Process Process.h "lldb/Target/Process.h" +/// @brief A plug-in interface definition class for debugging a process. +//---------------------------------------------------------------------- +class Process : + public UserID, + public Broadcaster, + public ExecutionContextScope, + public PluginInterface +{ +friend class ThreadList; + +public: + + //------------------------------------------------------------------ + /// Broadcaster event bits definitions. + //------------------------------------------------------------------ + enum + { + eBroadcastBitStateChanged = (1 << 0), + eBroadcastBitInterrupt = (1 << 1), + eBroadcastBitSTDOUT = (1 << 2), + eBroadcastBitSTDERR = (1 << 3), + }; + + enum + { + eBroadcastInternalStateControlStop = (1<<0), + eBroadcastInternalStateControlPause = (1<<1), + eBroadcastInternalStateControlResume = (1<<2) + }; + + //------------------------------------------------------------------ + /// A notification structure that can be used by clients to listen + /// for changes in a process's lifetime. + /// + /// @see RegisterNotificationCallbacks (const Notifications&) + /// @see UnregisterNotificationCallbacks (const Notifications&) + //------------------------------------------------------------------ +#ifndef SWIG + typedef struct + { + void *baton; + void (*initialize)(void *baton, Process *process); + void (*process_state_changed) (void *baton, Process *process, lldb::StateType state); + } Notifications; + + class ProcessEventData : + public EventData + { + public: + ProcessEventData (); + ProcessEventData (const lldb::ProcessSP &process, lldb::StateType state); + + virtual ~ProcessEventData(); + + static const ConstString & + GetFlavorString (); + + virtual const ConstString & + GetFlavor () const; + + const lldb::ProcessSP & + GetProcessSP() const; + + lldb::StateType + GetState() const; + + bool + GetRestarted () const; + + virtual void + Dump (Stream *s) const; + + virtual void + DoOnRemoval (Event *event_ptr); + + static const Process::ProcessEventData * + GetEventDataFromEvent (const Event *event_ptr); + + static lldb::ProcessSP + GetProcessFromEvent (const Event *event_ptr); + + static lldb::StateType + GetStateFromEvent (const Event *event_ptr); + + static bool + GetRestartedFromEvent (const Event *event_ptr); + + static void + SetRestartedInEvent (Event *event_ptr, bool new_value); + + static bool + SetUpdateStateOnRemoval (Event *event_ptr); + + + private: + + void + SetUpdateStateOnRemoval(); + + void + SetRestarted (bool new_value); + + lldb::ProcessSP m_process_sp; + lldb::StateType m_state; + bool m_restarted; // For "eStateStopped" events, this is true if the target was automatically restarted. + bool m_update_state; + DISALLOW_COPY_AND_ASSIGN (ProcessEventData); + + }; +#endif + + //------------------------------------------------------------------ + /// Construct with a shared pointer to a target, and the Process listener. + //------------------------------------------------------------------ + Process(Target &target, Listener &listener); + + //------------------------------------------------------------------ + /// Destructor. + /// + /// The destructor is virtual since this class is designed to be + /// inherited from by the plug-in instance. + //------------------------------------------------------------------ + virtual + ~Process(); + + //------------------------------------------------------------------ + /// Find a Process plug-in that can debug \a module using the + /// currently selected architecture. + /// + /// Scans all loaded plug-in interfaces that implement versions of + /// the Process plug-in interface and returns the first instance + /// that can debug the file. + /// + /// @param[in] module_sp + /// The module shared pointer that this process will debug. + /// + /// @param[in] plugin_name + /// If NULL, select the best plug-in for the binary. If non-NULL + /// then look for a plugin whose PluginInfo's name matches + /// this string. + /// + /// @see Process::CanDebug () + //------------------------------------------------------------------ + static Process* + FindPlugin (Target &target, const char *plugin_name, Listener &listener); + + + + //------------------------------------------------------------------ + /// Static function that can be used with the \b host function + /// Host::StartMonitoringChildProcess (). + /// + /// This function can be used by lldb_private::Process subclasses + /// when they want to watch for a local process and have its exit + /// status automatically set when the host child process exits. + /// Subclasses should call Host::StartMonitoringChildProcess () + /// with: + /// callback = Process::SetHostProcessExitStatus + /// callback_baton = NULL + /// pid = Process::GetID() + /// monitor_signals = false + //------------------------------------------------------------------ + static bool + SetProcessExitStatus (void *callback_baton, // The callback baton which should be set to NULL + lldb::pid_t pid, // The process ID we want to monitor + int signo, // Zero for no signal + int status); // Exit value of process if signal is zero + + //------------------------------------------------------------------ + /// Check if a plug-in instance can debug the file in \a module. + /// + /// Each plug-in is given a chance to say wether it can debug + /// the file in \a module. If the Process plug-in instance can + /// debug a file on the current system, it should return \b true. + /// + /// @return + /// Returns \b true if this Process plug-in instance can + /// debug the executable, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + CanDebug (Target &target) = 0; + + + //------------------------------------------------------------------ + /// This object is about to be destroyed, do any necessary cleanup. + /// + /// Subclasses that override this method should always call this + /// superclass method. + //------------------------------------------------------------------ + virtual void + Finalize(); + + //------------------------------------------------------------------ + /// Launch a new process. + /// + /// Launch a new process by spawning a new process using the + /// target object's executable module's file as the file to launch. + /// Arguments are given in \a argv, and the environment variables + /// are in \a envp. Standard input and output files can be + /// optionally re-directed to \a stdin_path, \a stdout_path, and + /// \a stderr_path. + /// + /// This function is not meant to be overridden by Process + /// subclasses. It will first call Process::WillLaunch (Module *) + /// and if that returns \b true, Process::DoLaunch (Module*, + /// char const *[],char const *[],const char *,const char *, + /// const char *) will be called to actually do the launching. If + /// DoLaunch returns \b true, then Process::DidLaunch() will be + /// called. + /// + /// @param[in] argv + /// The argument array. + /// + /// @param[in] envp + /// The environment array. + /// + /// @param[in] stdin_path + /// The path to use when re-directing the STDIN of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @param[in] stdout_path + /// The path to use when re-directing the STDOUT of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @param[in] stderr_path + /// The path to use when re-directing the STDERR of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @return + /// An error object. Call GetID() to get the process ID if + /// the error object is success. + //------------------------------------------------------------------ + virtual Error + Launch (char const *argv[], + char const *envp[], + const char *stdin_path, + const char *stdout_path, + const char *stderr_path); + + //------------------------------------------------------------------ + /// Attach to an existing process using a process ID. + /// + /// This function is not meant to be overridden by Process + /// subclasses. It will first call Process::WillAttach (lldb::pid_t) + /// and if that returns \b true, Process::DoAttach (lldb::pid_t) will + /// be called to actually do the attach. If DoAttach returns \b + /// true, then Process::DidAttach() will be called. + /// + /// @param[in] pid + /// The process ID that we should attempt to attach to. + /// + /// @return + /// Returns \a pid if attaching was successful, or + /// LLDB_INVALID_PROCESS_ID if attaching fails. + //------------------------------------------------------------------ + virtual Error + Attach (lldb::pid_t pid); + + //------------------------------------------------------------------ + /// Attach to an existing process by process name. + /// + /// This function is not meant to be overridden by Process + /// subclasses. It will first call + /// Process::WillAttach (const char *) and if that returns \b + /// true, Process::DoAttach (const char *) will be called to + /// actually do the attach. If DoAttach returns \b true, then + /// Process::DidAttach() will be called. + /// + /// @param[in] process_name + /// A process name to match against the current process list. + /// + /// @return + /// Returns \a pid if attaching was successful, or + /// LLDB_INVALID_PROCESS_ID if attaching fails. + //------------------------------------------------------------------ + virtual Error + Attach (const char *process_name, bool wait_for_launch); + + uint32_t + GetAddressByteSize(); + + //------------------------------------------------------------------ + /// Get the image information address for the current process. + /// + /// Some runtimes have system functions that can help dynamic + /// loaders locate the dynamic loader information needed to observe + /// shared libraries being loaded or unloaded. This function is + /// in the Process interface (as opposed to the DynamicLoader + /// interface) to ensure that remote debugging can take advantage of + /// this functionality. + /// + /// @return + /// The address of the dynamic loader information, or + /// LLDB_INVALID_ADDRESS if this is not supported by this + /// interface. + //------------------------------------------------------------------ + virtual lldb::addr_t + GetImageInfoAddress (); + + //------------------------------------------------------------------ + /// Register for process and thread notifications. + /// + /// Clients can register nofication callbacks by filling out a + /// Process::Notifications structure and calling this function. + /// + /// @param[in] callbacks + /// A structure that contains the notification baton and + /// callback functions. + /// + /// @see Process::Notifications + //------------------------------------------------------------------ +#ifndef SWIG + void + RegisterNotificationCallbacks (const Process::Notifications& callbacks); +#endif + //------------------------------------------------------------------ + /// Unregister for process and thread notifications. + /// + /// Clients can unregister nofication callbacks by passing a copy of + /// the original baton and callbacks in \a callbacks. + /// + /// @param[in] callbacks + /// A structure that contains the notification baton and + /// callback functions. + /// + /// @return + /// Returns \b true if the notification callbacks were + /// successfully removed from the process, \b false otherwise. + /// + /// @see Process::Notifications + //------------------------------------------------------------------ +#ifndef SWIG + bool + UnregisterNotificationCallbacks (const Process::Notifications& callbacks); +#endif + //================================================================== + // Built in Process Control functions + //================================================================== + //------------------------------------------------------------------ + /// Resumes all of a process's threads as configured using the + /// Thread run control functions. + /// + /// Threads for a process should be updated with one of the run + /// control actions (resume, step, or suspend) that they should take + /// when the process is resumed. If no run control action is given + /// to a thread it will be resumed by default. + /// + /// This function is not meant to be overridden by Process + /// subclasses. This function will take care of disabling any + /// breakpoints that threads may be stopped at, single stepping, and + /// re-enabling breakpoints, and enabling the basic flow control + /// that the plug-in instances need not worry about. + /// + /// @return + /// Returns an error object. + /// + /// @see Thread:Resume() + /// @see Thread:Step() + /// @see Thread:Suspend() + //------------------------------------------------------------------ + virtual Error + Resume (); + + //------------------------------------------------------------------ + /// Halts a running process. + /// + /// This function is not meant to be overridden by Process + /// subclasses. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + Halt (); + + //------------------------------------------------------------------ + /// Detaches from a running or stopped process. + /// + /// This function is not meant to be overridden by Process + /// subclasses. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + Detach (); + + //------------------------------------------------------------------ + /// Kills the process and shuts down all threads that were spawned + /// to track and monitor the process. + /// + /// This function is not meant to be overridden by Process + /// subclasses. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + Destroy(); + + //------------------------------------------------------------------ + /// Sends a process a UNIX signal \a signal. + /// + /// This function is not meant to be overridden by Process + /// subclasses. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + Signal (int signal); + + virtual UnixSignals & + GetUnixSignals (); + + + //================================================================== + // Plug-in Process Control Overrides + //================================================================== + + //------------------------------------------------------------------ + /// Called before attaching to a process. + /// + /// Allow Process plug-ins to execute some code before attaching a + /// process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillAttach (lldb::pid_t pid) + { + return Error(); + } + + //------------------------------------------------------------------ + /// Called before attaching to a process. + /// + /// Allow Process plug-ins to execute some code before attaching a + /// process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillAttach (const char *process_name, bool wait_for_launch) + { + return Error(); + } + + //------------------------------------------------------------------ + /// Attach to an existing process using a process ID. + /// + /// @param[in] pid + /// The process ID that we should attempt to attach to. + /// + /// @return + /// Returns \a pid if attaching was successful, or + /// LLDB_INVALID_PROCESS_ID if attaching fails. + //------------------------------------------------------------------ + virtual Error + DoAttach (lldb::pid_t pid) = 0; + + //------------------------------------------------------------------ + /// Attach to an existing process using a partial process name. + /// + /// @param[in] process_name + /// The name of the process to attach to. + /// + /// @param[in] wait_for_launch + /// If \b true, wait for the process to be launched and attach + /// as soon as possible after it does launch. If \b false, then + /// search for a matching process the currently exists. + /// + /// @return + /// Returns \a pid if attaching was successful, or + /// LLDB_INVALID_PROCESS_ID if attaching fails. + //------------------------------------------------------------------ + virtual Error + DoAttach (const char *process_name, bool wait_for_launch) + { + Error error; + error.SetErrorString("attach by name is not supported"); + return error; + } + + //------------------------------------------------------------------ + /// Called after attaching a process. + /// + /// Allow Process plug-ins to execute some code after attaching to + /// a process. + //------------------------------------------------------------------ + virtual void + DidAttach () {} + + + //------------------------------------------------------------------ + /// Called before launching to a process. + /// + /// Allow Process plug-ins to execute some code before launching a + /// process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillLaunch (Module* module) + { + return Error(); + } + + //------------------------------------------------------------------ + /// Launch a new process. + /// + /// Launch a new process by spawning a new process using \a module's + /// file as the file to launch. Arguments are given in \a argv, + /// and the environment variables are in \a envp. Standard input + /// and output files can be optionally re-directed to \a stdin_path, + /// \a stdout_path, and \a stderr_path. + /// + /// @param[in] module + /// The module from which to extract the file specification and + /// launch. + /// + /// @param[in] argv + /// The argument array. + /// + /// @param[in] envp + /// The environment array. + /// + /// @param[in] stdin_path + /// The path to use when re-directing the STDIN of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @param[in] stdout_path + /// The path to use when re-directing the STDOUT of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @param[in] stderr_path + /// The path to use when re-directing the STDERR of the new + /// process. If all stdXX_path arguments are NULL, a pseudo + /// terminal will be used. + /// + /// @return + /// A new valid process ID, or LLDB_INVALID_PROCESS_ID if + /// launching fails. + //------------------------------------------------------------------ + virtual Error + DoLaunch (Module* module, + char const *argv[], + char const *envp[], + const char *stdin_path, + const char *stdout_path, + const char *stderr_path) = 0; + + //------------------------------------------------------------------ + /// Called after launching a process. + /// + /// Allow Process plug-ins to execute some code after launching + /// a process. + //------------------------------------------------------------------ + virtual void + DidLaunch () {} + + + + //------------------------------------------------------------------ + /// Called before resuming to a process. + /// + /// Allow Process plug-ins to execute some code before resuming a + /// process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillResume () { return Error(); } + + //------------------------------------------------------------------ + /// Resumes all of a process's threads as configured using the + /// Thread run control functions. + /// + /// Threads for a process should be updated with one of the run + /// control actions (resume, step, or suspend) that they should take + /// when the process is resumed. If no run control action is given + /// to a thread it will be resumed by default. + /// + /// @return + /// Returns \b true if the process successfully resumes using + /// the thread run control actions, \b false otherwise. + /// + /// @see Thread:Resume() + /// @see Thread:Step() + /// @see Thread:Suspend() + //------------------------------------------------------------------ + virtual Error + DoResume () = 0; + + //------------------------------------------------------------------ + /// Called after resuming a process. + /// + /// Allow Process plug-ins to execute some code after resuming + /// a process. + //------------------------------------------------------------------ + virtual void + DidResume () {} + + + //------------------------------------------------------------------ + /// Called before halting to a process. + /// + /// Allow Process plug-ins to execute some code before halting a + /// process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillHalt () { return Error(); } + + //------------------------------------------------------------------ + /// Halts a running process. + /// + /// @return + /// Returns \b true if the process successfully halts, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual Error + DoHalt () = 0; + + //------------------------------------------------------------------ + /// Called after halting a process. + /// + /// Allow Process plug-ins to execute some code after halting + /// a process. + //------------------------------------------------------------------ + virtual void + DidHalt () {} + + //------------------------------------------------------------------ + /// Called before detaching from a process. + /// + /// Allow Process plug-ins to execute some code before detaching + /// from a process. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + WillDetach () + { + return Error(); + } + + //------------------------------------------------------------------ + /// Detaches from a running or stopped process. + /// + /// @return + /// Returns \b true if the process successfully detaches, \b + /// false otherwise. + //------------------------------------------------------------------ + virtual Error + DoDetach () = 0; + + //------------------------------------------------------------------ + /// Called after detaching from a process. + /// + /// Allow Process plug-ins to execute some code after detaching + /// from a process. + //------------------------------------------------------------------ + virtual void + DidDetach () {} + + //------------------------------------------------------------------ + /// Called before sending a signal to a process. + /// + /// Allow Process plug-ins to execute some code before sending a + /// signal to a process. + /// + /// @return + /// Returns no error if it is safe to proceed with a call to + /// Process::DoSignal(int), otherwise an error describing what + /// prevents the signal from being sent. + //------------------------------------------------------------------ + virtual Error + WillSignal () { return Error(); } + + //------------------------------------------------------------------ + /// Sends a process a UNIX signal \a signal. + /// + /// @return + /// Returns an error object. + //------------------------------------------------------------------ + virtual Error + DoSignal (int signal) = 0; + + + + virtual Error + WillDestroy () { return Error(); } + + virtual Error + DoDestroy () = 0; + + virtual void + DidDestroy () { } + + + //------------------------------------------------------------------ + /// Called after sending a signal to a process. + /// + /// Allow Process plug-ins to execute some code after sending a + /// signal to a process. + //------------------------------------------------------------------ + virtual void + DidSignal () {} + + + //------------------------------------------------------------------ + /// Currently called as part of ShouldStop. + /// FIXME: Should really happen when the target stops before the + /// event is taken from the queue... + /// + /// This callback is called as the event + /// is about to be queued up to allow Process plug-ins to execute + /// some code prior to clients being notified that a process was + /// stopped. Common operations include updating the thread list, + /// invalidating any thread state (registers, stack, etc) prior to + /// letting the notification go out. + /// + //------------------------------------------------------------------ + virtual void + RefreshStateAfterStop () = 0; + + //------------------------------------------------------------------ + /// Get the target object pointer for this module. + /// + /// @return + /// A Target object pointer to the target that owns this + /// module. + //------------------------------------------------------------------ + Target & + GetTarget (); + + //------------------------------------------------------------------ + /// Get the const target object pointer for this module. + /// + /// @return + /// A const Target object pointer to the target that owns this + /// module. + //------------------------------------------------------------------ + const Target & + GetTarget () const; + + //------------------------------------------------------------------ + /// Get accessor for the current process state. + /// + /// @return + /// The current state of the process. + /// + /// @see lldb::StateType + //------------------------------------------------------------------ + lldb::StateType + GetState (); + +protected: + friend class CommandObjectProcessLaunch; + friend class ProcessEventData; + friend class CommandObjectBreakpointCommand; + + void + SetState (lldb::EventSP &event_sp); + + lldb::StateType + GetPrivateState (); + +public: + //------------------------------------------------------------------ + /// Get the exit status for a process. + /// + /// @return + /// The process's return code, or -1 if the current process + /// state is not eStateExited. + //------------------------------------------------------------------ + int + GetExitStatus (); + + //------------------------------------------------------------------ + /// Get a textual description of what the process exited. + /// + /// @return + /// The textual description of why the process exited, or NULL + /// if there is no description available. + //------------------------------------------------------------------ + const char * + GetExitDescription (); + + + virtual void + DidExit () + { + } + + //------------------------------------------------------------------ + /// Get the number of times this process has posted a stop event. + /// + /// @return + /// The number of times this process has stopped while being + /// debugged. + //------------------------------------------------------------------ + uint32_t + GetStopID () const; + + //------------------------------------------------------------------ + /// Set accessor for the process exit status (return code). + /// + /// Sometimes a child exits and the exit can be detected by global + /// functions (signal handler for SIGCHLD for example). This + /// accessor allows the exit status to be set from an external + /// source. + /// + /// Setting this will cause a eStateExited event to be posted to + /// the process event queue. + /// + /// @param[in] exit_status + /// The value for the process's return code. + /// + /// @see lldb::StateType + //------------------------------------------------------------------ + virtual void + SetExitStatus (int exit_status, const char *cstr); + + //------------------------------------------------------------------ + /// Check if a process is still alive. + /// + /// @return + /// Returns \b true if the process is still valid, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual bool + IsAlive () = 0; + + //------------------------------------------------------------------ + /// Actually do the reading of memory from a process. + /// + /// Subclasses must override this function and can return fewer + /// bytes than requested when memory requests are too large. This + /// class will break up the memory requests and keep advancing the + /// arguments along as needed. + /// + /// @param[in] vm_addr + /// A virtual load address that indicates where to start reading + /// memory from. + /// + /// @param[in] size + /// The number of bytes to read. + /// + /// @param[out] buf + /// A byte buffer that is at least \a size bytes long that + /// will receive the memory bytes. + /// + /// @return + /// The number of bytes that were actually read into \a buf. + //------------------------------------------------------------------ + virtual size_t + DoReadMemory (lldb::addr_t vm_addr, + void *buf, + size_t size, + Error &error) = 0; + + //------------------------------------------------------------------ + /// Read of memory from a process. + /// + /// This function will read memory from the current process's + /// address space and remove any traps that may have been inserted + /// into the memory. + /// + /// This function is not meant to be overridden by Process + /// subclasses, the subclasses should implement + /// Process::DoReadMemory (lldb::addr_t, size_t, void *). + /// + /// @param[in] vm_addr + /// A virtual load address that indicates where to start reading + /// memory from. + /// + /// @param[out] buf + /// A byte buffer that is at least \a size bytes long that + /// will receive the memory bytes. + /// + /// @param[in] size + /// The number of bytes to read. + /// + /// @return + /// The number of bytes that were actually read into \a buf. If + /// the returned number is greater than zero, yet less than \a + /// size, then this function will get called again with \a + /// vm_addr, \a buf, and \a size updated appropriately. Zero is + /// returned to indicate an error. + //------------------------------------------------------------------ + size_t + ReadMemory (lldb::addr_t vm_addr, + void *buf, + size_t size, + Error &error); + + //------------------------------------------------------------------ + /// Actually do the writing of memory to a process. + /// + /// @param[in] vm_addr + /// A virtual load address that indicates where to start writing + /// memory to. + /// + /// @param[in] buf + /// A byte buffer that is at least \a size bytes long that + /// contains the data to write. + /// + /// @param[in] size + /// The number of bytes to write. + /// + /// @return + /// The number of bytes that were actually written. + //------------------------------------------------------------------ + virtual size_t + DoWriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) = 0; + + //------------------------------------------------------------------ + /// Write memory to a process. + /// + /// This function will write memory to the current process's + /// address space and maintain any traps that might be present due + /// to software breakpoints. + /// + /// This function is not meant to be overridden by Process + /// subclasses, the subclasses should implement + /// Process::DoWriteMemory (lldb::addr_t, size_t, void *). + /// + /// @param[in] vm_addr + /// A virtual load address that indicates where to start writing + /// memory to. + /// + /// @param[in] buf + /// A byte buffer that is at least \a size bytes long that + /// contains the data to write. + /// + /// @param[in] size + /// The number of bytes to write. + /// + /// @return + /// The number of bytes that were actually written. + //------------------------------------------------------------------ + size_t + WriteMemory (lldb::addr_t vm_addr, const void *buf, size_t size, Error &error); + + + //------------------------------------------------------------------ + /// Actually allocate memory in the process. + /// + /// This function will allocate memory in the process's address + /// space. This can't rely on the generic function calling mechanism, + /// since that requires this function. + /// + /// @param[in] size + /// The size of the allocation requested. + /// + /// @return + /// The address of the allocated buffer in the process, or + /// LLDB_INVALID_ADDRESS if the allocation failed. + //------------------------------------------------------------------ + + virtual lldb::addr_t + DoAllocateMemory (size_t size, uint32_t permissions, Error &error) = 0; + + //------------------------------------------------------------------ + /// The public interface to allocating memory in the process. + /// + /// This function will allocate memory in the process's address + /// space. This can't rely on the generic function calling mechanism, + /// since that requires this function. + /// + /// @param[in] size + /// The size of the allocation requested. + /// + /// @param[in] permissions + /// Or together any of the lldb::Permissions bits. The permissions on + /// a given memory allocation can't be changed after allocation. Note + /// that a block that isn't set writable can still be written on from lldb, + /// just not by the process itself. + /// + /// @return + /// The address of the allocated buffer in the process, or + /// LLDB_INVALID_ADDRESS if the allocation failed. + //------------------------------------------------------------------ + + lldb::addr_t + AllocateMemory (size_t size, uint32_t permissions, Error &error); + + //------------------------------------------------------------------ + /// Actually deallocate memory in the process. + /// + /// This function will deallocate memory in the process's address + /// space that was allocated with AllocateMemory. + /// + /// @param[in] ptr + /// A return value from AllocateMemory, pointing to the memory you + /// want to deallocate. + /// + /// @return + /// \btrue if the memory was deallocated, \bfalse otherwise. + //------------------------------------------------------------------ + + virtual Error + DoDeallocateMemory (lldb::addr_t ptr) = 0; + + //------------------------------------------------------------------ + /// The public interface to deallocating memory in the process. + /// + /// This function will deallocate memory in the process's address + /// space that was allocated with AllocateMemory. + /// + /// @param[in] ptr + /// A return value from AllocateMemory, pointing to the memory you + /// want to deallocate. + /// + /// @return + /// \btrue if the memory was deallocated, \bfalse otherwise. + //------------------------------------------------------------------ + + Error + DeallocateMemory (lldb::addr_t ptr); + + //------------------------------------------------------------------ + /// Get any available STDOUT. + /// + /// If the process was launched without supplying valid file paths + /// for stdin, stdout, and stderr, then the Process class might + /// try to cache the STDOUT for the process if it is able. Events + /// will be queued indicating that there is STDOUT available that + /// can be retrieved using this function. + /// + /// @param[out] buf + /// A buffer that will receive any STDOUT bytes that are + /// currently available. + /// + /// @param[out] buf_size + /// The size in bytes for the buffer \a buf. + /// + /// @return + /// The number of bytes written into \a buf. If this value is + /// equal to \a buf_size, another call to this function should + /// be made to retrieve more STDOUT data. + //------------------------------------------------------------------ + virtual size_t + GetSTDOUT (char *buf, size_t buf_size, Error &error) + { + error.SetErrorString("stdout unsupported"); + return 0; + } + + + //------------------------------------------------------------------ + /// Get any available STDERR. + /// + /// If the process was launched without supplying valid file paths + /// for stdin, stdout, and stderr, then the Process class might + /// try to cache the STDERR for the process if it is able. Events + /// will be queued indicating that there is STDERR available that + /// can be retrieved using this function. + /// + /// @param[out] buf + /// A buffer that will receive any STDERR bytes that are + /// currently available. + /// + /// @param[out] buf_size + /// The size in bytes for the buffer \a buf. + /// + /// @return + /// The number of bytes written into \a buf. If this value is + /// equal to \a buf_size, another call to this function should + /// be made to retrieve more STDERR data. + //------------------------------------------------------------------ + virtual size_t + GetSTDERR (char *buf, size_t buf_size, Error &error) + { + error.SetErrorString("stderr unsupported"); + return 0; + } + + virtual size_t + PutSTDIN (const char *buf, size_t buf_size, Error &error) + { + error.SetErrorString("stdin unsupported"); + return 0; + } + + //---------------------------------------------------------------------- + // Process Breakpoints + //---------------------------------------------------------------------- + virtual size_t + GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site) = 0; + + virtual Error + EnableBreakpoint (BreakpointSite *bp_site) = 0; + + virtual Error + DisableBreakpoint (BreakpointSite *bp_site) = 0; + + // This is implemented completely using the lldb::Process API. Subclasses + // don't need to implement this function unless the standard flow of + // read existing opcode, write breakpoint opcode, verify breakpoint opcode + // doesn't work for a specific process plug-in. + virtual Error + EnableSoftwareBreakpoint (BreakpointSite *bp_site); + + // This is implemented completely using the lldb::Process API. Subclasses + // don't need to implement this function unless the standard flow of + // restoring original opcode in memory and verifying the restored opcode + // doesn't work for a specific process plug-in. + virtual Error + DisableSoftwareBreakpoint (BreakpointSite *bp_site); + + BreakpointSiteList & + GetBreakpointSiteList(); + + const BreakpointSiteList & + GetBreakpointSiteList() const; + + void + DisableAllBreakpointSites (); + + Error + ClearBreakpointSiteByID (lldb::user_id_t break_id); + + lldb::user_id_t + CreateBreakpointSite (lldb::BreakpointLocationSP &owner, + bool use_hardware); + + Error + DisableBreakpointSiteByID (lldb::user_id_t break_id); + + Error + EnableBreakpointSiteByID (lldb::user_id_t break_id); + + + // BreakpointLocations use RemoveOwnerFromBreakpointSite to remove + // themselves from the owner's list of this breakpoint sites. This has to + // be a static function because you can't be sure that removing the + // breakpoint from it's containing map won't delete the breakpoint site, + // and doing that in an instance method isn't copasetic. + void + RemoveOwnerFromBreakpointSite (lldb::user_id_t owner_id, + lldb::user_id_t owner_loc_id, + lldb::BreakpointSiteSP &bp_site_sp); + + //---------------------------------------------------------------------- + // Process Watchpoints (optional) + //---------------------------------------------------------------------- + virtual Error + EnableWatchpoint (WatchpointLocation *bp_loc); + + virtual Error + DisableWatchpoint (WatchpointLocation *bp_loc); + + //------------------------------------------------------------------ + // Thread Queries + //------------------------------------------------------------------ + virtual uint32_t + UpdateThreadListIfNeeded () = 0; + + ThreadList & + GetThreadList (); + + const ThreadList & + GetThreadList () const; + + uint32_t + GetNextThreadIndexID (); + + //------------------------------------------------------------------ + // Event Handling + //------------------------------------------------------------------ + lldb::StateType + GetNextEvent (lldb::EventSP &event_sp); + + lldb::StateType + WaitForProcessToStop (const TimeValue *timeout); + + lldb::StateType + WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp); + + Event * + PeekAtStateChangedEvents (); + + //------------------------------------------------------------------ + /// This is the part of the event handling that for a process event. + /// It decides what to do with the event and returns true if the + /// event needs to be propagated to the user, and false otherwise. + /// If the event is not propagated, this call will most likely set + /// the target to executing again. + /// + /// @param[in] event_ptr + /// This is the event we are handling. + /// + /// @return + /// Returns \b true if the event should be reported to the + /// user, \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldBroadcastEvent (Event *event_ptr); + + //------------------------------------------------------------------ + /// Gets the byte order for this process. + /// + /// @return + /// A valid ByteOrder enumeration, or eByteOrderInvalid. + //------------------------------------------------------------------ + virtual lldb::ByteOrder + GetByteOrder () const = 0; + + const ConstString & + GetTargetTriple () + { + return m_target_triple; + } + + const ABI * + GetABI (); + + virtual DynamicLoader * + GetDynamicLoader (); + + lldb::addr_t + GetSectionLoadAddress (const Section *section) const; + + bool + ResolveLoadAddress (lldb::addr_t load_addr, Address &so_addr) const; + + bool + SectionLoaded (const Section *section, lldb::addr_t load_addr); + + // The old load address should be specified when unloading to ensure we get + // the correct instance of the section as a shared library could be loaded + // at more than one location. + bool + SectionUnloaded (const Section *section, lldb::addr_t load_addr); + + // Unload all instances of a section. This function can be used on systems + // that don't support multiple copies of the same shared library to be + // loaded at the same time. + size_t + SectionUnloaded (const Section *section); + + bool + IsRunning () const; + + //------------------------------------------------------------------ + // lldb::ExecutionContextScope pure virtual functions + //------------------------------------------------------------------ + virtual Target * + CalculateTarget (); + + virtual Process * + CalculateProcess (); + + virtual Thread * + CalculateThread (); + + virtual StackFrame * + CalculateStackFrame (); + + virtual void + Calculate (ExecutionContext &exe_ctx); + + lldb::ProcessSP + GetSP (); + + ObjCObjectPrinter & + GetObjCObjectPrinter(); + +protected: + typedef ThreadSafeSTLMap<lldb::addr_t, const Section *> SectionLoadColl; + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + Target & m_target; ///< The target that owns this process. + SectionLoadColl m_section_load_info; ///< A mapping of all currently loaded sections. + ThreadSafeValue<lldb::StateType> m_public_state; + ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process + Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener. + Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread. + Listener m_private_state_listener; // This is the listener for the private state thread. + Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete. + lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events + uint32_t m_stop_id; ///< A count of many times the process has stopped. + uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. + int m_exit_status; ///< The exit status of the process, or -1 if not set. + std::string m_exit_string; ///< A textual description of why a process exited. + ThreadList m_thread_list; ///< The threads for this process. + std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver. + Listener &m_listener; + BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend + ///< to insert in the target. + UnixSignals m_unix_signals; /// This is the current signal set for this process. + ConstString m_target_triple; + lldb::ABISP m_abi_sp; + ObjCObjectPrinter m_objc_object_printer; + + size_t + RemoveBreakpointOpcodesFromBuffer (lldb::addr_t addr, size_t size, uint8_t *buf) const; + + void + SynchronouslyNotifyStateChanged (lldb::StateType state); + + void + SetPublicState (lldb::StateType new_state); + + void + SetPrivateState (lldb::StateType state); + + bool + StartPrivateStateThread (); + + void + StopPrivateStateThread (); + + void + PausePrivateStateThread (); + + void + ResumePrivateStateThread (); + + static void * + PrivateStateThread (void *arg); + + void * + RunPrivateStateThread (); + + void + HandlePrivateEvent (lldb::EventSP &event_sp); + + lldb::StateType + WaitForProcessStopPrivate (const TimeValue *timeout, lldb::EventSP &event_sp); + + Error + CompleteAttach (); + + + // This waits for both the state change broadcaster, and the control broadcaster. + // If control_only, it only waits for the control broadcaster. + + bool + WaitForEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp, bool control_only); + + lldb::StateType + WaitForStateChangedEventsPrivate (const TimeValue *timeout, lldb::EventSP &event_sp); + + lldb::StateType + WaitForState (const TimeValue *timeout, + const lldb::StateType *match_states, + const uint32_t num_match_states); + + size_t + WriteMemoryPrivate (lldb::addr_t addr, const void *buf, size_t size, Error &error); + +private: + //------------------------------------------------------------------ + // For Process only + //------------------------------------------------------------------ + void ControlPrivateStateThread (uint32_t signal); + DISALLOW_COPY_AND_ASSIGN (Process); + +}; + +} // namespace lldb_private + +#endif // liblldb_Process_h_ diff --git a/lldb/include/lldb/Target/RegisterContext.h b/lldb/include/lldb/Target/RegisterContext.h new file mode 100644 index 00000000000..5c646cf600b --- /dev/null +++ b/lldb/include/lldb/Target/RegisterContext.h @@ -0,0 +1,172 @@ +//===-- RegisterContext.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContext_h_ +#define liblldb_RegisterContext_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/ExecutionContextScope.h" + +namespace lldb_private { + +class RegisterContext : + public ExecutionContextScope +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + RegisterContext (Thread &thread, StackFrame *frame); + + virtual + ~RegisterContext (); + + //------------------------------------------------------------------ + // Subclasses must override these functions + //------------------------------------------------------------------ + virtual void + Invalidate () = 0; + + virtual size_t + GetRegisterCount () = 0; + + virtual const lldb::RegisterInfo * + GetRegisterInfoAtIndex (uint32_t reg) = 0; + + virtual size_t + GetRegisterSetCount () = 0; + + virtual const lldb::RegisterSet * + GetRegisterSet (uint32_t reg_set) = 0; + + virtual bool + ReadRegisterValue (uint32_t reg, Scalar &value) = 0; + + virtual bool + ReadRegisterBytes (uint32_t reg, DataExtractor &data) = 0; + + virtual bool + ReadAllRegisterValues (lldb::DataBufferSP &data_sp) = 0; + + virtual bool + WriteRegisterValue (uint32_t reg, const Scalar &value) = 0; + + virtual bool + WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset = 0) = 0; + + virtual bool + WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) = 0; + + virtual uint32_t + ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) = 0; + + //------------------------------------------------------------------ + // Subclasses can override these functions if desired + //------------------------------------------------------------------ + virtual uint32_t + NumSupportedHardwareBreakpoints (); + + virtual uint32_t + SetHardwareBreakpoint (lldb::addr_t addr, size_t size); + + virtual bool + ClearHardwareBreakpoint (uint32_t hw_idx); + + virtual uint32_t + NumSupportedHardwareWatchpoints (); + + virtual uint32_t + SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write); + + virtual bool + ClearHardwareWatchpoint (uint32_t hw_index); + + virtual bool + HardwareSingleStep (bool enable); + + //------------------------------------------------------------------ + // Subclasses should not override these + //------------------------------------------------------------------ + lldb::tid_t + GetThreadID() const; + + const lldb::RegisterInfo * + GetRegisterInfoByName (const char *reg_name, uint32_t start_idx = 0); + + uint64_t + GetPC (uint64_t fail_value = LLDB_INVALID_ADDRESS); + + bool + SetPC (uint64_t pc); + + uint64_t + GetSP (uint64_t fail_value = LLDB_INVALID_ADDRESS); + + bool + SetSP (uint64_t sp); + + uint64_t + GetFP (uint64_t fail_value = LLDB_INVALID_ADDRESS); + + bool + SetFP (uint64_t fp); + + const char * + GetRegisterName (uint32_t reg); + + uint64_t + GetReturnAddress (uint64_t fail_value = LLDB_INVALID_ADDRESS); + + uint64_t + GetFlags (uint64_t fail_value = 0); + + uint64_t + ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value); + + bool + WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval); + + //------------------------------------------------------------------ + // lldb::ExecutionContextScope pure virtual functions + //------------------------------------------------------------------ + virtual Target * + CalculateTarget (); + + virtual Process * + CalculateProcess (); + + virtual Thread * + CalculateThread (); + + virtual StackFrame * + CalculateStackFrame (); + + virtual void + Calculate (ExecutionContext &exe_ctx); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from RegisterContext can see and modify these + //------------------------------------------------------------------ + Thread &m_thread; // The thread that this register context belongs to. + StackFrame *m_frame; // The stack frame for this context, or NULL if this is the root context +private: + //------------------------------------------------------------------ + // For RegisterContext only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (RegisterContext); +}; + +} // namespace lldb_private + +#endif // liblldb_RegisterContext_h_ diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h new file mode 100644 index 00000000000..0c46ec278eb --- /dev/null +++ b/lldb/include/lldb/Target/StackFrame.h @@ -0,0 +1,126 @@ +//===-- StackFrame.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StackFrame_h_ +#define liblldb_StackFrame_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Error.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/UserID.h" +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/StackID.h" + +namespace lldb_private { + +class StackFrame : + public UserID, + public ExecutionContextScope +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr = NULL); + StackFrame (lldb::user_id_t frame_idx, Thread &thread, lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr = NULL); + virtual ~StackFrame (); + + Thread & + GetThread() + { return m_thread; } + + const Thread & + GetThread() const + { return m_thread; } + + StackID& + GetStackID(); + + Address& + GetPC(); + + void + ChangePC (lldb::addr_t pc); + + const SymbolContext& + GetSymbolContext (uint32_t resolve_scope); + + bool + GetFrameBaseValue(Scalar &value, Error *error_ptr); + + RegisterContext * + GetRegisterContext (); + + VariableList * + GetVariableList (); + + bool + HasDebugInformation (); + + ValueObjectList & + GetValueObjectList(); + + const char * + Disassemble (); + + void + Dump (Stream *strm, bool show_frame_index); + + //------------------------------------------------------------------ + // lldb::ExecutionContextScope pure virtual functions + //------------------------------------------------------------------ + virtual Target * + CalculateTarget (); + + virtual Process * + CalculateProcess (); + + virtual Thread * + CalculateThread (); + + virtual StackFrame * + CalculateStackFrame (); + + virtual void + Calculate (ExecutionContext &exe_ctx); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from StackFrame can see and modify these + //------------------------------------------------------------------ + + +private: + //------------------------------------------------------------------ + // For StackFrame only + //------------------------------------------------------------------ + Thread &m_thread; + lldb::RegisterContextSP m_reg_context_sp; + StackID m_id; + Address m_pc; // PC as a section/offset address + SymbolContext m_sc; + Flags m_flags; + Scalar m_frame_base; + Error m_frame_base_error; + lldb::VariableListSP m_variable_list_sp; + ValueObjectList m_value_object_list; + StreamString m_disassembly; + DISALLOW_COPY_AND_ASSIGN (StackFrame); +}; + +} // namespace lldb_private + +#endif // liblldb_StackFrame_h_ diff --git a/lldb/include/lldb/Target/StackFrameList.h b/lldb/include/lldb/Target/StackFrameList.h new file mode 100644 index 00000000000..678bff5a3d8 --- /dev/null +++ b/lldb/include/lldb/Target/StackFrameList.h @@ -0,0 +1,88 @@ +//===-- StackFrameList.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StackFrameList_h_ +#define liblldb_StackFrameList_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/Host/Mutex.h" +#include "lldb/Target/StackFrame.h" + +namespace lldb_private { + +class StackFrameList +{ +public: + friend class Thread; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StackFrameList(); + + virtual + ~StackFrameList(); + + uint32_t + GetNumFrames() const; + + lldb::StackFrameSP + GetFrameAtIndex (uint32_t idx) const; + + bool + SetFrameAtIndex (uint32_t idx, lldb::StackFrameSP &frame_sp); + + // Mark a stack frame as the current frame + uint32_t + SetCurrentFrame (lldb_private::StackFrame *frame); + + uint32_t + GetCurrentFrameIndex () const; + + // Mark a stack frame as the current frame using the frame index + void + SetCurrentFrameByIndex (uint32_t idx); + + void + Clear (); + + // After we have determined the number of frames, we can set the count here + // and have the frame info be generated on demand. + void + SetNumFrames(uint32_t count); + + void + InvalidateFrames (uint32_t start_idx); +protected: + + //------------------------------------------------------------------ + // Classes that inherit from StackFrameList can see and modify these + //------------------------------------------------------------------ + typedef std::vector<lldb::StackFrameSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + mutable Mutex m_mutex; + collection m_frames; + uint32_t m_current_frame_idx; + +private: + //------------------------------------------------------------------ + // For StackFrameList only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (StackFrameList); +}; + +} // namespace lldb_private + +#endif // liblldb_StackFrameList_h_ diff --git a/lldb/include/lldb/Target/StackID.h b/lldb/include/lldb/Target/StackID.h new file mode 100644 index 00000000000..cf02be1c925 --- /dev/null +++ b/lldb/include/lldb/Target/StackID.h @@ -0,0 +1,65 @@ +//===-- StackID.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StackID_h_ +#define liblldb_StackID_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" + +namespace lldb_private { + +class StackID +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StackID (); + explicit StackID (lldb::addr_t cfa); + StackID (const Address& start_address, lldb::addr_t cfa); + StackID (const StackID& rhs); + virtual ~StackID(); + + const Address& + GetStartAddress() const; + + void + SetStartAddress(const Address& start_address); + + lldb::addr_t + GetCallFrameAddress() const; + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const StackID& + operator=(const StackID& rhs); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from StackID can see and modify these + //------------------------------------------------------------------ + Address m_start_address; // The address range for the function for this frame + lldb::addr_t m_cfa; // The call frame address (stack pointer) value + // at the beginning of the function that uniquely + // identifies this frame +}; + +bool operator== (const StackID& lhs, const StackID& rhs); +bool operator!= (const StackID& lhs, const StackID& rhs); +bool operator< (const StackID& lhs, const StackID& rhs); + +} // namespace lldb_private + +#endif // liblldb_StackID_h_ diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h new file mode 100644 index 00000000000..0f9fd09b985 --- /dev/null +++ b/lldb/include/lldb/Target/Target.h @@ -0,0 +1,324 @@ +//===-- Target.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Target_h_ +#define liblldb_Target_h_ + +// C Includes +// C++ Includes + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Breakpoint/BreakpointList.h" +#include "lldb/Breakpoint/BreakpointLocationCollection.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Event.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/ABI.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/PathMappingList.h" + +#include "lldb/API/SBTarget.h" + +namespace lldb_private { + +class Target : + public Broadcaster, + public ExecutionContextScope +{ +public: + friend class TargetList; + + //------------------------------------------------------------------ + /// Broadcaster event bits definitions. + //------------------------------------------------------------------ + enum + { + eBroadcastBitBreakpointChanged = (1 << 0), + eBroadcastBitModulesLoaded = (1 << 1), + eBroadcastBitModulesUnloaded = (1 << 2) + }; + + lldb::ModuleSP + GetSharedModule (const FileSpec& file_spec, + const ArchSpec& arch, + const UUID *uuid = NULL, + const ConstString *object_name = NULL, + off_t object_offset = 0, + Error *error_ptr = NULL); +private: + //------------------------------------------------------------------ + /// Construct with optional file and arch. + /// + /// This member is private. Clients must use + /// TargetList::CreateTarget(const FileSpec*, const ArchSpec*) + /// so all targets can be tracked from the central target list. + /// + /// @see TargetList::CreateTarget(const FileSpec*, const ArchSpec*) + //------------------------------------------------------------------ + Target(); + +public: + ~Target(); + + void + DeleteCurrentProcess (); + + //------------------------------------------------------------------ + /// Dump a description of this object to a Stream. + /// + /// Dump a description of the contents of this object to the + /// supplied stream \a s. The dumped content will be only what has + /// been loaded or parsed up to this point at which this function + /// is called, so this is a good way to see what has been parsed + /// in a target. + /// + /// @param[in] s + /// The stream to which to dump the object descripton. + //------------------------------------------------------------------ + void + Dump (Stream *s); + + const lldb::ProcessSP & + CreateProcess (Listener &listener, const char *plugin_name = NULL); + + const lldb::ProcessSP & + GetProcessSP () const; + + lldb::TargetSP + GetSP(); + + + //------------------------------------------------------------------ + // This part handles the breakpoints. + //------------------------------------------------------------------ + + BreakpointList & + GetBreakpointList(bool internal = false); + + const BreakpointList & + GetBreakpointList(bool internal = false) const; + + lldb::BreakpointSP + GetBreakpointByID (lldb::break_id_t break_id); + + // Use this to create a file and line breakpoint to a given module or all module it is NULL + lldb::BreakpointSP + CreateBreakpoint (const FileSpec *containingModule, + const FileSpec &file, + uint32_t line_no, + bool check_inlines, + bool internal = false); + + // Use this to create a breakpoint from a load address + lldb::BreakpointSP + CreateBreakpoint (lldb::addr_t load_addr, + bool internal = false); + + // Use this to create Address breakpoints: + lldb::BreakpointSP + CreateBreakpoint (Address &addr, + bool internal = false); + + // Use this to create a function breakpoint by regexp in containingModule, or all modules if it is NULL + lldb::BreakpointSP + CreateBreakpoint (FileSpec *containingModule, + RegularExpression &func_regexp, + bool internal = false); + + // Use this to create a function breakpoint by name in containingModule, or all modules if it is NULL + lldb::BreakpointSP + CreateBreakpoint (FileSpec *containingModule, + const char *func_name, + bool internal = false); + + // Use this to create a general breakpoint: + lldb::BreakpointSP + CreateBreakpoint (lldb::SearchFilterSP &filter_sp, + lldb::BreakpointResolverSP &resolver_sp, + bool internal = false); + + void + RemoveAllBreakpoints (bool internal_also = false); + + void + DisableAllBreakpoints (bool internal_also = false); + + void + EnableAllBreakpoints (bool internal_also = false); + + bool + DisableBreakpointByID (lldb::break_id_t break_id); + + bool + EnableBreakpointByID (lldb::break_id_t break_id); + + bool + RemoveBreakpointByID (lldb::break_id_t break_id); + + void + ModulesDidLoad (ModuleList &module_list); + + void + ModulesDidUnload (ModuleList &module_list); + +protected: + void + ModuleAdded (lldb::ModuleSP &module_sp); + + void + ModuleUpdated (lldb::ModuleSP &old_module_sp, lldb::ModuleSP &new_module_sp); + +public: + //------------------------------------------------------------------ + /// Gets the module for the main executable. + /// + /// Each process has a notion of a main executable that is the file + /// that will be executed or attached to. Executable files can have + /// dependent modules that are discovered from the object files, or + /// discovered at runtime as things are dynamically loaded. + /// + /// @return + /// The shared pointer to the executable module which can + /// contains a NULL Module object if no executable has been + /// set. + /// + /// @see DynamicLoader + /// @see ObjectFile::GetDependentModules (FileSpecList&) + /// @see Process::SetExecutableModule(lldb::ModuleSP&) + //------------------------------------------------------------------ + lldb::ModuleSP + GetExecutableModule (); + + //------------------------------------------------------------------ + /// Set the main executable module. + /// + /// Each process has a notion of a main executable that is the file + /// that will be executed or attached to. Executable files can have + /// dependent modules that are discovered from the object files, or + /// discovered at runtime as things are dynamically loaded. + /// + /// Setting the executable causes any of the current dependant + /// image information to be cleared and replaced with the static + /// dependent image information found by calling + /// ObjectFile::GetDependentModules (FileSpecList&) on the main + /// executable and any modules on which it depends. Calling + /// Process::GetImages() will return the newly found images that + /// were obtained from all of the object files. + /// + /// @param[in] module_sp + /// A shared pointer reference to the module that will become + /// the main executable for this process. + /// + /// @param[in] get_dependent_files + /// If \b true then ask the object files to track down any + /// known dependent files. + /// + /// @see ObjectFile::GetDependentModules (FileSpecList&) + /// @see Process::GetImages() + //------------------------------------------------------------------ + void + SetExecutableModule (lldb::ModuleSP& module_sp, bool get_dependent_files); + + //------------------------------------------------------------------ + /// Get accessor for the images for this process. + /// + /// Each process has a notion of a main executable that is the file + /// that will be executed or attached to. Executable files can have + /// dependent modules that are discovered from the object files, or + /// discovered at runtime as things are dynamically loaded. After + /// a main executable has been set, the images will contain a list + /// of all the files that the executable depends upon as far as the + /// object files know. These images will usually contain valid file + /// virtual addresses only. When the process is launched or attached + /// to, the DynamicLoader plug-in will discover where these images + /// were loaded in memory and will resolve the load virtual + /// addresses is each image, and also in images that are loaded by + /// code. + /// + /// @return + /// A list of Module objects in a module list. + //------------------------------------------------------------------ + ModuleList& + GetImages (); + + ArchSpec + GetArchitecture () const; + + bool + GetTargetTriple (ConstString &target_triple); + + size_t + ReadMemory (lldb::AddressType addr_type, + lldb::addr_t addr, + void *buf, + size_t size, + Error &error, + ObjectFile* objfile = NULL); + + //------------------------------------------------------------------ + // lldb::ExecutionContextScope pure virtual functions + //------------------------------------------------------------------ + virtual Target * + CalculateTarget (); + + virtual Process * + CalculateProcess (); + + virtual Thread * + CalculateThread (); + + virtual StackFrame * + CalculateStackFrame (); + + virtual void + Calculate (ExecutionContext &exe_ctx); + + PathMappingList & + GetImageSearchPathList (); + + ClangASTContext * + GetScratchClangASTContext(); + +protected: + friend class lldb::SBTarget; + + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded). + BreakpointList m_breakpoint_list; + BreakpointList m_internal_breakpoint_list; + // We want to tightly control the process destruction process so + // we can correctly tear down everything that we need to, so the only + // class that knows about the process lifespan is this target class. + lldb::ProcessSP m_process_sp; + ConstString m_triple; ///< The target triple ("x86_64-apple-darwin10") + lldb::SearchFilterSP m_search_filter_sp; + PathMappingList m_image_search_paths; + std::auto_ptr<ClangASTContext> m_scratch_ast_context_ap; + //------------------------------------------------------------------ + // Methods. + //------------------------------------------------------------------ + lldb::SearchFilterSP + GetSearchFilterForModule (const FileSpec *containingModule); + + static void + ImageSearchPathsChanged (const PathMappingList &path_list, + void *baton); + +private: + DISALLOW_COPY_AND_ASSIGN (Target); +}; + +} // namespace lldb_private + +#endif // liblldb_Target_h_ diff --git a/lldb/include/lldb/Target/TargetList.h b/lldb/include/lldb/Target/TargetList.h new file mode 100644 index 00000000000..8cd7b7b971d --- /dev/null +++ b/lldb/include/lldb/Target/TargetList.h @@ -0,0 +1,206 @@ +//===-- TargetList.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TargetList_h_ +#define liblldb_TargetList_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Broadcaster.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Target/Target.h" + +namespace lldb_private { + +class TargetList : public Broadcaster +{ +private: + friend class Debugger; + + //------------------------------------------------------------------ + /// Constructor + /// + /// The constructor for the target list is private. Clients can + /// get ahold of of the one and only target list through the + /// lldb_private::Debugger::GetSharedInstance().GetTargetList(). + /// + /// @see static TargetList& lldb_private::Debugger::GetTargetList(). + //------------------------------------------------------------------ + TargetList(); + +public: + + //------------------------------------------------------------------ + /// Broadcaster event bits definitions. + //------------------------------------------------------------------ + enum + { + eBroadcastBitInterrupt = (1 << 0) + }; + + + ~TargetList(); + + //------------------------------------------------------------------ + /// Create a new Target. + /// + /// Clients must use this function to create a Target. This allows + /// a global list of targets to be maintained in a central location + /// so signal handlers and other global functions can use it to + /// locate an appropriate target to deliver asynchronous information + /// to. + /// + /// @param[in] file_spec + /// The main executable file for a debug target. This value + /// can be NULL and the file can be set later using: + /// Target::SetExecutableModule (ModuleSP&) + /// + /// @param[in] arch + /// The architecture to use when launching the \a file_spec for + /// debugging. This can be NULL if the architecture is not known + /// or when attaching to a process. + /// + /// @param[in] uuid_ptr + /// An optional UUID to use when loading a target. When this is + /// specified, plug-ins might be able to track down a different + /// executable than the one on disk specified by "file_spec" in + /// an alternate SDK or build location (such as when doing + /// symbolication on non-native OS builds). + /// + /// @return + /// A shared pointer to a target object. + //------------------------------------------------------------------ + Error + CreateTarget (const FileSpec& file_spec, + const ArchSpec& arch, + const UUID *uuid_ptr, + bool get_dependent_files, + lldb::TargetSP &target_sp); + + //------------------------------------------------------------------ + /// Delete a Target object from the list. + /// + /// When clients are done with the Target objets, this function + /// should be called to release the memory associated with a target + /// object. + /// + /// @param[in] target_sp + /// The shared pointer to a target. + /// + /// @return + /// Returns \b true if the target was successfully removed from + /// from this target list, \b false otherwise. The client will + /// be left with the last remaining shared pointer to the target + /// in \a target_sp which can then be properly released. + //------------------------------------------------------------------ + bool + DeleteTarget (lldb::TargetSP &target_sp); + + int + GetNumTargets () const; + + lldb::TargetSP + GetTargetAtIndex (uint32_t index) const; + + //------------------------------------------------------------------ + /// Find the target that contains has an executable whose path + /// matches \a exe_file_spec, and whose architecture matches + /// \a arch_ptr if arch_ptr is not NULL. + /// + /// @param[in] exe_file_spec + /// A file spec containing a basename, or a full path (directory + /// and basename). If \a exe_file_spec contains only a filename + /// (empty GetDirectory() value) then matching will be done + /// solely based on the filenames and directories won't be + /// compared. If \a exe_file_spec contains a filename and a + /// directory, then both must match. + /// + /// @param[in] exe_arch_ptr + /// If not NULL then the architecture also needs to match, else + /// the architectures will be compared. + /// + /// @return + /// A shared pointer to a target object. The returned shared + /// pointer will contain NULL if no target objects have a + /// executable whose full or partial path matches + /// with a matching process ID. + //------------------------------------------------------------------ + lldb::TargetSP + FindTargetWithExecutableAndArchitecture (const FileSpec &exe_file_spec, + const ArchSpec *exe_arch_ptr = NULL) const; + + //------------------------------------------------------------------ + /// Find the target that contains a process with process ID \a + /// pid. + /// + /// @param[in] pid + /// The process ID to search our target list for. + /// + /// @return + /// A shared pointer to a target object. The returned shared + /// pointer will contain NULL if no target objects own a process + /// with a matching process ID. + //------------------------------------------------------------------ + lldb::TargetSP + FindTargetWithProcessID (lldb::pid_t pid) const; + + lldb::TargetSP + FindTargetWithProcess (lldb_private::Process *process) const; + + lldb::TargetSP + GetTargetSP (Target *target) const; + + //------------------------------------------------------------------ + /// Send an async interrupt to one or all processes. + /// + /// Find the target that contains the process with process ID \a + /// pid and send a LLDB_EVENT_ASYNC_INTERRUPT event to the process's + /// event queue. + /// + /// @param[in] pid + /// The process ID to search our target list for, if \a pid is + /// LLDB_INVALID_PROCESS_ID, then the interrupt will be sent to + /// all processes. + /// + /// @return + /// The number of async interrupts sent. + //------------------------------------------------------------------ + uint32_t + SendAsyncInterrupt (lldb::pid_t pid = LLDB_INVALID_PROCESS_ID); + + uint32_t + SignalIfRunning (lldb::pid_t pid, int signo); + + uint32_t + SetCurrentTarget (Target *target); + + void + SetCurrentTargetWithIndex (uint32_t idx); + + lldb::TargetSP + GetCurrentTarget (); + + +protected: + typedef std::vector<lldb::TargetSP> collection; + //------------------------------------------------------------------ + // Member variables. + //------------------------------------------------------------------ + collection m_target_list; + mutable Mutex m_target_list_mutex; + uint32_t m_current_target_idx; +private: + DISALLOW_COPY_AND_ASSIGN (TargetList); +}; + +} // namespace lldb_private + +#endif // liblldb_TargetList_h_ diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h new file mode 100644 index 00000000000..cc5dcf89db0 --- /dev/null +++ b/lldb/include/lldb/Target/Thread.h @@ -0,0 +1,701 @@ +//===-- Thread.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Thread_h_ +#define liblldb_Thread_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Core/UserID.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/StackFrameList.h" + +#define LLDB_THREAD_MAX_STOP_EXC_DATA 8 + +// I forward declare these here so I don't have to #include ThreadPlan, so in turn I +// can use Thread.h in ThreadPlan.h. + +namespace lldb_private { + +class Thread : + public UserID, + public ExecutionContextScope +{ +friend class ThreadPlan; +public: + //---------------------------------------------------------------------- + // StopInfo + // + // Describes the reason the thread it was created with stopped. + //---------------------------------------------------------------------- + class StopInfo + { + public: + StopInfo(Thread *thread = NULL); + + ~StopInfo(); + + // Clear clears the stop reason, but it does not clear the thread this + // StopInfo is tied to. + void + Clear(); + + lldb::StopReason + GetStopReason() const; + + void + SetThread (Thread *thread); + + Thread * + GetThread (); + + void + SetStopReasonWithBreakpointSiteID (lldb::user_id_t break_id); + + void + SetStopReasonWithWatchpointID (lldb::user_id_t watch_id); + + void + SetStopReasonWithSignal (int signo); + + void + SetStopReasonToTrace (); + + void + SetStopReasonWithException (uint32_t exc_type, size_t exc_data_count); + + void + SetStopReasonWithPlan (lldb::ThreadPlanSP &plan); + + void + SetStopReasonToNone (); + + const char * + GetStopDescription() const; + + void + SetStopDescription(const char *desc); + + lldb::user_id_t + GetBreakpointSiteID() const; + + lldb::user_id_t + GetWatchpointID() const; + + int + GetSignal() const; + + lldb::user_id_t + GetPlanID () const; + + uint32_t + GetExceptionType() const; + + size_t + GetExceptionDataCount() const; + + lldb::addr_t + GetExceptionDataAtIndex (uint32_t idx) const; + + bool + SetExceptionDataAtIndex (uint32_t idx, lldb::addr_t data); + + void + Dump (Stream *s) const; + + protected: + lldb::StopReason m_reason; + //-------------------------------------------------------------- + // For eStopReasonPlan the completed plan is stored in this shared pointer. + //-------------------------------------------------------------- + lldb::ThreadPlanSP m_completed_plan_sp; + Thread *m_thread; + char m_description[256]; + union + { + //-------------------------------------------------------------- + // eStopReasonBreakpoint + //-------------------------------------------------------------- + struct + { + lldb::user_id_t bp_site_id; + } breakpoint; + //-------------------------------------------------------------- + // eStopReasonWatchpoint + //-------------------------------------------------------------- + struct + { + lldb::user_id_t watch_id; + } watchpoint; + //-------------------------------------------------------------- + // eStopReasonSignal + //-------------------------------------------------------------- + struct + { + int signo; + } signal; + //-------------------------------------------------------------- + // eStopReasonException + //-------------------------------------------------------------- + struct + { + uint32_t type; + size_t data_count; + lldb::addr_t data[LLDB_THREAD_MAX_STOP_EXC_DATA]; + } exception; + } m_details; + }; + + class RegisterCheckpoint + { + public: + + RegisterCheckpoint() : + m_stack_id (), + m_data_sp () + { + } + + RegisterCheckpoint (const StackID &stack_id) : + m_stack_id (stack_id), + m_data_sp () + { + } + + ~RegisterCheckpoint() + { + } + + const StackID & + GetStackID() + { + return m_stack_id; + } + + void + SetStackID (const StackID &stack_id) + { + m_stack_id = stack_id; + } + + lldb::DataBufferSP & + GetData() + { + return m_data_sp; + } + + const lldb::DataBufferSP & + GetData() const + { + return m_data_sp; + } + + protected: + StackID m_stack_id; + lldb::DataBufferSP m_data_sp; + }; + + Thread (Process &process, lldb::tid_t tid); + virtual ~Thread(); + + Process & + GetProcess() { return m_process; } + + const Process & + GetProcess() const { return m_process; } + + int + GetResumeSignal () const; + + void + SetResumeSignal (int signal); + + lldb::StateType + GetState() const; + + lldb::ThreadSP + GetSP (); + + void + SetState (lldb::StateType state); + + lldb::StateType + GetResumeState () const; + + void + SetResumeState (lldb::StateType state); + + // This function is called on all the threads before "WillResume" in case + // a thread needs to change its state before the ThreadList polls all the + // threads to figure out which ones actually will get to run and how. + void + SetupForResume (); + + // Override this to do platform specific tasks before resume, but always + // call the Thread::WillResume at the end of your work. + + virtual bool + WillResume (lldb::StateType resume_state); + + // This clears generic thread state after a resume. If you subclass this, + // be sure to call it. + virtual void + DidResume (); + + virtual void + RefreshStateAfterStop() = 0; + + void + WillStop (); + + bool + ShouldStop (Event *event_ptr); + + lldb::Vote + ShouldReportStop (Event *event_ptr); + + lldb::Vote + ShouldReportRun (Event *event_ptr); + + bool + GetStopInfo (StopInfo *stop_info); + + bool + ThreadStoppedForAReason (); + + virtual const char * + GetInfo () = 0; + + virtual const char * + GetName () + { + return NULL; + } + + virtual const char * + GetQueueName () + { + return NULL; + } + + virtual uint32_t + GetStackFrameCount() = 0; + + virtual lldb::StackFrameSP + GetStackFrameAtIndex (uint32_t idx) = 0; + + lldb::StackFrameSP + GetCurrentFrame (); + + uint32_t + SetCurrentFrame (lldb_private::StackFrame *frame); + + void + SetCurrentFrameByIndex (uint32_t frame_idx); + + virtual RegisterContext * + GetRegisterContext () = 0; + + virtual bool + SaveFrameZeroState (RegisterCheckpoint &checkpoint) = 0; + + virtual bool + RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) = 0; + + virtual RegisterContext * + CreateRegisterContextForFrame (StackFrame *frame) = 0; + + virtual void + ClearStackFrames () + { + m_frames.Clear(); + } + + void + DumpInfo (Stream &strm, + bool show_stop_reason, + bool show_name, + bool show_queue, + uint32_t frame_idx);// = UINT32_MAX); + + //------------------------------------------------------------------ + // Thread Plan Providers: + // This section provides the basic thread plans that the Process control + // machinery uses to run the target. ThreadPlan.h provides more details on + // how this mechanism works. + // The thread provides accessors to a set of plans that perform basic operations. + // The idea is that particular Platform plugins can override these methods to + // provide the implementation of these basic operations appropriate to their + // environment. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Queues the base plan for a thread. + /// The version returned by Process does some things that are useful, + /// like handle breakpoints and signals, so if you return a plugin specific + /// one you probably want to call through to the Process one for anything + /// your plugin doesn't explicitly handle. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueFundamentalPlan (bool abort_other_plans); + + //------------------------------------------------------------------ + /// Queues the plan used to step over a breakpoint at the current PC of \a thread. + /// The default version returned by Process handles trap based breakpoints, and + /// will disable the breakpoint, single step over it, then re-enable it. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans); + + //------------------------------------------------------------------ + /// Queues the plan used to step one instruction from the current PC of \a thread. + /// + /// @param[in] step_over + /// \b true if we step over calls to functions, false if we step in. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForStepSingleInstruction (bool step_over, + bool abort_other_plans, + bool stop_other_threads); + + //------------------------------------------------------------------ + /// Queues the plan used to step through an address range, stepping into or over + /// function calls depending on the value of StepType. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] type + /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported by this plan. + /// + /// @param[in] range + /// The address range to step through. + /// + /// @param[in] addr_context + /// When dealing with stepping through inlined functions the current PC is not enough information to know + /// what "step" means. For instance a series of nested inline functions might start at the same address. + // The \a addr_context provides the current symbol context the step + /// is supposed to be out of. + // FIXME: Currently unused. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForStepRange (bool abort_other_plans, + lldb::StepType type, + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_other_threads); + + //------------------------------------------------------------------ + /// Queue the plan used to step out of the function at the current PC of + /// \a thread. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] addr_context + /// When dealing with stepping through inlined functions the current PC is not enough information to know + /// what "step" means. For instance a series of nested inline functions might start at the same address. + // The \a addr_context provides the current symbol context the step + /// is supposed to be out of. + // FIXME: Currently unused. + /// + /// @param[in] first_insn + /// \b true if this is the first instruction of a function. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @param[in] stop_vote + /// @param[in] run_vote + /// See standard meanings for the stop & run votes in ThreadPlan.h. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForStepOut (bool abort_other_plans, + SymbolContext *addr_context, + bool first_insn, + bool stop_other_threads, + lldb::Vote stop_vote = lldb::eVoteYes, + lldb::Vote run_vote = lldb::eVoteNoOpinion); + + //------------------------------------------------------------------ + /// Gets the plan used to step through the code that steps from a function + /// call site at the current PC into the actual function call. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForStepThrough (bool abort_other_plans, + bool stop_other_threads); + + //------------------------------------------------------------------ + /// Gets the plan used to continue from the current PC. + /// This is a simple plan, mostly useful as a backstop when you are continuing + /// for some particular purpose. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @param[in] stop_vote + /// @param[in] run_vote + /// See standard meanings for the stop & run votes in ThreadPlan.h. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForContinue (bool abort_other_plans, + bool stop_other_threads, + lldb::Vote stop_vote, + lldb::Vote run_vote = lldb::eVoteNoOpinion, + bool immediate = false); + //------------------------------------------------------------------ + /// Gets the plan used to continue from the current PC. + /// This is a simple plan, mostly useful as a backstop when you are continuing + /// for some particular purpose. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @param[in] target_addr + /// The address to which we're running. + /// + /// @param[in] stop_other_threads + /// \b true if we will stop other threads while we single step this one. + /// + /// @return + /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued. + //------------------------------------------------------------------ + virtual ThreadPlan * + QueueThreadPlanForRunToAddress (bool abort_other_plans, + Address &target_addr, + bool stop_other_threads); + + virtual ThreadPlan * + QueueThreadPlanForStepUntil (bool abort_other_plans, + lldb::addr_t *address_list, + size_t num_addresses, + bool stop_others); + + virtual ThreadPlan * + QueueThreadPlanForCallFunction (bool abort_other_plans, + Address& function, + lldb::addr_t arg, + bool stop_other_threads, + bool discard_on_error = false); + + virtual ThreadPlan * + QueueThreadPlanForCallFunction (bool abort_other_plans, + Address& function, + ValueList &args, + bool stop_other_threads, + bool discard_on_error = false); + + //------------------------------------------------------------------ + // Thread Plan accessors: + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Gets the plan which will execute next on the plan stack. + /// + /// @return + /// A pointer to the next executed plan. + //------------------------------------------------------------------ + ThreadPlan * + GetCurrentPlan (); + + //------------------------------------------------------------------ + /// Gets the inner-most plan that was popped off the plan stack in the + /// most recent stop. Useful for printing the stop reason accurately. + /// + /// @return + /// A pointer to the last completed plan. + //------------------------------------------------------------------ + lldb::ThreadPlanSP + GetCompletedPlan (); + + //------------------------------------------------------------------ + /// Checks whether the given plan is in the completed plans for this + /// stop. + /// + /// @param[in] plan + /// Pointer to the plan you're checking. + /// + /// @return + /// Returns true if the input plan is in the completed plan stack, + /// false otherwise. + //------------------------------------------------------------------ + bool + IsThreadPlanDone (ThreadPlan *plan); + + //------------------------------------------------------------------ + /// Checks whether the given plan is in the discarded plans for this + /// stop. + /// + /// @param[in] plan + /// Pointer to the plan you're checking. + /// + /// @return + /// Returns true if the input plan is in the discarded plan stack, + /// false otherwise. + //------------------------------------------------------------------ + bool + WasThreadPlanDiscarded (ThreadPlan *plan); + + //------------------------------------------------------------------ + /// Queues a generic thread plan. + /// + /// @param[in] plan_sp + /// The plan to queue. + /// + /// @param[in] abort_other_plans + /// \b true if we discard the currently queued plans and replace them with this one. + /// Otherwise this plan will go on the end of the plan stack. + /// + /// @return + /// A pointer to the last completed plan. + //------------------------------------------------------------------ + void + QueueThreadPlan (lldb::ThreadPlanSP &plan_sp, bool abort_other_plans); + + + //------------------------------------------------------------------ + /// Discards the plans queued on the plan stack of the current thread. This is + /// arbitrated by the "Master" ThreadPlans, using the "OkayToDiscard" call. + // But if \a force is true, all thread plans are discarded. + //------------------------------------------------------------------ + void + DiscardThreadPlans (bool force); + + //------------------------------------------------------------------ + /// Prints the current plan stack. + /// + /// @param[in] s + /// The stream to which to dump the plan stack info. + /// + //------------------------------------------------------------------ + void + DumpThreadPlans (Stream *s) const; + + // Get the thread index ID. The index ID that is guaranteed to not be + // re-used by a process. They start at 1 and increase with each new thread. + // This allows easy command line access by a unique ID that is easier to + // type than the actual system thread ID. + uint32_t + GetIndexID () const; + + //------------------------------------------------------------------ + // lldb::ExecutionContextScope pure virtual functions + //------------------------------------------------------------------ + virtual Target * + CalculateTarget (); + + virtual Process * + CalculateProcess (); + + virtual Thread * + CalculateThread (); + + virtual StackFrame * + CalculateStackFrame (); + + virtual void + Calculate (ExecutionContext &exe_ctx); + +protected: + void + PushPlan (lldb::ThreadPlanSP &plan_sp); + + void + PopPlan (); + + void + DiscardPlan (); + + ThreadPlan *GetPreviousPlan (ThreadPlan *plan); + + virtual bool + GetRawStopReason (StopInfo *stop_info) = 0; + + typedef std::vector<lldb::ThreadPlanSP> plan_stack; + + //------------------------------------------------------------------ + // Classes that inherit from Process can see and modify these + //------------------------------------------------------------------ + Process & m_process; ///< The process that owns this thread. + const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access. + lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state. + lldb::StateType m_state; ///< The state of our process. + plan_stack m_plan_stack; ///< The stack of plans this thread is executing. + plan_stack m_immediate_plan_stack; ///< The plans that need to get executed before any other work gets done. + plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. + plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. + mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. + StackFrameList m_frames; ///< The stack frames that get lazily populated after a thread stops. + uint32_t m_current_frame_idx;///< The current frame for this thread + int m_resume_signal; ///< The signal that should be used when continuing this thread. + lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. +private: + //------------------------------------------------------------------ + // For Thread only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (Thread); + +}; + +} // namespace lldb_private + +#endif // liblldb_Thread_h_ diff --git a/lldb/include/lldb/Target/ThreadList.h b/lldb/include/lldb/Target/ThreadList.h new file mode 100644 index 00000000000..4f82cc7ca65 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadList.h @@ -0,0 +1,120 @@ +//===-- ThreadList.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadList_h_ +#define liblldb_ThreadList_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Core/UserID.h" + + +// FIXME: Currently this is a thread list with lots of functionality for use only by +// the process for which this is the thread list. If we ever want a container class +// to hand out that is just a random subset of threads, with iterator functionality, +// then we should make that part a base class, and make a ProcessThreadList for the +// process. +namespace lldb_private { + +class ThreadList +{ +friend class Process; + +public: + + ThreadList (Process *process); + + ThreadList (const ThreadList &rhs); + + ~ThreadList (); + + const ThreadList& + operator = (const ThreadList& rhs); + + uint32_t + GetSize(bool can_update = true); + + void + AddThread (lldb::ThreadSP &thread_sp); + + lldb::ThreadSP + GetCurrentThread (); + + bool + SetCurrentThreadByID (lldb::tid_t tid); + + bool + SetCurrentThreadByIndexID (uint32_t index_id); + + void + Clear(); + + // Note that "idx" is not the same as the "thread_index". It is a zero + // based index to accessing the current threads, whereas "thread_index" + // is a unique index assigned + lldb::ThreadSP + GetThreadAtIndex (uint32_t idx, bool can_update = true); + + lldb::ThreadSP + FindThreadByID (lldb::tid_t tid, bool can_update = true); + + lldb::ThreadSP + FindThreadByIndexID (lldb::tid_t index_id, bool can_update = true); + + lldb::ThreadSP + GetThreadSPForThreadPtr (Thread *thread_ptr); + + bool + ShouldStop (Event *event_ptr); + + lldb::Vote + ShouldReportStop (Event *event_ptr); + + lldb::Vote + ShouldReportRun (Event *event_ptr); + + void + RefreshStateAfterStop (); + + bool + WillResume (); + + void + DidResume (); + + void + DiscardThreadPlans(); + + uint32_t + GetStopID () const; + + void + SetStopID (uint32_t stop_id); + +protected: + + typedef std::vector<lldb::ThreadSP> collection; + //------------------------------------------------------------------ + // Classes that inherit from Process can see and modify these + //------------------------------------------------------------------ + Process *m_process; ///< The process that manages this thread list. + uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for. + collection m_threads; ///< The threads for this process. + mutable Mutex m_threads_mutex; + lldb::tid_t m_current_tid; ///< For targets that need the notion of a current thread. + +private: + ThreadList (); +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadList_h_ diff --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h new file mode 100644 index 00000000000..96a13264737 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlan.h @@ -0,0 +1,358 @@ +//===-- ThreadPlan.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlan_h_ +#define liblldb_ThreadPlan_h_ + +// C Includes +// C++ Includes +#include <string> +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//------------------------------------------------------------------ +// ThreadPlan: +// This is the pure virtual base class for thread plans. +// +// The thread plans provide the "atoms" of behavior that +// all the logical process control, either directly from commands or through +// more complex composite plans will rely on. +// +// Plan Stack: +// +// The thread maintaining a thread plan stack, and you program the actions of a particular thread +// by pushing plans onto the plan stack. +// There is always a "Current" plan, which is the head of the plan stack, though in some cases +// a plan may defer to plans higher in the stack for some piece of information. +// +// The plan stack is never empty, there is always a Base Plan which persists through the life +// of the running process. +// +// +// DEPRECATED: This ended up causing a real hassle, too many cases where the immediate plan +// got stranded. So the better way to do this is to post any plans you need to do right before +// running in the PrepareToResume method. +//f +// Immediate Plans: +// +// One other complexity of the plan stack is that sometimes you need to do a piece of work immediately +// on resume, regardless of what other plans have been pushed on the stack while the process has +// been stopped. The classic example is stepping over a breakpoint. To that end the plan stack is +// actually two stacks, an "immediate" plan stack and the normal plan stack. A plan can indicate that it +// should go on the immediate plan stack by returning "true" from the IsImmediate method. +// +// END DEPRECATED... +// +// Creating Plans: +// +// The thread plan is generally created and added to the plan stack through the QueueThreadPlanFor... API +// in lldb::Thread. Those API's will return the plan that performs the named operation in a manner +// appropriate for the current process. The plans in lldb/source/Target are generic +// implementations, but a Process plugin can override them. +// +// ValidatePlan is then called. If it returns false, the plan is unshipped. This is a little +// convenience which keeps us from having to error out of the constructor. +// +// Then the plan is added to the plan stack. When the plan is added to the plan stack its DidPush +// will get called. This is useful if a plan wants to push any additional plans as it is constructed, +// since you need to make sure you're already on the stack before you push additional plans. +// +// Completed Plans: +// +// When the target process stops the plans are queried, among other things, for whether their job is done. +// If it is they are moved from the plan stack to the Completed Plan stack in reverse order from their position +// on the plan stack (since multiple plans may be done at a given stop.) This is used primarily so that +// the lldb::Thread::StopInfo for the thread can be set properly. If one plan pushes another to achieve part of +// its job, but it doesn't want that sub-plan to be the one that sets the StopInfo, then call SetPrivate on the +// sub-plan when you create it, and the Thread will pass over that plan in reporting the reason for the stop. +// +// When the plan is moved from the plan stack to the completed plan stack its DidPop method is called. You should +// undo anything that affects target state in this method so the target state is clear for new plans. +// But be sure to leave whatever state might be needed to correctly fill the StopInfo. +// +// Over the lifetime of the plan, various methods of the ThreadPlan are then called in response to changes of state in +// the process we are debugging as follows: +// +// Resuming: +// +// When the target process is about to be restarted, the plan's WillResume method is called, +// giving the plan a chance to prepare for the run. If WillResume returns false, then the +// process is not restarted. Be sure to set an appropriate error value in the Process if +// you have to do this. +// Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan +// returns "true" then only that thread gets to run. If more than one returns "true" the threads that want to run solo +// get run one by one round robin fashion. Otherwise all are let to run. +// Finally, for each thread that is running, it run state is set to the return of RunState from the +// thread's Current plan. +// +// Responding to a stop: +// +// When the target process stops, the plan is called in the following stages: +// +// First the thread asks the Current Plan if it can handle this stop by calling PlanExplainsStop. +// If the Current plan answers "true" then it is asked if the stop should percolate all the way to the +// user by calling the ShouldStop method. If the current plan doesn't explain the stop, then we query down +// the plan stack for a plan that does explain the stop. The plan that does explain the stop then needs to +// figure out what to do about the plans below it in the stack. If the stop is recoverable, then the plan that +// understands it can just do what it needs to set up to restart, and then continue. +// Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it. +// In the normal case, this will just collapse the plan stack up to the point of the plan that understood +// the stop reason. However, if a plan wishes to stay on the stack after an event it didn't directly handle +// it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be +// discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when +// we resume execution. +// +// Actually Stopping: +// +// If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling +// MischiefManaged. If that returns true, the thread is popped from the plan stack and added to the +// Completed Plan Stack. Then the next plan in the stack is asked if it ShouldStop, and it returns "true", +// it is asked if it is done, and if yes popped, and so on till we reach a plan that is not done. +// +// Since you often know in the ShouldStop method whether your plan is complete, as a convenience you can call +// SetPlanComplete and the ThreadPlan implementation of MischiefManaged will return "true", without your having +// to redo the calculation when your sub-classes MischiefManaged is called. If you call SetPlanComplete, you can +// later use IsPlanComplete to determine whether the plan is complete. This is only a convenience for sub-classes, +// the logic in lldb::Thread will only call MischiefManaged. +// +// One slightly tricky point is you have to be careful using SetPlanComplete in PlanExplainsStop because you +// are not guaranteed that PlanExplainsStop for a plan will get called before ShouldStop gets called. If your sub-plan +// explained the stop and then popped itself, only your ShouldStop will get called. +// +// If ShouldStop for any thread returns "true", then the WillStop method of the Current plan of +// all threads will be called, the stop event is placed on the Process's public broadcaster, and +// control returns to the upper layers of the debugger. +// +// Automatically Resuming: +// +// If ShouldStop for all threads returns "false", then the target process will resume. This then cycles back to +// Resuming above. +// +// Reporting eStateStopped events when the target is restarted: +// +// If a plan decides to auto-continue the target by returning "false" from ShouldStop, then it will be asked +// whether the Stopped event should still be reported. For instance, if you hit a breakpoint that is a User set +// breakpoint, but the breakpoint callback said to continue the target process, you might still want to inform +// the upper layers of lldb that the stop had happened. +// The way this works is every thread gets to vote on whether to report the stop. If all votes are eVoteNoOpinion, +// then the thread list will decide what to do (at present it will pretty much always suppress these stopped events.) +// If there is an eVoteYes, then the event will be reported regardless of the other votes. If there is an eVoteNo +// and no eVoteYes's, then the event won't be reported. +// +// One other little detail here, sometimes a plan will push another plan onto the plan stack to do some part of +// the first plan's job, and it would be convenient to tell that plan how it should respond to ShouldReportStop. +// You can do that by setting the stop_vote in the child plan when you create it. +// +// Suppressing the initial eStateRunning event: +// +// The private process running thread will take care of ensuring that only one "eStateRunning" event will be +// delivered to the public Process broadcaster per public eStateStopped event. However there are some cases +// where the public state of this process is eStateStopped, but a thread plan needs to restart the target, but +// doesn't want the running event to be publically broadcast. The obvious example of this is running functions +// by hand as part of expression evaluation. To suppress the running event return eVoteNo from ShouldReportStop, +// to force a running event to be reported return eVoteYes, in general though you should return eVoteNoOpinion +// which will allow the ThreadList to figure out the right thing to do. +// The run_vote argument to the constructor works like stop_vote, and is a way for a plan to instruct a sub-plan\ +// on how to respond to ShouldReportStop. +// +//------------------------------------------------------------------ + +class ThreadPlan: + public UserID +{ +public: + typedef enum + { + eAllThreads, + eSomeThreads, + eThisThread + } ThreadScope; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ThreadPlan (const char *name, + Thread &thread, + lldb::Vote stop_vote, + lldb::Vote run_vote); + + virtual + ~ThreadPlan(); + + //------------------------------------------------------------------ + /// Returns the name of this thread plan. + /// + /// @return + /// A const char * pointer to the thread plan's name. + //------------------------------------------------------------------ + const char * + GetName () const; + + //------------------------------------------------------------------ + /// Returns the Thread that is using this thread plan. + /// + /// @return + /// A pointer to the thread plan's owning thread. + //------------------------------------------------------------------ + Thread & + GetThread(); + + const Thread & + GetThread() const; + + //------------------------------------------------------------------ + /// Print a description of this thread to the stream \a s. + /// \a thread. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The level of description desired. Note that eDescriptionLevelBrief + /// will be used in the stop message printed when the plan is complete. + //------------------------------------------------------------------ + virtual void + GetDescription (Stream *s, + lldb::DescriptionLevel level) = 0; + + //------------------------------------------------------------------ + /// Returns whether this plan needs to be executed immediatly on resume. + /// + /// @return + /// \b true if the plan is immediate, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + IsImmediate() const + { + return false; + } + + //------------------------------------------------------------------ + /// Returns whether this plan could be successfully created. + /// + /// @param[in] error + /// A stream to which to print some reason why the plan could not be created. + /// + /// @return + /// \b true if the plan should be queued, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + ValidatePlan (Stream *error) = 0; + + virtual bool + PlanExplainsStop () = 0; + + + virtual lldb::StateType + RunState () = 0; + + virtual bool + ShouldStop (Event *event_ptr) = 0; + + // Whether a "stop class" event should be reported to the "outside world". In general + // if a thread plan is active, events should not be reported. + + virtual lldb::Vote + ShouldReportStop (Event *event_ptr); + + virtual lldb::Vote + ShouldReportRun (Event *event_ptr); + + virtual bool + StopOthers (); + + virtual bool + WillResume (lldb::StateType resume_state, bool current_plan); + + virtual bool + WillStop () = 0; + + virtual bool + IsMasterPlan() + { + return false; + } + + virtual bool + OkayToDiscard(); + + void + SetOkayToDiscard (bool value) + { + m_okay_to_discard = value; + } + + // The base class MischiefManaged does some cleanup - so you have to call it + // in your MischiefManaged derived class. + virtual bool + MischiefManaged (); + + bool + GetPrivate (); + + void + SetPrivate (bool input); + + virtual void + DidPush(); + + virtual void + WillPop(); + + // This pushes \a plan onto the plan stack of the current plan's thread. + void + PushPlan (lldb::ThreadPlanSP &thread_plan_sp); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from ThreadPlan can see and modify these + //------------------------------------------------------------------ + + bool + IsPlanComplete(); + + void + SetPlanComplete (); + + // This gets the previous plan to the current plan (for forwarding requests). + // This is mostly a formal requirement, it allows us to make the Thread's + // GetPreviousPlan protected, but only friend ThreadPlan to thread. + + ThreadPlan * + GetPreviousPlan (); + + Thread &m_thread; + lldb::Vote m_stop_vote; + lldb::Vote m_run_vote; + +private: + //------------------------------------------------------------------ + // For ThreadPlan only + //------------------------------------------------------------------ + static lldb::user_id_t GetNextID (); + + std::string m_name; + Mutex m_plan_complete_mutex; + bool m_plan_complete; + bool m_plan_private; + bool m_okay_to_discard; + +private: + DISALLOW_COPY_AND_ASSIGN(ThreadPlan); +}; + + +} // namespace lldb_private + +#endif // liblldb_ThreadPlan_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanBase.h b/lldb/include/lldb/Target/ThreadPlanBase.h new file mode 100644 index 00000000000..6a0dbfc405a --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanBase.h @@ -0,0 +1,66 @@ +//===-- ThreadPlanBase.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanFundamental_h_ +#define liblldb_ThreadPlanFundamental_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + + +//------------------------------------------------------------------ +// Base thread plans: +// This is the generic version of the bottom most plan on the plan stack. It should +// be able to handle generic breakpoint hitting, and signals and exceptions. +//------------------------------------------------------------------ + +class ThreadPlanBase : public ThreadPlan +{ +public: + virtual ~ThreadPlanBase (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillStop (); + virtual bool MischiefManaged (); + + virtual bool IsMasterPlan() + { + return true; + } + + virtual bool OkayToDiscard() + { + return false; + } + +protected: + ThreadPlanBase (Thread &thread); + +private: + friend ThreadPlan * + Thread::QueueFundamentalPlan(bool abort_other_plans); + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanBase); +}; + + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanFundamental_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/lldb/include/lldb/Target/ThreadPlanCallFunction.h new file mode 100644 index 00000000000..53b2a87afa7 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -0,0 +1,96 @@ +//===-- ThreadPlanCallFunction.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanCallFunction_h_ +#define liblldb_ThreadPlanCallFunction_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanCallFunction : public ThreadPlan +{ +public: + ThreadPlanCallFunction (Thread &thread, + Address &function, + lldb::addr_t arg, + bool stop_other_threads, + bool discard_on_error = true); + + ThreadPlanCallFunction (Thread &thread, + Address &function, + ValueList &args, + bool stop_other_threads, + bool discard_on_error = true); + + virtual + ~ThreadPlanCallFunction (); + + virtual void + GetDescription (Stream *s, lldb::DescriptionLevel level); + + virtual bool + ValidatePlan (Stream *error); + + virtual bool + PlanExplainsStop (); + + virtual bool + ShouldStop (Event *event_ptr); + + virtual bool + StopOthers (); + + virtual void + SetStopOthers (bool new_value); + + virtual lldb::StateType + RunState (); + + virtual void + DidPush (); + + virtual bool + WillStop (); + + virtual bool + MischiefManaged (); + + virtual bool + IsMasterPlan() + { + return true; + } + +protected: +private: + bool m_use_abi; + bool m_valid; + bool m_stop_other_threads; + Address m_function_addr; + Address m_start_addr; + lldb::addr_t m_arg_addr; + ValueList *m_args; + Process &m_process; + Thread &m_thread; + Thread::RegisterCheckpoint m_register_backup; + lldb::ThreadPlanSP m_subplan_sp; + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction); +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanCallFunction_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanContinue.h b/lldb/include/lldb/Target/ThreadPlanContinue.h new file mode 100644 index 00000000000..bd50c737fd7 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanContinue.h @@ -0,0 +1,60 @@ +//===-- ThreadPlanContinue.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanContinue_h_ +#define liblldb_ThreadPlanContinue_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanContinue : public ThreadPlan +{ +public: + ThreadPlanContinue (Thread &thread, + bool stop_others, + lldb::Vote stop_vote, + lldb::Vote run_vote, + bool immediate = false); + virtual ~ThreadPlanContinue (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + + virtual bool ValidatePlan (Stream *error); + + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool IsImmediate () const; + virtual bool WillResume (lldb::StateType resume_state, bool current_plan); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + bool InRange(); +private: + bool m_stop_others; + bool m_did_run; + bool m_immediate; + // Need an appropriate marker for the current stack so we can tell step out + // from step in. + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanContinue); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanContinue_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanRunToAddress.h b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h new file mode 100644 index 00000000000..3b591ea3324 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h @@ -0,0 +1,78 @@ +//===-- ThreadPlanRunToAddress.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanRunToAddress_h_ +#define liblldb_ThreadPlanRunToAddress_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanRunToAddress : public ThreadPlan +{ +public: + ThreadPlanRunToAddress (Thread &thread, + Address &address, + bool stop_others); + + ThreadPlanRunToAddress (Thread &thread, + lldb::addr_t address, + bool stop_others); + + virtual + ~ThreadPlanRunToAddress (); + + virtual void + GetDescription (Stream *s, lldb::DescriptionLevel level); + + virtual bool + ValidatePlan (Stream *error); + + virtual bool + PlanExplainsStop (); + + virtual bool + ShouldStop (Event *event_ptr); + + virtual bool + StopOthers (); + + virtual void + SetStopOthers (bool new_value); + + virtual lldb::StateType + RunState (); + + virtual bool + WillStop (); + + virtual bool + MischiefManaged (); + +protected: + void SetInitialBreakpoint(); + bool AtOurAddress(); +private: + bool m_stop_others; + lldb::addr_t m_address; // This is the address we are going to run to. + // TODO: Would it be useful to have multiple addresses? + lldb::user_id_t m_break_id; // This is the breakpoint we are using to stop us at m_address. + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanRunToAddress); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanRunToAddress_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h new file mode 100644 index 00000000000..66270dfa5a3 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -0,0 +1,94 @@ +//===-- ThreadPlanShouldStopHere.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanShouldStopHere_h_ +#define liblldb_ThreadPlanShouldStopHere_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +// This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior +// when a thread plan comes to a place where it would ordinarily stop. If such modification makes +// sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop +// method), call InvokeShouldStopHereCallback, and if that returns a non-NULL plan, execute that +// plan instead of stopping. +// +// The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have +// no debug information. +// +// This class also defines a set of flags to control general aspects of this "ShouldStop" behavior. +// A class implementing this protocol needs to define a default set of flags, and can provide access to +// changing that default flag set if it wishes. + +class ThreadPlanShouldStopHere +{ +public: + enum + { + eNone = 0, + eAvoidInlines = (1 << 0), + eAvoidNoDebug = (1 << 1), + }; + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ThreadPlanShouldStopHere (ThreadPlan *owner, + ThreadPlanShouldStopHereCallback callback = NULL, + void *baton = NULL); + virtual + ~ThreadPlanShouldStopHere(); + + void + SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton); + + ThreadPlan * + InvokeShouldStopHereCallback (); + + lldb_private::Flags & + GetFlags () + { + return m_flags; + } + + const lldb_private::Flags & + GetFlags () const + { + return m_flags; + } + +protected: + // Implement this, and call it in the plan's constructor to set the default flags. + virtual void SetFlagsToDefault () = 0; + + //------------------------------------------------------------------ + // Classes that inherit from ThreadPlanShouldStopHere can see and modify these + //------------------------------------------------------------------ + ThreadPlanShouldStopHereCallback m_callback; + void * m_baton; + ThreadPlan *m_owner; + lldb_private::Flags m_flags; + +private: + //------------------------------------------------------------------ + // For ThreadPlanShouldStopHere only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanShouldStopHere); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanShouldStopHere_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h new file mode 100644 index 00000000000..2e0b4cb8385 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -0,0 +1,76 @@ +//===-- ThreadPlanStepInRange.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepInRange_h_ +#define liblldb_ThreadPlanStepInRange_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/AddressRange.h" +#include "lldb/Target/StackID.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" + +namespace lldb_private { + +class ThreadPlanStepInRange : + public ThreadPlanStepRange, + public ThreadPlanShouldStopHere +{ +public: + virtual + ~ThreadPlanStepInRange (); + + virtual void + GetDescription (Stream *s, lldb::DescriptionLevel level); + + virtual bool + ShouldStop (Event *event_ptr); + + static ThreadPlan * + DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton); + + static void + SetDefaultFlagValue (uint32_t new_value); + +protected: + + ThreadPlanStepInRange (Thread &thread, + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_others); + + virtual void + SetFlagsToDefault (); + +private: + + friend ThreadPlan * + Thread::QueueThreadPlanForStepRange (bool abort_other_plans, + lldb::StepType type, + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_others); + + + // Need an appropriate marker for the current stack so we can tell step out + // from step in. + + static uint32_t s_default_flag_values; + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepInRange_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h new file mode 100644 index 00000000000..2157e84d8e9 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -0,0 +1,61 @@ +//===-- ThreadPlanStepInstruction.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepInstruction_h_ +#define liblldb_ThreadPlanStepInstruction_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanStepInstruction : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepInstruction (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + ThreadPlanStepInstruction (Thread &thread, + bool step_over, + bool stop_others, + lldb::Vote stop_vote, + lldb::Vote run_vote); + +private: + friend ThreadPlan * + Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads); + + lldb::addr_t m_instruction_addr; + bool m_stop_other_threads; + bool m_step_over; + // This is used only for the step over case. + uint64_t m_stack_depth; + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInstruction); + +}; + + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepInstruction_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepOut.h b/lldb/include/lldb/Target/ThreadPlanStepOut.h new file mode 100644 index 00000000000..fd74e7199c3 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -0,0 +1,72 @@ +//===-- ThreadPlanStepOut.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepOut_h_ +#define liblldb_ThreadPlanStepOut_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + + +class ThreadPlanStepOut : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepOut (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillResume (lldb::StateType resume_state, bool current_plan); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + ThreadPlanStepOut (Thread &thread, + SymbolContext *addr_context, + bool first_insn, + bool stop_others, + lldb::Vote stop_vote, + lldb::Vote run_vote); + +private: + SymbolContext *m_step_from_context; + lldb::addr_t m_step_from_insn; + uint64_t m_stack_depth; + lldb::break_id_t m_return_bp_id; + lldb::addr_t m_return_addr; + bool m_first_insn; + bool m_stop_others; + + friend ThreadPlan * + Thread::QueueThreadPlanForStepOut (bool abort_other_plans, + SymbolContext *addr_context, + bool first_insn, + bool stop_others, + lldb::Vote stop_vote, + lldb::Vote run_vote); + + // Need an appropriate marker for the current stack so we can tell step out + // from step in. + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOut); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepOut_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h new file mode 100644 index 00000000000..14ba453ffd9 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -0,0 +1,55 @@ +//===-- ThreadPlanStepOverBreakpoint.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepOverBreakpoint_h_ +#define liblldb_ThreadPlanStepOverBreakpoint_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanStepOverBreakpoint : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepOverBreakpoint (); + + ThreadPlanStepOverBreakpoint (Thread &thread); + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool IsImmediate () const + { + return false; + } + virtual bool WillResume (lldb::StateType resume_state, bool current_plan); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + +private: + + lldb::addr_t m_breakpoint_addr; + lldb::user_id_t m_breakpoint_site_id; + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverBreakpoint); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepOverBreakpoint_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepOverRange.h b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h new file mode 100644 index 00000000000..9ecde535eb9 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h @@ -0,0 +1,56 @@ +//===-- ThreadPlanStepOverRange.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepOverRange_h_ +#define liblldb_ThreadPlanStepOverRange_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/AddressRange.h" +#include "lldb/Target/StackID.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlanStepRange.h" + +namespace lldb_private { + +class ThreadPlanStepOverRange : public ThreadPlanStepRange +{ +public: + virtual ~ThreadPlanStepOverRange (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ShouldStop (Event *event_ptr); + virtual bool + IsMasterPlan() + { + return true; + } + +protected: + + ThreadPlanStepOverRange (Thread &thread, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_others, bool okay_to_discard = false); + +private: + + friend ThreadPlan * + Thread::QueueThreadPlanForStepRange (bool abort_other_plans, + lldb::StepType type, + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_others); + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepOverRange_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepRange.h b/lldb/include/lldb/Target/ThreadPlanStepRange.h new file mode 100644 index 00000000000..dfdd2e20e50 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepRange.h @@ -0,0 +1,74 @@ +//===-- ThreadPlanStepRange.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepRange_h_ +#define liblldb_ThreadPlanStepRange_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/AddressRange.h" +#include "lldb/Target/StackID.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" + +namespace lldb_private { + +class ThreadPlanStepRange : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepRange (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level) = 0; + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr) = 0; + virtual lldb::Vote ShouldReportStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + + ThreadPlanStepRange (const char *name, + Thread &thread, + const AddressRange &range, + const SymbolContext &addr_context, + lldb::RunMode stop_others); + + bool InRange(); + bool FrameIsYounger(); + bool FrameIsOlder(); + bool InSymbol(); + + SymbolContext m_addr_context; + AddressRange m_address_range; + lldb::RunMode m_stop_others; + uint32_t m_stack_depth; + StackID m_stack_id; // Use the stack ID so we can tell step out from step in. + bool m_no_more_plans; // Need this one so we can tell if we stepped into a call, but can't continue, + // in which case we are done. + bool m_first_run_event; // We want to broadcast only one running event, our first. + +private: + + // friend ThreadPlan * + // Thread::QueueThreadPlanForStepRange (bool abort_other_plans, StepType type, const AddressRange &range, SymbolContext *addr_context, bool stop_others); + + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepRange); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepRange_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepThrough.h b/lldb/include/lldb/Target/ThreadPlanStepThrough.h new file mode 100644 index 00000000000..4763da719b8 --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepThrough.h @@ -0,0 +1,58 @@ +//===-- ThreadPlanStepThrough.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepThrough_h_ +#define liblldb_ThreadPlanStepThrough_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + +class ThreadPlanStepThrough : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepThrough (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillResume (lldb::StateType resume_state, bool current_plan); + virtual bool WillStop (); + virtual bool MischiefManaged (); + +protected: + ThreadPlanStepThrough (Thread &thread, + bool stop_others); + + bool + HappyToStopHere (); + +private: + friend ThreadPlan * + Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, + bool stop_others); + + lldb::addr_t m_start_address; + bool m_stop_others; + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepThrough); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepThrough_h_ diff --git a/lldb/include/lldb/Target/ThreadPlanStepUntil.h b/lldb/include/lldb/Target/ThreadPlanStepUntil.h new file mode 100644 index 00000000000..504fd2f8dfa --- /dev/null +++ b/lldb/include/lldb/Target/ThreadPlanStepUntil.h @@ -0,0 +1,83 @@ +//===-- ThreadPlanStepUntil.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadPlanStepUntil_h_ +#define liblldb_ThreadPlanStepUntil_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" + +namespace lldb_private { + + +class ThreadPlanStepUntil : public ThreadPlan +{ +public: + virtual ~ThreadPlanStepUntil (); + + virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); + virtual bool ValidatePlan (Stream *error); + virtual bool PlanExplainsStop (); + virtual bool ShouldStop (Event *event_ptr); + virtual bool StopOthers (); + virtual lldb::StateType RunState (); + virtual bool WillResume (lldb::StateType resume_state, bool current_plan); + virtual bool WillStop (); + virtual bool MischiefManaged (); + + virtual bool + IsMasterPlan() + { + return true; + } + +protected: + ThreadPlanStepUntil (Thread &thread, + lldb::addr_t *address_list, + size_t num_addresses, + bool stop_others); + void AnalyzeStop(void); + +private: + + uint64_t m_stack_depth; + lldb::addr_t m_step_from_insn; + lldb::break_id_t m_return_bp_id; + lldb::addr_t m_return_addr; + bool m_stepped_out; + bool m_should_stop; + bool m_ran_analyze; + bool m_explains_stop; + + typedef std::map<lldb::addr_t,lldb::break_id_t> until_collection; + until_collection m_until_points; + bool m_stop_others; + + void Clear(); + + friend ThreadPlan * + Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, + lldb::addr_t *address_list, + size_t num_addresses, + bool stop_others); + + // Need an appropriate marker for the current stack so we can tell step out + // from step in. + + DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepUntil); + +}; + +} // namespace lldb_private + +#endif // liblldb_ThreadPlanStepUntil_h_ diff --git a/lldb/include/lldb/Target/UnixSignals.h b/lldb/include/lldb/Target/UnixSignals.h new file mode 100644 index 00000000000..c83a5a4d8ad --- /dev/null +++ b/lldb/include/lldb/Target/UnixSignals.h @@ -0,0 +1,168 @@ +//===-- UnixSignals.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_UnixSignals_h_ +#define lldb_UnixSignals_h_ + +// C Includes +// C++ Includes +#include <string> +#include <map> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" + +namespace lldb_private +{ + +class UnixSignals +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + UnixSignals(); + + virtual + ~UnixSignals(); + + const char * + GetSignalAsCString (int32_t signo) const; + + bool + SignalIsValid (int32_t signo) const; + + int32_t + GetSignalNumberFromName (const char *name) const; + + const char * + GetSignalInfo (int32_t signo, + bool &should_suppress, + bool &should_stop, + bool &should_notify) const; + + bool + GetShouldSuppress (int32_t signo) const; + + bool + SetShouldSuppress (int32_t signo, + bool value); + + bool + SetShouldSuppress (const char *signal_name, + bool value); + + bool + GetShouldStop (int32_t signo) const; + + bool + SetShouldStop (int32_t signo, + bool value); + bool + SetShouldStop (const char *signal_name, + bool value); + + bool + GetShouldNotify (int32_t signo) const; + + bool + SetShouldNotify (int32_t signo, bool value); + + bool + SetShouldNotify (const char *signal_name, + bool value); + + // These provide an iterator through the signals available on this system. + // Call GetFirstSignalNumber to get the first entry, then iterate on GetNextSignalNumber + // till you get back LLDB_INVALID_SIGNAL_NUMBER. + int32_t + GetFirstSignalNumber () const; + + int32_t + GetNextSignalNumber (int32_t current_signal) const; + + // We assume that the elements of this object are constant once it is constructed, + // since a process should never need to add or remove symbols as it runs. So don't + // call these functions anywhere but the constructor of your subclass of UnixSignals or in + // your Process Plugin's GetUnixSignals method before you return the UnixSignal object. + + void + AddSignal (int signo, + const char *name, + bool default_suppress, + bool default_stop, + bool default_notify); + + void + RemoveSignal (int signo); + +protected: + //------------------------------------------------------------------ + // Classes that inherit from UnixSignals can see and modify these + //------------------------------------------------------------------ + + struct Signal + { + typedef enum + { + eCondSuppress = 0, + eCondStop = 1, + eCondNotify + } Condition; + + ConstString m_name; + bool m_conditions[3]; + + Signal (const char *name, + bool default_suppress, + bool default_stop, + bool default_notify); + + ~Signal () {} + }; + + bool + GetCondition (int signo, + Signal::Condition cond_pos) const; + bool + SetCondition (int signo, + Signal::Condition cond_pos, + bool value); + + bool + SetCondition (const char *signal_name, + Signal::Condition cond_pos, + bool value); + + Signal * + GetSignalByName (const char *name, + int32_t &signo); + + const Signal * + GetSignalByName (const char *name, + int32_t &signo) const; + + void + Reset (); + +private: + //------------------------------------------------------------------ + // For UnixSignals only + //------------------------------------------------------------------ + typedef std::map <int32_t, Signal> collection; + + collection m_signals; + + DISALLOW_COPY_AND_ASSIGN (UnixSignals); +}; + +} // Namespace lldb +#endif // lldb_UnixSignals_h_ diff --git a/lldb/include/lldb/Target/Unwind.h b/lldb/include/lldb/Target/Unwind.h new file mode 100644 index 00000000000..f863add40dc --- /dev/null +++ b/lldb/include/lldb/Target/Unwind.h @@ -0,0 +1,69 @@ +//===-- Unwind.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Unwind_h_ +#define liblldb_Unwind_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class Unwind +{ +protected: + //------------------------------------------------------------------ + // Classes that inherit from Unwind can see and modify these + //------------------------------------------------------------------ + Unwind(Thread &thread) : + m_thread (thread) + { + } + +public: + virtual + ~Unwind() + { + } + + virtual void + Clear() = 0; + + virtual uint32_t + GetFrameCount() = 0; + + virtual bool + GetFrameInfoAtIndex (uint32_t frame_idx, + lldb::addr_t& cfa, + lldb::addr_t& pc) = 0; + + virtual RegisterContext * + CreateRegisterContextForFrame (StackFrame *frame) = 0; + + Thread & + GetThread() + { + return m_thread; + } + +protected: + //------------------------------------------------------------------ + // Classes that inherit from Unwind can see and modify these + //------------------------------------------------------------------ + Thread &m_thread; +private: + DISALLOW_COPY_AND_ASSIGN (Unwind); +}; + +} // namespace lldb_private + +#endif // liblldb_Unwind_h_ diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h new file mode 100644 index 00000000000..89d17af4ddf --- /dev/null +++ b/lldb/include/lldb/lldb-defines.h @@ -0,0 +1,88 @@ +//===-- lldb-defines.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_defines_h_ +#define LLDB_defines_h_ + +#include <LLDB/lldb-types.h> + +#if !defined(UINT32_MAX) + #define UINT32_MAX 4294967295U +#endif + +#if !defined(UINT64_MAX) + #define UINT64_MAX 18446744073709551615ULL +#endif + +//---------------------------------------------------------------------- +// lldb defines +//---------------------------------------------------------------------- +#define LLDB_GENERIC_ERROR ((uint32_t)UINT32_MAX) + +//---------------------------------------------------------------------- +// Breakpoints +//---------------------------------------------------------------------- +#define LLDB_INVALID_BREAK_ID ((lldb::break_id_t)0) +#define LLDB_DEFAULT_BREAK_SIZE 0 +#define LLDB_BREAK_ID_IS_VALID(bid) ((bid) != (LLDB_INVALID_BREAK_ID)) +#define LLDB_BREAK_ID_IS_INTERNAL(bid) ((bid) < 0) + +//---------------------------------------------------------------------- +// Watchpoints +//---------------------------------------------------------------------- +#define LLDB_INVALID_WATCH_ID ((lldb::user_id_t)0) +#define LLDB_WATCH_ID_IS_VALID(uid) ((uid) != (LLDB_INVALID_WATCH_ID)) +#define LLDB_WATCH_TYPE_READ (1u << 0) +#define LLDB_WATCH_TYPE_WRITE (1u << 1) + +//---------------------------------------------------------------------- +// Generic Register Numbers +//---------------------------------------------------------------------- +#define LLDB_REGNUM_GENERIC_PC 0 // Program Counter +#define LLDB_REGNUM_GENERIC_SP 1 // Stack Pointer +#define LLDB_REGNUM_GENERIC_FP 2 // Frame Pointer +#define LLDB_REGNUM_GENERIC_RA 3 // Return Address +#define LLDB_REGNUM_GENERIC_FLAGS 4 // Processor flags register + +//---------------------------------------------------------------------- +/// Invalid value definitions +//---------------------------------------------------------------------- +#define LLDB_INVALID_ADDRESS (~((lldb::addr_t)0)) +#define LLDB_INVALID_INDEX32 ((uint32_t)UINT32_MAX) +#define LLDB_INVALID_REGNUM ((uint32_t)UINT32_MAX) +#define LLDB_INVALID_UID ((lldb::user_id_t)UINT32_MAX) +#define LLDB_INVALID_PROCESS_ID ((lldb::pid_t)0) +#define LLDB_INVALID_THREAD_ID ((lldb::tid_t)0) +#define LLDB_INVALID_FRAME_ID ((uint32_t) UINT32_MAX) +#define LLDB_INVALID_SIGNAL_NUMBER ((int32_t) INT32_MAX) + +//---------------------------------------------------------------------- +/// CPU Type defintions +//---------------------------------------------------------------------- +#define LLDB_ARCH_DEFAULT "systemArch" +#define LLDB_ARCH_DEFAULT_32BIT "systemArch32" +#define LLDB_ARCH_DEFAULT_64BIT "systemArch64" +#define LLDB_INVALID_CPUTYPE (0xFFFFFFFEu) + + + +#if defined(__cplusplus) + +//---------------------------------------------------------------------- +/// @def DISALLOW_COPY_AND_ASSIGN(TypeName) +/// Macro definition for easily disallowing copy constructor and +/// assignment operators in C++ classes. +//---------------------------------------------------------------------- +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + const TypeName& operator=(const TypeName&) + +#endif // #if defined(__cplusplus) + +#endif // LLDB_defines_h_ diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h new file mode 100644 index 00000000000..8ad33500ee4 --- /dev/null +++ b/lldb/include/lldb/lldb-enumerations.h @@ -0,0 +1,358 @@ +//===-- lldb-enumerations.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_enumerations_h_ +#define LLDB_enumerations_h_ + +namespace lldb { + +//---------------------------------------------------------------------- +// Process and Thread States +//---------------------------------------------------------------------- +typedef enum StateType +{ + eStateInvalid = 0, + eStateUnloaded, + eStateAttaching, + eStateLaunching, + eStateStopped, + eStateRunning, + eStateStepping, + eStateCrashed, + eStateDetached, + eStateExited, + eStateSuspended +} StateType; + +//---------------------------------------------------------------------- +// Thread Step Types +//---------------------------------------------------------------------- +typedef enum StepType +{ + eStepTypeNone, + eStepTypeTrace, ///< Single step one instruction. + eStepTypeTraceOver, ///< Single step one instruction, stepping over. + eStepTypeInto, ///< Single step into a specified context. + eStepTypeOver, ///< Single step over a specified context. + eStepTypeOut ///< Single step out a specified context. +} StepType; + +//---------------------------------------------------------------------- +// Thread Run Modes +//---------------------------------------------------------------------- +typedef enum RunMode { + eOnlyThisThread, + eAllThreads, + eOnlyDuringStepping +} RunMode; + +//---------------------------------------------------------------------- +// Address Types +//---------------------------------------------------------------------- +typedef enum AddressType +{ + eAddressTypeInvalid = 0, + eAddressTypeFile, ///< Address is an address as found in an object or symbol file + eAddressTypeLoad, ///< Address is an address as in the current target inferior process + eAddressTypeHost ///< Address is an address in the process that is running this code +} AddressType; + +//---------------------------------------------------------------------- +// Byte ordering definitions +//---------------------------------------------------------------------- +typedef enum ByteOrder +{ + eByteOrderInvalid = 0, + eByteOrderLittle = 1234, + eByteOrderBig = 4321, + eByteOrderPDP = 3412, +#if defined (__LITTLE_ENDIAN__) + eByteOrderHost = eByteOrderLittle +#elif defined (__BIG_ENDIAN__) + eByteOrderHost = eByteOrderBig +#elif defined (__PDP_ENDIAN__) + eByteOrderHost = eByteOrderPDP +#else +#error unable to detect endianness +#endif +} ByteOrder; + +//---------------------------------------------------------------------- +// Register encoding definitions +//---------------------------------------------------------------------- +typedef enum Encoding +{ + eEncodingInvalid = 0, + eEncodingUint, // unsigned integer + eEncodingSint, // signed integer + eEncodingIEEE754, // float + eEncodingVector // vector registers +} Encoding; + +//---------------------------------------------------------------------- +// Display format definitions +//---------------------------------------------------------------------- +typedef enum Format +{ + eFormatDefault = 0, + eFormatInvalid = 0, + eFormatBoolean, + eFormatBinary, + eFormatBytes, + eFormatBytesWithASCII, + eFormatChar, + eFormatCharPrintable, // Only printable characters, space if not printable + eFormatComplex, + eFormatCString, // NULL terminated C strings + eFormatDecimal, + eFormatEnum, + eFormatHex, + eFormatFloat, + eFormatOctal, + eFormatUnicode16, + eFormatUnicode32, + eFormatUnsigned, + eFormatPointer, + eFormatVectorOfChar, + eFormatVectorOfSInt8, + eFormatVectorOfUInt8, + eFormatVectorOfSInt16, + eFormatVectorOfUInt16, + eFormatVectorOfSInt32, + eFormatVectorOfUInt32, + eFormatVectorOfSInt64, + eFormatVectorOfUInt64, + eFormatVectorOfFloat32, + eFormatVectorOfFloat64, + eFormatVectorOfUInt128, + +} Format; + +//---------------------------------------------------------------------- +// Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls +//---------------------------------------------------------------------- +typedef enum DescriptionLevel +{ + eDescriptionLevelBrief = 0, + eDescriptionLevelFull, + eDescriptionLevelVerbose, + kNumDescriptionLevels +} DescriptionLevel; + +//---------------------------------------------------------------------- +// Script interpreter types +//---------------------------------------------------------------------- +typedef enum ScriptLanguage +{ + eScriptLanguageNone, + eScriptLanguagePython, + eScriptLanguageDefault = eScriptLanguagePython +} ScriptLanguage; + +//---------------------------------------------------------------------- +// Register numbering types +//---------------------------------------------------------------------- +typedef enum RegisterKind +{ + eRegisterKindGCC = 0, + eRegisterKindDWARF, + eRegisterKindGeneric, + eRegisterKindGDB, + kNumRegisterKinds +} RegisterKind; + +//---------------------------------------------------------------------- +// Thread stop reasons +//---------------------------------------------------------------------- +typedef enum StopReason +{ + eStopReasonInvalid = 0, + eStopReasonNone, + eStopReasonTrace, + eStopReasonBreakpoint, + eStopReasonWatchpoint, + eStopReasonSignal, + eStopReasonException, + eStopReasonPlanComplete +} StopReason; + +//---------------------------------------------------------------------- +// Votes - Need a tri-state, yes, no, no opinion... +//---------------------------------------------------------------------- +typedef enum Vote +{ + eVoteNo = -1, + eVoteNoOpinion = 0, + eVoteYes = 1, +} Vote; + +//---------------------------------------------------------------------- +// Symbol types +//---------------------------------------------------------------------- +typedef enum SymbolType +{ + eSymbolTypeAny = 0, + eSymbolTypeInvalid = 0, + eSymbolTypeAbsolute, + eSymbolTypeExtern, + eSymbolTypeCode, + eSymbolTypeData, + eSymbolTypeTrampoline, + eSymbolTypeRuntime, + eSymbolTypeException, + eSymbolTypeSourceFile, + eSymbolTypeHeaderFile, + eSymbolTypeObjectFile, + eSymbolTypeFunction, + eSymbolTypeFunctionEnd, + eSymbolTypeCommonBlock, + eSymbolTypeBlock, + eSymbolTypeStatic, + eSymbolTypeGlobal, + eSymbolTypeLocal, + eSymbolTypeParam, + eSymbolTypeVariable, + eSymbolTypeVariableType, + eSymbolTypeLineEntry, + eSymbolTypeLineHeader, + eSymbolTypeScopeBegin, + eSymbolTypeScopeEnd, + eSymbolTypeAdditional, // When symbols take more than one entry, the extra entries get this type + eSymbolTypeCompiler, + eSymbolTypeInstrumentation, + eSymbolTypeUndefined +} SymbolType; + + +//---------------------------------------------------------------------- +// Command Return Status Types +//---------------------------------------------------------------------- +typedef enum ReturnStatus +{ + eReturnStatusInvalid, + eReturnStatusSuccessFinishNoResult, + eReturnStatusSuccessFinishResult, + eReturnStatusSuccessContinuingNoResult, + eReturnStatusSuccessContinuingResult, + eReturnStatusStarted, + eReturnStatusFailed, + eReturnStatusQuit +} ReturnStatus; + + +//---------------------------------------------------------------------- +// Connection Status Types +//---------------------------------------------------------------------- +typedef enum ConnectionStatus +{ + eConnectionStatusSuccess, // Success + eConnectionStatusError, // Check GetError() for details + eConnectionStatusTimedOut, // Request timed out + eConnectionStatusNoConnection, // No connection + eConnectionStatusLostConnection // Lost connection while connected to a valid connection +} ConnectionStatus; + + +typedef enum ErrorType +{ + eErrorTypeInvalid, + eErrorTypeGeneric, ///< Generic errors that can be any value. + eErrorTypeMachKernel, ///< Mach kernel error codes. + eErrorTypePOSIX ///< POSIX error codes. +} ErrorType; + + +typedef enum ValueType +{ + eValueTypeInvalid = 0, + eValueTypeVariableGlobal = 1, // globals variable + eValueTypeVariableStatic = 2, // static variable + eValueTypeVariableArgument = 3, // function argument variables + eValueTypeVariableLocal = 4, // function local variables + eValueTypeRegister = 5, // stack frame register value + eValueTypeRegisterSet = 6 // A collection of stack frame register values +} ValueType; + +//---------------------------------------------------------------------- +// Token size/granularities for Input Readers +//---------------------------------------------------------------------- + +typedef enum InputReaderGranularity +{ + eInputReaderGranularityInvalid = 0, + eInputReaderGranularityByte, + eInputReaderGranularityWord, + eInputReaderGranularityLine, + eInputReaderGranularityAll, +} InputReaderGranularity; + +//------------------------------------------------------------------ +/// These mask bits allow a common interface for queries that can +/// limit the amount of information that gets parsed to only the +/// information that is requested. These bits also can indicate what +/// actually did get resolved during query function calls. +/// +/// Each definition corresponds to a one of the member variables +/// in this class, and requests that that item be resolved, or +/// indicates that the member did get resolved. +//------------------------------------------------------------------ +typedef enum SymbolContextItem +{ + eSymbolContextTarget = (1 << 0), ///< Set when \a target is requested from a query, or was located in query results + eSymbolContextModule = (1 << 1), ///< Set when \a module is requested from a query, or was located in query results + eSymbolContextCompUnit = (1 << 2), ///< Set when \a comp_unit is requested from a query, or was located in query results + eSymbolContextFunction = (1 << 3), ///< Set when \a function is requested from a query, or was located in query results + eSymbolContextBlock = (1 << 4), ///< Set when the deepest \a block is requested from a query, or was located in query results + eSymbolContextLineEntry = (1 << 5), ///< Set when \a line_entry is requested from a query, or was located in query results + eSymbolContextSymbol = (1 << 6), ///< Set when \a symbol is requested from a query, or was located in query results + eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1) ///< Indicates to try and lookup everything up during a query. +} SymbolContextItem; + +typedef enum Permissions +{ + ePermissionsWritable = (1 << 0), + ePermissionsReadable = (1 << 1), + ePermissionsExecutable = (1 << 2) +}; + +typedef enum SectionType +{ + eSectionTypeInvalid, + eSectionTypeCode, + eSectionTypeContainer, // The section contains child sections + eSectionTypeData, + eSectionTypeDataCString, // Inlined C string data + eSectionTypeDataCStringPointers, // Pointers to C string data + eSectionTypeDataSymbolAddress, // Address of a symbol in the symbol table + eSectionTypeData4, + eSectionTypeData8, + eSectionTypeData16, + eSectionTypeDataPointers, + eSectionTypeDebug, + eSectionTypeZeroFill, + eSectionTypeDataObjCMessageRefs, // Pointer to function pointer + selector + eSectionTypeDataObjCCFStrings, // Objective C const CFString/NSString objects + eSectionTypeOther + +} SectionType; + + +typedef enum InputReaderAction +{ + eInputReaderActivate, // reader is newly pushed onto the reader stack + eInputReaderReactivate, // reader is on top of the stack again after another reader was popped off + eInputReaderDeactivate, // another reader was pushed on the stack + eInputReaderGotToken, // reader got one of its tokens (granularity) + eInputReaderDone, // reader was just popped off the stack and is done +} InputReaderAction; + +} // namespace lldb + + +#endif // LLDB_enumerations_h_ diff --git a/lldb/include/lldb/lldb-forward-rtti.h b/lldb/include/lldb/lldb-forward-rtti.h new file mode 100644 index 00000000000..163a319c901 --- /dev/null +++ b/lldb/include/lldb/lldb-forward-rtti.h @@ -0,0 +1,76 @@ +//===-- lldb-forward-rtti.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_forward_rtti_h_ +#define LLDB_forward_rtti_h_ + +#if defined(__cplusplus) + +#ifndef NO_RTTI +//---------------------------------------------------------------------- +// And source files that may not have RTTI enabled during their +// compilation will want to do a "#define NO_RTTI" before including the +// lldb-include.h file. +//---------------------------------------------------------------------- + +#include <LLDB/lldb-types.h> +#include <LLDB/lldb-forward.h> + +//---------------------------------------------------------------------- +// lldb forward declarations +//---------------------------------------------------------------------- +namespace lldb { + + typedef SharedPtr<lldb_private::ABI>::Type ABISP; + typedef SharedPtr<lldb_private::AddressResolver>::Type AddressResolverSP; + typedef SharedPtr<lldb_private::Baton>::Type BatonSP; + typedef SharedPtr<lldb_private::Block>::Type BlockSP; + typedef SharedPtr<lldb_private::Breakpoint>::Type BreakpointSP; + typedef SharedPtr<lldb_private::BreakpointSite>::Type BreakpointSiteSP; + typedef SharedPtr<lldb_private::BreakpointLocation>::Type BreakpointLocationSP; + typedef SharedPtr<lldb_private::BreakpointResolver>::Type BreakpointResolverSP; + typedef SharedPtr<lldb_private::Broadcaster>::Type BroadcasterSP; + typedef SharedPtr<lldb_private::CommandObject>::Type CommandObjectSP; + typedef SharedPtr<lldb_private::Communication>::Type CommunicationSP; + typedef SharedPtr<lldb_private::CompileUnit>::Type CompUnitSP; + typedef SharedPtr<lldb_private::DataBuffer>::Type DataBufferSP; + typedef SharedPtr<lldb_private::DynamicLoader>::Type DynamicLoaderSP; + typedef SharedPtr<lldb_private::Event>::Type EventSP; + typedef SharedPtr<lldb_private::Function>::Type FunctionSP; + typedef SharedPtr<lldb_private::InlineFunctionInfo>::Type InlineFunctionInfoSP; + typedef SharedPtr<lldb_private::InputReader>::Type InputReaderSP; + typedef SharedPtr<lldb_private::LineTable>::Type LineTableSP; + typedef SharedPtr<lldb_private::Listener>::Type ListenerSP; + typedef SharedPtr<lldb_private::Log>::Type LogSP; + typedef SharedPtr<lldb_private::LogChannel>::Type LogChannelSP; + typedef SharedPtr<lldb_private::Module>::Type ModuleSP; + typedef SharedPtr<lldb_private::Process>::Type ProcessSP; + typedef SharedPtr<lldb_private::RegisterContext>::Type RegisterContextSP; + typedef SharedPtr<lldb_private::Section>::Type SectionSP; + typedef SharedPtr<lldb_private::SearchFilter>::Type SearchFilterSP; + typedef SharedPtr<lldb_private::StackFrame>::Type StackFrameSP; + typedef SharedPtr<lldb_private::StateVariable>::Type StateVariableSP; + typedef SharedPtr<lldb_private::StoppointLocation>::Type StoppointLocationSP; + typedef SharedPtr<lldb_private::Stream>::Type StreamSP; + typedef SharedPtr<lldb_private::SymbolFile>::Type SymbolFileSP; + typedef SharedPtr<lldb_private::Target>::Type TargetSP; + typedef SharedPtr<lldb_private::Thread>::Type ThreadSP; + typedef SharedPtr<lldb_private::ThreadPlan>::Type ThreadPlanSP; + typedef SharedPtr<lldb_private::Type>::Type TypeSP; + typedef SharedPtr<lldb_private::ValueObject>::Type ValueObjectSP; + typedef SharedPtr<lldb_private::Variable>::Type VariableSP; + typedef SharedPtr<lldb_private::VariableList>::Type VariableListSP; + +} // namespace lldb + +#endif // #ifndef NO_RTTI + +#endif // #if defined(__cplusplus) + +#endif // LLDB_forward_rtti_h_ diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h new file mode 100644 index 00000000000..9e69ca09f52 --- /dev/null +++ b/lldb/include/lldb/lldb-forward.h @@ -0,0 +1,149 @@ +//===-- lldb-forward.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_forward_h_ +#define LLDB_forward_h_ + +#if defined(__cplusplus) + +//---------------------------------------------------------------------- +// lldb forward declarations +//---------------------------------------------------------------------- +namespace lldb_private { + +class ABI; +class Address; +class AddressRange; +class AddressResolver; +class ArchSpec; +class Args; +class Baton; +class Block; +class BlockList; +class Breakpoint; +class BreakpointID; +class BreakpointIDList; +class BreakpointSite; +class BreakpointSiteList; +class BreakpointList; +class BreakpointLocation; +class BreakpointLocationCollection; +class BreakpointLocationList; +class BreakpointOptions; +class BreakpointResolver; +class Broadcaster; +class ClangASTContext; +class ClangExpression; +class ClangExpressionDeclMap; +class ClangExpressionVariableList; +class CommandContext; +class CommandInterpreter; +class CommandObject; +class CommandReturnObject; +class Communication; +class Condition; +class CompileUnit; +class Connection; +class ConnectionFileDescriptor; +class ConstString; +class DWARFCallFrameInfo; +class DWARFExpression; +class DataBuffer; +class DataExtractor; +class Debugger; +class Declaration; +class Disassembler; +class DynamicLoader; +class Error; +class Event; +class EventData; +class ExecutionContext; +class ExecutionContextScope; +class FileSpec; +class FileSpecList; +class Flags; +class Function; +class FunctionInfo; +class InlineFunctionInfo; +class InputReader; +struct LineEntry; +class LineTable; +class Listener; +class Log; +class LogChannel; +class Mangled; +class Module; +class ModuleList; +class Mutex; +class ObjCObjectPrinter; +class ObjectContainer; +class ObjectFile; +class Options; +class PathMappingList; +class Process; +class RegisterContext; +class RegisterLocation; +class RegisterLocationList; +class RegularExpression; +class Scalar; +class ScriptInterpreter; +class ScriptInterpreterPython; +class SearchFilter; +class Section; +class SectionList; +class SourceManager; +class StackFrame; +class StackFrameList; +class StackID; +class StateVariable; +class Stoppoint; +class StoppointCallbackContext; +class StoppointLocation; +class Stream; +class StreamFile; +class StreamString; +class StringList; +class Symbol; +class SymbolContext; +class SymbolContextList; +class SymbolContextScope; +class SymbolFile; +class SymbolVendor; +class Symtab; +class Target; +class TargetList; +class Thread; +class ThreadList; +class ThreadPlan; +class ThreadPlanContinue; +class ThreadPlanBase; +class ThreadPlanStepInstruction; +class ThreadPlanStepOut; +class ThreadPlanStepOverBreakpoint; +class ThreadPlanStepThrough; +class ThreadPlanStepRange; +class ThreadPlanRunToAddress; +class TimeValue; +class Type; +class TypeList; +class Unwind; +class UUID; +class VMRange; +class Value; +class ValueList; +class ValueObject; +class ValueObjectList; +class Variable; +class VariableList; +class WatchpointLocation; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // LLDB_forward_h_ diff --git a/lldb/include/lldb/lldb-include.h b/lldb/include/lldb/lldb-include.h new file mode 100644 index 00000000000..de415c48ad9 --- /dev/null +++ b/lldb/include/lldb/lldb-include.h @@ -0,0 +1,19 @@ +//===-- lldb-include.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_include_h_ +#define LLDB_include_h_ + +#include <LLDB/lldb-defines.h> +#include <LLDB/lldb-enumerations.h> +#include <LLDB/lldb-forward.h> +#include <LLDB/lldb-forward-rtti.h> +#include <LLDB/lldb-types.h> + +#endif // LLDB_include_h_ diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h new file mode 100644 index 00000000000..3cd8aab476b --- /dev/null +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -0,0 +1,37 @@ +//===-- lldb-private-interfaces.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_lldb_interfaces_h_ +#define liblldb_lldb_interfaces_h_ + +#if defined(__cplusplus) +#ifndef NO_RTTI + +#include "lldb/lldb-private.h" + +namespace lldb_private +{ + typedef ABI* (*ABICreateInstance) (const ConstString &triple); + typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch); + typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process); + typedef ObjectContainer* (*ObjectContainerCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length); + typedef ObjectFile* (*ObjectFileCreateInstance) (Module* module, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length); + typedef LogChannel* (*LogChannelCreateInstance) (); + typedef Process* (*ProcessCreateInstance) (Target &target, Listener &listener); + typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file); + typedef SymbolVendor* (*SymbolVendorCreateInstance) (Module *module); // Module can be NULL for default system symbol vendor + typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); + typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id, uint32_t type); + typedef ThreadPlan * (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton); +} // namespace lldb_private + +#endif // #ifndef NO_RTTI +#endif // #if defined(__cplusplus) + +#endif // liblldb_lldb_interfaces_h_ diff --git a/lldb/include/lldb/lldb-private-log.h b/lldb/include/lldb/lldb-private-log.h new file mode 100644 index 00000000000..394fe73e269 --- /dev/null +++ b/lldb/include/lldb/lldb-private-log.h @@ -0,0 +1,83 @@ +//===-- lldb-private-log.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_lldb_log_h_ +#define liblldb_lldb_log_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" + +//---------------------------------------------------------------------- +// Log Bits specific to logging in lldb +//---------------------------------------------------------------------- +#define LIBLLDB_LOG_VERBOSE (1u << 0) +#define LIBLLDB_LOG_PROCESS (1u << 1) +#define LIBLLDB_LOG_THREAD (1u << 2) +#define LIBLLDB_LOG_SHLIB (1u << 3) +#define LIBLLDB_LOG_EVENTS (1u << 4) +#define LIBLLDB_LOG_BREAKPOINTS (1u << 5) +#define LIBLLDB_LOG_WATCHPOINTS (1u << 6) +#define LIBLLDB_LOG_STEP (1u << 7) +#define LIBLLDB_LOG_EXPRESSIONS (1u << 8) +#define LIBLLDB_LOG_TEMPORARY (1u << 9) +#define LIBLLDB_LOG_STATE (1u << 10) +#define LIBLLDB_LOG_OBJECT (1u << 11) +#define LIBLLDB_LOG_COMMUNICATION (1u << 12) +#define LIBLLDB_LOG_CONNECTION (1u << 13) +#define LIBLLDB_LOG_ALL (UINT32_MAX) +#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ + LIBLLDB_LOG_THREAD |\ + LIBLLDB_LOG_SHLIB |\ + LIBLLDB_LOG_BREAKPOINTS |\ + LIBLLDB_LOG_WATCHPOINTS |\ + LIBLLDB_LOG_STEP |\ + LIBLLDB_LOG_STATE ) + +namespace lldb_private { + +uint32_t +GetLogMask (); + +void +LogIfAllCategoriesSet (uint32_t mask, const char *format, ...); + +void +LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...); + +Log * +GetLogIfAllCategoriesSet (uint32_t mask); + +Log * +GetLogIfAnyCategoriesSet (uint32_t mask); + +uint32_t +GetLogMask (); + +bool +IsLogVerbose (); + +void +DisableLog (); + +#ifndef NO_RTTI + +Log * +EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm); + +#endif + +void +ListLogCategories (Stream *strm); + +} // namespace lldb_private + +#endif // liblldb_lldb_log_h_ diff --git a/lldb/include/lldb/lldb-private.h b/lldb/include/lldb/lldb-private.h new file mode 100644 index 00000000000..a67ebf27c14 --- /dev/null +++ b/lldb/include/lldb/lldb-private.h @@ -0,0 +1,77 @@ +//===-- lldb-private.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_lldb_private_h_ +#define lldb_lldb_private_h_ + +#if defined(__cplusplus) + +#include "lldb/lldb-include.h" +#include "lldb/lldb-private-interfaces.h" +#include "lldb/lldb-private-log.h" + +namespace lldb_private { + +//------------------------------------------------------------------ +/// Initializes lldb. +/// +/// This function should be called prior to using any lldb +/// classes to ensure they have a chance to do any static +/// initialization that they need to do. +//------------------------------------------------------------------ +void +Initialize(); + + +//------------------------------------------------------------------ +/// Notifies any classes that lldb will be terminating soon. +/// +/// This function will be called when the Debugger shared instance +/// is being destructed and will give classes the ability to clean +/// up any threads or other resources they have that they might not +/// be able to clean up in their own destructors. +/// +/// Internal classes that need this ability will need to add their +/// void T::WillTerminate() method in the body of this function in +/// lldb.cpp to ensure it will get called. +/// +/// TODO: when we start having external plug-ins, we will need a way +/// for plug-ins to register a WillTerminate callback. +//------------------------------------------------------------------ +void +WillTerminate(); + +//------------------------------------------------------------------ +/// Terminates lldb +/// +/// This function optionally can be called when clients are done +/// using lldb functionality to free up any static resources +/// that have been allocated during initialization or during +/// function calls. No lldb functions should be called after +/// calling this function without again calling DCInitialize() +/// again. +//------------------------------------------------------------------ +void +Terminate(); + + +const char * +GetVersion (); + +// The function below can be moved into lldb::Debugger when/if we get one +ArchSpec & +GetDefaultArchitecture (); + +} // namespace lldb_private + + +#endif // defined(__cplusplus) + + +#endif // lldb_lldb_private_h_ diff --git a/lldb/include/lldb/lldb-types.h b/lldb/include/lldb/lldb-types.h new file mode 100644 index 00000000000..c83a3861fd9 --- /dev/null +++ b/lldb/include/lldb/lldb-types.h @@ -0,0 +1,168 @@ +//===-- lldb-types.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_types_h_ +#define LLDB_types_h_ + +#include <LLDB/lldb-enumerations.h> +#include <LLDB/lldb-forward.h> + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// MACOSX START +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- + +#include <assert.h> +#include <mach/mach_types.h> +#include <machine/endian.h> +#include <pthread.h> +#include <signal.h> +#include <stdint.h> +#include <stdbool.h> +#include <sys/syslimits.h> +#include <unistd.h> + +#ifndef NO_RTTI + +//---------------------------------------------------------------------- +// And source files that may not have RTTI enabled during their +// compilation will want to do a "#define NO_RTTI" before including the +// lldb-include.h file. +//---------------------------------------------------------------------- + +#include <tr1/memory> // for std::tr1::shared_ptr + +#endif + +//---------------------------------------------------------------------- +// All host systems must define: +// liblldb::condition_t The native condition type (or a substitute class) for conditions on the host system. +// liblldb::mutex_t The native mutex type for mutex objects on the host system. +// liblldb::thread_t The native thread type for spawned threads on the system +// liblldb::thread_arg_t The type of the one any only thread creation argument for the host system +// liblldb::thread_result_t The return type that gets returned when a thread finishes. +// liblldb::thread_func_t The function prototype used to spawn a thread on the host system. +// liblldb::SharedPtr The template that wraps up the host version of a reference counted pointer (like boost::shared_ptr) +// #define LLDB_INVALID_PROCESS_ID ... +// #define LLDB_INVALID_THREAD_ID ... +// #define LLDB_INVALID_HOST_THREAD ... +//---------------------------------------------------------------------- + +// TODO: Add a bunch of ifdefs to determine the host system and what +// things should be defined. Currently MacOSX is being assumed by default +// since that is what lldb was first developed for. + +namespace lldb { + //---------------------------------------------------------------------- + // MacOSX Types + //---------------------------------------------------------------------- + typedef ::pthread_mutex_t mutex_t; + typedef pthread_cond_t condition_t; + typedef pthread_t thread_t; // Host thread type + typedef void * thread_arg_t; // Host thread argument type + typedef void * thread_result_t; // Host thread result type + typedef void * (*thread_func_t)(void *); // Host thread function type + +#ifndef NO_RTTI + // The template below can be used in a few useful ways: + // + // // Make a single shared pointer a class Foo + // lldb::SharePtr<Foo>::Type foo_sp; + // + // // Make a typedef to a Foo shared pointer + // typedef lldb::SharePtr<Foo>::Type FooSP; + // + template<typename _Tp> + struct SharedPtr + { + typedef std::tr1::shared_ptr<_Tp> Type; + }; +#endif + +} // namespace lldb + +#define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL) +#define LLDB_INVALID_HOST_TIME { 0, 0 } + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// MACOSX END +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- + +#ifdef SWIG +#define CONST_CHAR_PTR char * +#else +#define CONST_CHAR_PTR const char * +#endif + +namespace lldb { + typedef uint64_t addr_t; + typedef uint32_t user_id_t; + typedef int32_t pid_t; + typedef uint32_t tid_t; + typedef int32_t break_id_t; + + //---------------------------------------------------------------------- + // Every register is described in detail including its name, alternate + // name (optional), encoding, size in bytes and the default display + // format. + //---------------------------------------------------------------------- + typedef struct + { + CONST_CHAR_PTR name; // Name of this register, can't be NULL + CONST_CHAR_PTR alt_name; // Alternate name of this register, can be NULL + uint32_t byte_size; // Size in bytes of the register + uint32_t byte_offset; // The byte offset in the register context data where this register's value is found + lldb::Encoding encoding; // Encoding of the register bits + lldb::Format format; // Default display format + uint32_t reg; // The native register number for this register + uint32_t kinds[kNumRegisterKinds]; // Holds all of the various register numbers for all register kinds + } RegisterInfo; + + //---------------------------------------------------------------------- + // Registers are grouped into register sets + //---------------------------------------------------------------------- + typedef struct + { + CONST_CHAR_PTR name; // Name of this register set + CONST_CHAR_PTR short_name; // A short name for this register set + size_t num_registers; // The number of registers in REGISTERS array below + const uint32_t *registers; // An array of register numbers in this set + } RegisterSet; + + typedef struct + { + int value; + CONST_CHAR_PTR string_value; + CONST_CHAR_PTR usage; + } OptionEnumValueElement; + + typedef struct + { + uint32_t usage_level; // Used to mark options that can be used together. + bool required; // This option is required (in the current usage level) + CONST_CHAR_PTR long_option; // Full name for this option. + char short_option; // Single character for this option. + int option_has_arg; // no_argument, required_argument or optional_argument + OptionEnumValueElement *enum_values;// If non-NULL an array of enum values. + uint32_t completionType; // Cookie the option class can use to do define the argument completion. + CONST_CHAR_PTR argument_name; // Text name to be use in usage text to refer to the option's value. + CONST_CHAR_PTR usage_text; // Full text explaining what this options does and what (if any) argument to + // pass it. + } OptionDefinition; + + + typedef int (*comparison_function)(const void *, const void *); +} + +#undef CONST_CHAR_PTR + +#endif // LLDB_types_h_ |