diff options
author | Ed Maste <emaste@FreeBSD.org> | 2014-02-18 16:23:10 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2014-02-18 16:23:10 +0000 |
commit | 866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec (patch) | |
tree | 95cb16075f0af1b3a05b9b84eb18dda8e6c903e9 /include | |
parent | de889deb2c386f2a7831befaf226e5c86685fa53 (diff) | |
download | src-test2-866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec.tar.gz src-test2-866dcdacfe59f5f448e008fe2c4cb9dfcf72b2ec.zip |
Notes
Diffstat (limited to 'include')
82 files changed, 3203 insertions, 937 deletions
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index 93bc3bc121e2..b9c3198b73e5 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -33,13 +33,14 @@ #include "lldb/API/SBFrame.h" #include "lldb/API/SBFunction.h" #include "lldb/API/SBHostOS.h" -#include "lldb/API/SBInputReader.h" #include "lldb/API/SBInstruction.h" #include "lldb/API/SBInstructionList.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBListener.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBQueue.h" +#include "lldb/API/SBQueueItem.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" diff --git a/include/lldb/API/SBAddress.h b/include/lldb/API/SBAddress.h index c5e8cc685a4c..58a7d2bfb1da 100644 --- a/include/lldb/API/SBAddress.h +++ b/include/lldb/API/SBAddress.h @@ -118,6 +118,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class SBQueueItem; lldb_private::Address * operator->(); diff --git a/include/lldb/API/SBCommandInterpreter.h b/include/lldb/API/SBCommandInterpreter.h index 9b2583cd85ca..184a6b473126 100644 --- a/include/lldb/API/SBCommandInterpreter.h +++ b/include/lldb/API/SBCommandInterpreter.h @@ -122,6 +122,36 @@ public: SBCommandInterpreter (lldb_private::CommandInterpreter *interpreter_ptr = NULL); // Access using SBDebugger::GetCommandInterpreter(); + //---------------------------------------------------------------------- + /// Return true if the command interpreter is the active IO handler. + /// + /// This indicates that any input coming into the debugger handles will + /// go to the command interpreter and will result in LLDB command line + /// commands being executed. + //---------------------------------------------------------------------- + bool + IsActive (); + + //---------------------------------------------------------------------- + /// Get the string that needs to be written to the debugger stdin file + /// handle when a control character is typed. + /// + /// Some GUI programs will intercept "control + char" sequences and want + /// to have them do what normally would happen when using a real + /// terminal, so this function allows GUI programs to emulate this + /// functionality. + /// + /// @param[in] ch + /// The character that was typed along with the control key + /// + /// @return + /// The string that should be written into the file handle that is + /// feeding the input stream for the debugger, or NULL if there is + /// no string for this control key. + //---------------------------------------------------------------------- + const char * + GetIOHandlerControlSequence(char ch); + protected: lldb_private::CommandInterpreter & diff --git a/include/lldb/API/SBDebugger.h b/include/lldb/API/SBDebugger.h index 80e6969cbd3a..2386ffc968de 100644 --- a/include/lldb/API/SBDebugger.h +++ b/include/lldb/API/SBDebugger.h @@ -17,6 +17,16 @@ namespace lldb { + +class SBInputReader +{ +public: + SBInputReader(); + ~SBInputReader(); + SBError Initialize(lldb::SBDebugger&, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool); + void SetIsDone(bool); + bool IsActive() const; +}; class SBDebugger { public: @@ -231,12 +241,6 @@ public: void PushInputReader (lldb::SBInputReader &reader); - void - NotifyTopInputReader (lldb::InputReaderAction notification); - - bool - InputReaderIsTopReader (const lldb::SBInputReader &reader); - const char * GetInstanceName (); @@ -313,6 +317,10 @@ public: GetSyntheticForType (SBTypeNameSpecifier); #endif + void + RunCommandInterpreter (bool auto_handle_events, + bool spawn_thread); + private: friend class SBCommandInterpreter; diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index 2cdf92170d8d..8779d43d1f40 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -48,7 +48,6 @@ class SBFileSpecList; class SBFrame; class SBFunction; class SBHostOS; -class SBInputReader; class SBInstruction; class SBInstructionList; class SBLineEntry; diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h index 12b34ec6dbc3..25d7e81a3be5 100644 --- a/include/lldb/API/SBError.h +++ b/include/lldb/API/SBError.h @@ -71,7 +71,6 @@ protected: friend class SBDebugger; friend class SBCommunication; friend class SBHostOS; - friend class SBInputReader; friend class SBPlatform; friend class SBProcess; friend class SBThread; diff --git a/include/lldb/API/SBInputReader.h b/include/lldb/API/SBInputReader.h deleted file mode 100644 index 61f7de4fde4c..000000000000 --- a/include/lldb/API/SBInputReader.h +++ /dev/null @@ -1,97 +0,0 @@ -//===-- 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/API/SBDefines.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 (SBDebugger &debugger, - Callback callback, - void *callback_baton, - lldb::InputReaderGranularity granularity, - const char *end_token, - const char *prompt, - bool echo); - - bool - IsValid () const; - - const lldb::SBInputReader & - operator = (const lldb::SBInputReader &rhs); - - bool - IsActive () const; - - bool - IsDone () const; - - void - SetIsDone (bool value); - - InputReaderGranularity - GetGranularity (); - -protected: - friend class SBDebugger; - - lldb_private::InputReader * - operator->() const; - - lldb::InputReaderSP & - operator *(); - - const lldb::InputReaderSP & - operator *() const; - - lldb_private::InputReader * - get() const; - - lldb_private::InputReader & - ref() 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_opaque_sp; - Callback m_callback_function; - void *m_callback_baton; -}; - -} // namespace lldb - -#endif // LLDB_SBInputReader_h_ diff --git a/include/lldb/API/SBModule.h b/include/lldb/API/SBModule.h index f5955b39734d..e85654bccc72 100644 --- a/include/lldb/API/SBModule.h +++ b/include/lldb/API/SBModule.h @@ -235,6 +235,25 @@ public: lldb::SBTypeList FindTypes (const char* type); + //------------------------------------------------------------------ + /// Get a type using its type ID. + /// + /// Each symbol file reader will assign different user IDs to their + /// types, but it is sometimes useful when debugging type issues to + /// be able to grab a type using its type ID. + /// + /// For DWARF debug info, the type ID is the DIE offset. + /// + /// @param[in] uid + /// The type user ID. + /// + /// @return + /// An SBType for the given type ID, or an empty SBType if the + /// type was not found. + //------------------------------------------------------------------ + lldb::SBType + GetTypeByID (lldb::user_id_t uid); + lldb::SBType GetBasicType(lldb::BasicType type); diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index 4ecaeaa49920..f2846710c614 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -13,6 +13,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" #include "lldb/API/SBTarget.h" +#include "lldb/API/SBQueue.h" #include <stdio.h> namespace lldb { @@ -142,6 +143,15 @@ public: SetSelectedThreadByIndexID (uint32_t index_id); //------------------------------------------------------------------ + // Queue related functions + //------------------------------------------------------------------ + uint32_t + GetNumQueues (); + + lldb::SBQueue + GetQueueAtIndex (size_t index); + + //------------------------------------------------------------------ // Stepping related functions //------------------------------------------------------------------ @@ -312,6 +322,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class lldb_private::QueueImpl; lldb::ProcessSP GetSP() const; diff --git a/include/lldb/API/SBQueue.h b/include/lldb/API/SBQueue.h new file mode 100644 index 000000000000..6ab9aa09f466 --- /dev/null +++ b/include/lldb/API/SBQueue.h @@ -0,0 +1,83 @@ +//===-- SBQueue.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_SBQueue_h_ +#define LLDB_SBQueue_h_ + +#include <vector> + +#include "lldb/lldb-forward.h" +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBQueueItem.h" + +namespace lldb { + +class SBQueue +{ +public: + SBQueue (); + + SBQueue (const QueueSP& queue_sp); + + SBQueue (const SBQueue& rhs); + + const SBQueue & + operator= (const lldb::SBQueue& rhs); + + ~SBQueue(); + + bool + IsValid() const; + + void + Clear (); + + lldb::SBProcess + GetProcess (); + + lldb::queue_id_t + GetQueueID () const; + + const char * + GetName () const; + + uint32_t + GetIndexID () const; + + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (uint32_t); + + uint32_t + GetNumPendingItems (); + + lldb::SBQueueItem + GetPendingItemAtIndex (uint32_t); + +protected: + friend class SBProcess; + + void + SetQueue (const lldb::QueueSP& queue_sp); + + void + FetchThreads (); + + void + FetchItems (); + +private: + std::shared_ptr<lldb_private::QueueImpl> m_opaque_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBQueue_h_ diff --git a/include/lldb/API/SBQueueItem.h b/include/lldb/API/SBQueueItem.h new file mode 100644 index 000000000000..355c5ac90a23 --- /dev/null +++ b/include/lldb/API/SBQueueItem.h @@ -0,0 +1,58 @@ +//===-- SBQueueItem.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_SBQueueItem_h_ +#define LLDB_SBQueueItem_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBThread.h" + +namespace lldb { + +class SBQueueItem +{ +public: + SBQueueItem (); + + SBQueueItem (const lldb::QueueItemSP& queue_item_sp); + + ~SBQueueItem(); + + bool + IsValid() const; + + void + Clear (); + + lldb::QueueItemKind + GetKind () const; + + void + SetKind (lldb::QueueItemKind kind); + + lldb::SBAddress + GetAddress () const; + + void + SetAddress (lldb::SBAddress addr); + + void + SetQueueItem (const lldb::QueueItemSP& queue_item_sp); + + SBThread + GetExtendedBacktraceThread (const char *type); + +private: + lldb::QueueItemSP m_queue_item_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBQueueItem_h_ diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index b41c11811549..230dffc68251 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -646,9 +646,47 @@ public: void Clear (); + //------------------------------------------------------------------ + /// Resolve a current load address into a section offset address. + /// + /// @param[in] vm_addr + /// A virtual address from the current process state that is to + /// be translated into a section offset address. + /// + /// @return + /// An SBAddress which will be valid if \a vm_addr was + /// successfully resolved into a section offset address, or an + /// invalid SBAddress if \a vm_addr doesn't resolve to a section + /// in a module. + //------------------------------------------------------------------ lldb::SBAddress ResolveLoadAddress (lldb::addr_t vm_addr); + //------------------------------------------------------------------ + /// Resolve a current load address into a section offset address + /// using the process stop ID to identify a time in the past. + /// + /// @param[in] stop_id + /// Each time a process stops, the process stop ID integer gets + /// incremented. These stop IDs are used to identify past times + /// and can be used in history objects as a cheap way to store + /// the time at which the sample was taken. Specifying + /// UINT32_MAX will always resolve the address using the + /// currently loaded sections. + /// + /// @param[in] vm_addr + /// A virtual address from the current process state that is to + /// be translated into a section offset address. + /// + /// @return + /// An SBAddress which will be valid if \a vm_addr was + /// successfully resolved into a section offset address, or an + /// invalid SBAddress if \a vm_addr doesn't resolve to a section + /// in a module. + //------------------------------------------------------------------ + lldb::SBAddress + ResolvePastLoadAddress (uint32_t stop_id, lldb::addr_t vm_addr); + SBSymbolContext ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope); diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index 6542dca1f95a..04b6c86e6d89 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -214,6 +214,8 @@ protected: friend class SBProcess; friend class SBDebugger; friend class SBValue; + friend class lldb_private::QueueImpl; + friend class SBQueueItem; void SetThread (const lldb::ThreadSP& lldb_object_sp); diff --git a/include/lldb/API/SBType.h b/include/lldb/API/SBType.h index 3729b2f84b90..2cd9b4459a33 100644 --- a/include/lldb/API/SBType.h +++ b/include/lldb/API/SBType.h @@ -106,6 +106,9 @@ public: GetReferenceType(); lldb::SBType + GetTypedefedType(); + + lldb::SBType GetDereferencedType(); lldb::SBType diff --git a/include/lldb/API/SBTypeFormat.h b/include/lldb/API/SBTypeFormat.h index cd6345fbe6fa..eb45ff2b0eba 100644 --- a/include/lldb/API/SBTypeFormat.h +++ b/include/lldb/API/SBTypeFormat.h @@ -22,6 +22,9 @@ public: SBTypeFormat (lldb::Format format, uint32_t options = 0); // see lldb::eTypeOption values + + SBTypeFormat (const char* type, + uint32_t options = 0); // see lldb::eTypeOption values SBTypeFormat (const lldb::SBTypeFormat &rhs); @@ -33,6 +36,9 @@ public: lldb::Format GetFormat (); + const char* + GetTypeName (); + uint32_t GetOptions(); @@ -40,6 +46,9 @@ public: SetFormat (lldb::Format); void + SetTypeName (const char*); + + void SetOptions (uint32_t); bool @@ -73,8 +82,15 @@ protected: SBTypeFormat (const lldb::TypeFormatImplSP &); + enum class Type + { + eTypeKeepSame, + eTypeFormat, + eTypeEnum + }; + bool - CopyOnWrite_Impl(); + CopyOnWrite_Impl(Type); }; diff --git a/include/lldb/Breakpoint/Breakpoint.h b/include/lldb/Breakpoint/Breakpoint.h index e82d6eacf7a8..749ff8d1a09c 100644 --- a/include/lldb/Breakpoint/Breakpoint.h +++ b/include/lldb/Breakpoint/Breakpoint.h @@ -612,12 +612,30 @@ protected: /// 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. + /// + /// @param[in] target + /// The target in which the breakpoint will be set. + /// + /// @param[in] filter_sp + /// Shared pointer to the search filter that restricts the search domain of the breakpoint. + /// + /// @param[in] resolver_sp + /// Shared pointer to the resolver object that will determine breakpoint matches. + /// + /// @param hardware + /// If true, request a hardware breakpoint to be used to implement the breakpoint locations. + /// + /// @param resolve_indirect_symbols + /// If true, and the address of a given breakpoint location in this breakpoint is set on an + /// indirect symbol (i.e. Symbol::IsIndirect returns true) then the actual breakpoint site will + /// be set on the target of the indirect symbol. //------------------------------------------------------------------ // This is the generic constructor Breakpoint(Target &target, lldb::SearchFilterSP &filter_sp, lldb::BreakpointResolverSP &resolver_sp, - bool hardware); + bool hardware, + bool resolve_indirect_symbols = true); friend class BreakpointLocation; // To call the following two when determining whether to stop. @@ -643,6 +661,7 @@ private: BreakpointOptions m_options; // Settable breakpoint options BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint. std::string m_kind_description; + bool m_resolve_indirect_symbols; void SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind); diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h index f4ba21a385f8..ac4c28bb6e5f 100644 --- a/include/lldb/Breakpoint/BreakpointLocation.h +++ b/include/lldb/Breakpoint/BreakpointLocation.h @@ -321,7 +321,59 @@ public: //------------------------------------------------------------------ bool InvokeCallback (StoppointCallbackContext *context); + + //------------------------------------------------------------------ + /// Returns whether we should resolve Indirect functions in setting the breakpoint site + /// for this location. + /// + /// @return + /// \b true if the breakpoint SITE for this location should be set on the + /// resolved location for Indirect functions. + //------------------------------------------------------------------ + bool + ShouldResolveIndirectFunctions () + { + return m_should_resolve_indirect_functions; + } + //------------------------------------------------------------------ + /// Returns whether the address set in the breakpoint site for this location was found by resolving + /// an indirect symbol. + /// + /// @return + /// \b true or \b false as given in the description above. + //------------------------------------------------------------------ + bool + IsIndirect () + { + return m_is_indirect; + } + + void + SetIsIndirect (bool is_indirect) + { + m_is_indirect = is_indirect; + } + + //------------------------------------------------------------------ + /// Returns whether the address set in the breakpoint location was re-routed to the target of a + /// re-exported symbol. + /// + /// @return + /// \b true or \b false as given in the description above. + //------------------------------------------------------------------ + bool + IsReExported () + { + return m_is_reexported; + } + + void + SetIsReExported (bool is_reexported) + { + m_is_reexported = is_reexported; + } + protected: friend class BreakpointLocationList; friend class Process; @@ -375,12 +427,16 @@ private: Breakpoint &owner, const Address &addr, lldb::tid_t tid, - bool hardware); - + bool hardware, + bool check_for_resolver = true); + //------------------------------------------------------------------ // Data members: //------------------------------------------------------------------ bool m_being_created; + bool m_should_resolve_indirect_functions; + bool m_is_reexported; + bool m_is_indirect; Address m_address; ///< The address defining this location. Breakpoint &m_owner; ///< The breakpoint that produced this object. std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options. @@ -390,6 +446,12 @@ private: size_t m_condition_hash; ///< For testing whether the condition source code changed. void + SetShouldResolveIndirectFunctions (bool do_resolve) + { + m_should_resolve_indirect_functions = do_resolve; + } + + void SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind); DISALLOW_COPY_AND_ASSIGN (BreakpointLocation); diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h index b25208659c7f..ec34641b727c 100644 --- a/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/include/lldb/Breakpoint/BreakpointLocationList.h @@ -236,7 +236,7 @@ protected: /// Returns breakpoint location id. //------------------------------------------------------------------ lldb::BreakpointLocationSP - Create (const Address &addr); + Create (const Address &addr, bool resolve_indirect_symbols); void StartRecordingNewLocations(BreakpointLocationCollection &new_locations); @@ -246,6 +246,7 @@ protected: lldb::BreakpointLocationSP AddLocation (const Address &addr, + bool resolve_indirect_symbols, bool *new_location = NULL); bool diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 7f2fd77a0934..4ec8e06c8b35 100644 --- a/include/lldb/Core/ArchSpec.h +++ b/include/lldb/Core/ArchSpec.h @@ -13,6 +13,7 @@ #if defined(__cplusplus) #include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" @@ -90,6 +91,7 @@ public: eCore_x86_32_i486sx, eCore_x86_64_x86_64, + eCore_x86_64_x86_64h, // Haswell enabled x86_64 eCore_uknownMach32, eCore_uknownMach64, kNumCores, @@ -203,6 +205,27 @@ public: GetMachine () const; //------------------------------------------------------------------ + /// Returns the distribution id of the architecture. + /// + /// This will be something like "ubuntu", "fedora", etc. on Linux. + /// + /// @return A ConstString ref containing the distribution id, + /// potentially empty. + //------------------------------------------------------------------ + const ConstString& + GetDistributionId () const; + + //------------------------------------------------------------------ + /// Set the distribution id of the architecture. + /// + /// This will be something like "ubuntu", "fedora", etc. on Linux. + /// This should be the same value returned by + /// Host::GetDistributionId (). + ///------------------------------------------------------------------ + void + SetDistributionId (const char* distribution_id); + + //------------------------------------------------------------------ /// Tests if this ArchSpec is valid. /// /// @return True if the current architecture is valid, false @@ -400,6 +423,8 @@ protected: Core m_core; lldb::ByteOrder m_byte_order; + ConstString m_distribution_id; + // Called when m_def or m_entry are changed. Fills in all remaining // members with default values. void diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h index 98d4dfd011b8..2dde55044171 100644 --- a/include/lldb/Core/Communication.h +++ b/include/lldb/Core/Communication.h @@ -286,6 +286,8 @@ public: virtual bool StopReadThread (Error *error_ptr = NULL); + virtual bool + JoinReadThread (Error *error_ptr = NULL); //------------------------------------------------------------------ /// Checks if there is a currently running read thread. /// diff --git a/include/lldb/Core/ConnectionFileDescriptor.h b/include/lldb/Core/ConnectionFileDescriptor.h index 3a2f0dd1ed0b..15598c9b1335 100644 --- a/include/lldb/Core/ConnectionFileDescriptor.h +++ b/include/lldb/Core/ConnectionFileDescriptor.h @@ -11,9 +11,7 @@ #define liblldb_ConnectionFileDescriptor_h_ // C Includes -#ifdef _WIN32 -typedef unsigned short in_port_t; -#else +#ifndef _WIN32 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> @@ -68,14 +66,17 @@ public: // If the read file descriptor is a socket, then return // the port number that is being used by the socket. - in_port_t + uint16_t GetReadPort () const; // If the write file descriptor is a socket, then return // the port number that is being used by the socket. - in_port_t + uint16_t GetWritePort () const; + uint16_t + GetBoundPort (uint32_t timeout_sec); + protected: typedef enum @@ -95,7 +96,7 @@ protected: BytesAvailable (uint32_t timeout_usec, Error *error_ptr); lldb::ConnectionStatus - SocketListen (uint16_t listen_port_num, Error *error_ptr); + SocketListen (const char *host_and_port, Error *error_ptr); lldb::ConnectionStatus ConnectTCP (const char *host_and_port, Error *error_ptr); @@ -117,15 +118,16 @@ protected: FDType m_fd_send_type; FDType m_fd_recv_type; std::unique_ptr<SocketAddress> m_udp_send_sockaddr; - bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. uint32_t m_socket_timeout_usec; int m_pipe_read; // A pipe that we select on the reading end of along with int m_pipe_write; // m_fd_recv so we can force ourselves out of the select. - Mutex m_mutex; + Mutex m_mutex; + Predicate<uint16_t> m_port_predicate; // Used when binding to port zero to wait for the thread that creates the socket, binds and listens to resolve the port number + bool m_should_close_fd; // True if this class should close the file descriptor when it goes away. bool m_shutting_down; // This marks that we are shutting down so if we get woken up from BytesAvailable // to disconnect, we won't try to read again. - static in_port_t + static uint16_t GetSocketPort (int fd); static int diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index a3c6d5eeb93d..e80ec8516793 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -19,9 +19,8 @@ #include "lldb/lldb-public.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Communication.h" -#include "lldb/Core/InputReaderStack.h" +#include "lldb/Core/IOHandler.h" #include "lldb/Core/Listener.h" -#include "lldb/Core/StreamFile.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserID.h" #include "lldb/Core/UserSettingsController.h" @@ -91,23 +90,25 @@ public: void SetAsyncExecution (bool async); - File & + lldb::StreamFileSP GetInputFile () { - return m_input_file.GetFile(); + return m_input_file_sp; } - File & + lldb::StreamFileSP GetOutputFile () { - return m_output_file.GetFile(); + return m_output_file_sp; } - File & + lldb::StreamFileSP GetErrorFile () { - return m_error_file.GetFile(); + return m_error_file_sp; } + + void SetInputFileHandle (FILE *fh, bool tranfer_ownership); @@ -124,18 +125,6 @@ public: void RestoreInputTerminalState(); - Stream& - GetOutputStream () - { - return m_output_file; - } - - Stream& - GetErrorStream () - { - return m_error_file; - } - lldb::StreamSP GetAsyncOutputStream (); @@ -200,24 +189,38 @@ public: void DispatchInputEndOfFile (); + //------------------------------------------------------------------ + // If any of the streams are not set, set them to the in/out/err + // stream of the top most input reader to ensure they at least have + // something + //------------------------------------------------------------------ void - DispatchInput (const char *bytes, size_t bytes_len); + AdoptTopIOHandlerFilesIfInvalid (lldb::StreamFileSP &in, + lldb::StreamFileSP &out, + lldb::StreamFileSP &err); void - WriteToDefaultReader (const char *bytes, size_t bytes_len); + PushIOHandler (const lldb::IOHandlerSP& reader_sp); + bool + PopIOHandler (const lldb::IOHandlerSP& reader_sp); + + // Synchronously run an input reader until it is done void - PushInputReader (const lldb::InputReaderSP& reader_sp); + RunIOHandler (const lldb::IOHandlerSP& reader_sp); + + bool + IsTopIOHandler (const lldb::IOHandlerSP& reader_sp); + + ConstString + GetTopIOHandlerControlSequence(char ch); bool - PopInputReader (const lldb::InputReaderSP& reader_sp); + HideTopIOHandler(); void - NotifyTopInputReader (lldb::InputReaderAction notification); + RefreshTopIOHandler(); - bool - InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp); - static lldb::DebuggerSP FindDebuggerWithID (lldb::user_id_t id); @@ -240,7 +243,7 @@ public: void - CleanUpInputReaders (); + ClearIOHandlers (); static int TestDebuggerRefCount (); @@ -338,29 +341,65 @@ public: bool LoadPlugin (const FileSpec& spec, Error& error); + void + ExecuteIOHanders(); + + bool + IsForwardingEvents (); + + void + EnableForwardEvents (const lldb::ListenerSP &listener_sp); + + void + CancelForwardEvents (const lldb::ListenerSP &listener_sp); protected: - static void - DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len); + friend class CommandInterpreter; + + bool + StartEventHandlerThread(); - lldb::InputReaderSP - GetCurrentInputReader (); - void - ActivateInputReader (const lldb::InputReaderSP &reader_sp); + StopEventHandlerThread(); + + static lldb::thread_result_t + EventHandlerThread (lldb::thread_arg_t arg); bool - CheckIfTopInputReaderIsDone (); + StartIOHandlerThread(); + + void + StopIOHandlerThread(); + static lldb::thread_result_t + IOHandlerThread (lldb::thread_arg_t arg); + + void + DefaultEventHandler(); + + void + HandleBreakpointEvent (const lldb::EventSP &event_sp); + + void + HandleProcessEvent (const lldb::EventSP &event_sp); + + void + HandleThreadEvent (const lldb::EventSP &event_sp); + + size_t + GetProcessSTDOUT (Process *process, Stream *stream); + + size_t + GetProcessSTDERR (Process *process, Stream *stream); + SourceManager::SourceFileCache & GetSourceFileCache () { return m_source_file_cache; } - Communication m_input_comm; - StreamFile m_input_file; - StreamFile m_output_file; - StreamFile m_error_file; + lldb::StreamFileSP m_input_file_sp; + lldb::StreamFileSP m_output_file_sp; + lldb::StreamFileSP m_error_file_sp; TerminalState m_terminal_state; TargetList m_target_list; PlatformList m_platform_list; @@ -370,8 +409,7 @@ protected: // source file cache. std::unique_ptr<CommandInterpreter> m_command_interpreter_ap; - InputReaderStack m_input_reader_stack; - std::string m_input_reader_data; + IOHandlerStack m_input_reader_stack; typedef std::map<std::string, lldb::StreamWP> LogStreamMap; LogStreamMap m_log_streams; lldb::StreamSP m_log_callback_stream_sp; @@ -379,7 +417,10 @@ protected: static LoadPluginCallbackType g_load_plugin_callback; typedef std::vector<lldb::DynamicLibrarySP> LoadedPluginsList; LoadedPluginsList m_loaded_plugins; - + lldb::thread_t m_event_handler_thread; + lldb::thread_t m_io_handler_thread; + lldb::ListenerSP m_forward_listener_sp; + bool m_event_handler_thread_alive; void InstanceInitialize (); diff --git a/include/lldb/Core/Disassembler.h b/include/lldb/Core/Disassembler.h index f434d56943d4..06a703b4c1aa 100644 --- a/include/lldb/Core/Disassembler.h +++ b/include/lldb/Core/Disassembler.h @@ -175,6 +175,9 @@ public: uint32_t GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target); + uint32_t + GetIndexOfInstructionAtAddress (const Address &addr); + void Clear(); diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h new file mode 100644 index 000000000000..a7d4880da0d3 --- /dev/null +++ b/include/lldb/Core/IOHandler.h @@ -0,0 +1,646 @@ +//===-- IOHandler.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_IOHandler_h_ +#define liblldb_IOHandler_h_ + +#include <string.h> + +#include <stack> + +#include "lldb/lldb-public.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Flags.h" +#include "lldb/Core/StringList.h" +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Host/Mutex.h" + +namespace curses +{ + class Application; + typedef std::unique_ptr<Application> ApplicationAP; +} + +namespace lldb_private { + + class IOHandler + { + public: + IOHandler (Debugger &debugger); + + IOHandler (Debugger &debugger, + const lldb::StreamFileSP &input_sp, + const lldb::StreamFileSP &output_sp, + const lldb::StreamFileSP &error_sp, + uint32_t flags); + + virtual + ~IOHandler (); + + // Each IOHandler gets to run until it is done. It should read data + // from the "in" and place output into "out" and "err and return + // when done. + virtual void + Run () = 0; + + // Hide any characters that have been displayed so far so async + // output can be displayed. Refresh() will be called after the + // output has been displayed. + virtual void + Hide () = 0; + + // Called when the async output has been received in order to update + // the input reader (refresh the prompt and redisplay any current + // line(s) that are being edited + virtual void + Refresh () = 0; + + virtual void + Interrupt () = 0; + + virtual void + GotEOF() = 0; + + virtual bool + IsActive () + { + return m_active && !m_done; + } + + virtual void + SetIsDone (bool b) + { + m_done = b; + } + + virtual bool + GetIsDone () + { + return m_done; + } + + virtual void + Activate () + { + m_active = true; + } + + virtual void + Deactivate () + { + m_active = false; + } + + virtual const char * + GetPrompt () + { + // Prompt support isn't mandatory + return NULL; + } + + virtual bool + SetPrompt (const char *prompt) + { + // Prompt support isn't mandatory + return false; + } + + virtual ConstString + GetControlSequence (char ch) + { + return ConstString(); + } + + int + GetInputFD(); + + int + GetOutputFD(); + + int + GetErrorFD(); + + FILE * + GetInputFILE(); + + FILE * + GetOutputFILE(); + + FILE * + GetErrorFILE(); + + lldb::StreamFileSP & + GetInputStreamFile(); + + lldb::StreamFileSP & + GetOutputStreamFile(); + + lldb::StreamFileSP & + GetErrorStreamFile(); + + Debugger & + GetDebugger() + { + return m_debugger; + } + + void * + GetUserData () + { + return m_user_data; + } + + void + SetUserData (void *user_data) + { + m_user_data = user_data; + } + + Flags & + GetFlags () + { + return m_flags; + } + + const Flags & + GetFlags () const + { + return m_flags; + } + + //------------------------------------------------------------------ + /// Check if the input is being supplied interactively by a user + /// + /// This will return true if the input stream is a terminal (tty or + /// pty) and can cause IO handlers to do different things (like + /// for a comfirmation when deleting all breakpoints). + //------------------------------------------------------------------ + bool + GetIsInteractive (); + + //------------------------------------------------------------------ + /// Check if the input is coming from a real terminal. + /// + /// A real terminal has a valid size with a certain number of rows + /// and colums. If this function returns true, then terminal escape + /// sequences are expected to work (cursor movement escape sequences, + /// clearning lines, etc). + //------------------------------------------------------------------ + bool + GetIsRealTerminal (); + + protected: + Debugger &m_debugger; + lldb::StreamFileSP m_input_sp; + lldb::StreamFileSP m_output_sp; + lldb::StreamFileSP m_error_sp; + Flags m_flags; + void *m_user_data; + bool m_done; + bool m_active; + + private: + DISALLOW_COPY_AND_ASSIGN (IOHandler); + }; + + + //------------------------------------------------------------------ + /// A delegate class for use with IOHandler subclasses. + /// + /// The IOHandler delegate is designed to be mixed into classes so + /// they can use an IOHandler subclass to fetch input and notify the + /// object that inherits from this delegate class when a token is + /// received. + //------------------------------------------------------------------ + class IOHandlerDelegate + { + public: + enum class Completion { + None, + LLDBCommand, + Expression + }; + + IOHandlerDelegate (Completion completion = Completion::None) : + m_completion(completion), + m_io_handler_done (false) + { + } + + virtual + ~IOHandlerDelegate() + { + } + + virtual void + IOHandlerActivated (IOHandler &io_handler) + { + } + + virtual int + IOHandlerComplete (IOHandler &io_handler, + const char *current_line, + const char *cursor, + const char *last_char, + int skip_first_n_matches, + int max_matches, + StringList &matches); + + //------------------------------------------------------------------ + /// Called when a line or lines have been retrieved. + /// + /// This funtion can handle the current line and possibly call + /// IOHandler::SetIsDone(true) when the IO handler is done like when + /// "quit" is entered as a command, of when an empty line is + /// received. It is up to the delegate to determine when a line + /// should cause a IOHandler to exit. + //------------------------------------------------------------------ + virtual void + IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0; + + //------------------------------------------------------------------ + /// Called when a line in \a lines has been updated when doing + /// multi-line input. + /// + /// @return + /// Return an enumeration to indicate the status of the current + /// line: + /// Success - The line is good and should be added to the + /// multiple lines + /// Error - There is an error with the current line and it + /// need to be re-edited before it is acceptable + /// Done - The lines collection is complete and ready to be + /// returned. + //------------------------------------------------------------------ + virtual LineStatus + IOHandlerLinesUpdated (IOHandler &io_handler, + StringList &lines, + uint32_t line_idx, + Error &error) + { + return LineStatus::Done; // Stop getting lines on the first line that is updated + // subclasses should do something more intelligent here. + // This function will not be called on IOHandler objects + // that are getting single lines. + } + + + virtual ConstString + GetControlSequence (char ch) + { + return ConstString(); + } + + protected: + Completion m_completion; // Support for common builtin completions + bool m_io_handler_done; + }; + + //---------------------------------------------------------------------- + // IOHandlerDelegateMultiline + // + // A IOHandlerDelegate that handles terminating multi-line input when + // the last line is equal to "end_line" which is specified in the + // constructor. + //---------------------------------------------------------------------- + class IOHandlerDelegateMultiline : + public IOHandlerDelegate + { + public: + IOHandlerDelegateMultiline (const char *end_line, + Completion completion = Completion::None) : + IOHandlerDelegate (completion), + m_end_line((end_line && end_line[0]) ? end_line : "") + { + } + + virtual + ~IOHandlerDelegateMultiline () + { + } + + virtual ConstString + GetControlSequence (char ch) + { + if (ch == 'd') + return ConstString (m_end_line + "\n"); + return ConstString(); + } + + virtual LineStatus + IOHandlerLinesUpdated (IOHandler &io_handler, + StringList &lines, + uint32_t line_idx, + Error &error) + { + if (line_idx == UINT32_MAX) + { + // Remove the last empty line from "lines" so it doesn't appear + // in our final expression and return true to indicate we are done + // getting lines + lines.PopBack(); + return LineStatus::Done; + } + else if (line_idx + 1 == lines.GetSize()) + { + // The last line was edited, if this line is empty, then we are done + // getting our multiple lines. + if (lines[line_idx] == m_end_line) + return LineStatus::Done; + } + return LineStatus::Success; + } + protected: + const std::string m_end_line; + }; + + + class IOHandlerEditline : public IOHandler + { + public: + IOHandlerEditline (Debugger &debugger, + const char *editline_name, // Used for saving history files + const char *prompt, + bool multi_line, + IOHandlerDelegate &delegate); + + IOHandlerEditline (Debugger &debugger, + const lldb::StreamFileSP &input_sp, + const lldb::StreamFileSP &output_sp, + const lldb::StreamFileSP &error_sp, + uint32_t flags, + const char *editline_name, // Used for saving history files + const char *prompt, + bool multi_line, + IOHandlerDelegate &delegate); + + virtual + ~IOHandlerEditline (); + + virtual void + Run (); + + virtual void + Hide (); + + virtual void + Refresh (); + + virtual void + Interrupt (); + + virtual void + GotEOF(); + + virtual void + Activate () + { + IOHandler::Activate(); + m_delegate.IOHandlerActivated(*this); + } + + virtual ConstString + GetControlSequence (char ch) + { + return m_delegate.GetControlSequence (ch); + } + + virtual const char * + GetPrompt (); + + virtual bool + SetPrompt (const char *prompt); + + bool + GetLine (std::string &line); + + bool + GetLines (StringList &lines); + + private: + static LineStatus + LineCompletedCallback (Editline *editline, + StringList &lines, + uint32_t line_idx, + Error &error, + void *baton); + + static int AutoCompleteCallback (const char *current_line, + const char *cursor, + const char *last_char, + int skip_first_n_matches, + int max_matches, + StringList &matches, + void *baton); + + protected: + std::unique_ptr<Editline> m_editline_ap; + IOHandlerDelegate &m_delegate; + std::string m_prompt; + bool m_multi_line; + }; + + class IOHandlerConfirm : + public IOHandlerEditline, + public IOHandlerDelegate + { + public: + IOHandlerConfirm (Debugger &debugger, + const char *prompt, + bool default_response); + + virtual + ~IOHandlerConfirm (); + + bool + GetResponse () const + { + return m_user_response; + } + + virtual int + IOHandlerComplete (IOHandler &io_handler, + const char *current_line, + const char *cursor, + const char *last_char, + int skip_first_n_matches, + int max_matches, + StringList &matches); + + virtual void + IOHandlerInputComplete (IOHandler &io_handler, std::string &data); + + protected: + const bool m_default_response; + bool m_user_response; + }; + + class IOHandlerCursesGUI : + public IOHandler + { + public: + IOHandlerCursesGUI (Debugger &debugger); + + virtual + ~IOHandlerCursesGUI (); + + virtual void + Run (); + + virtual void + Hide (); + + virtual void + Refresh (); + + virtual void + Interrupt (); + + virtual void + GotEOF(); + + virtual void + Activate (); + + virtual void + Deactivate (); + + protected: + curses::ApplicationAP m_app_ap; + }; + + class IOHandlerCursesValueObjectList : + public IOHandler + { + public: + IOHandlerCursesValueObjectList (Debugger &debugger, ValueObjectList &valobj_list); + + virtual + ~IOHandlerCursesValueObjectList (); + + virtual void + Run (); + + virtual void + Hide (); + + virtual void + Refresh (); + + virtual void + Interrupt (); + + virtual void + GotEOF(); + protected: + ValueObjectList m_valobj_list; + }; + + class IOHandlerStack + { + public: + + IOHandlerStack () : + m_stack(), + m_mutex(Mutex::eMutexTypeRecursive), + m_top (NULL) + { + } + + ~IOHandlerStack () + { + } + + size_t + GetSize () const + { + Mutex::Locker locker (m_mutex); + return m_stack.size(); + } + + void + Push (const lldb::IOHandlerSP& sp) + { + if (sp) + { + Mutex::Locker locker (m_mutex); + m_stack.push (sp); + // Set m_top the non-locking IsTop() call + m_top = sp.get(); + } + } + + bool + IsEmpty () const + { + Mutex::Locker locker (m_mutex); + return m_stack.empty(); + } + + lldb::IOHandlerSP + Top () + { + lldb::IOHandlerSP sp; + { + Mutex::Locker locker (m_mutex); + if (!m_stack.empty()) + sp = m_stack.top(); + } + return sp; + } + + void + Pop () + { + Mutex::Locker locker (m_mutex); + if (!m_stack.empty()) + m_stack.pop(); + // Set m_top the non-locking IsTop() call + if (m_stack.empty()) + m_top = NULL; + else + m_top = m_stack.top().get(); + } + + Mutex & + GetMutex() + { + return m_mutex; + } + + bool + IsTop (const lldb::IOHandlerSP &io_handler_sp) const + { + return m_top == io_handler_sp.get(); + } + + ConstString + GetTopIOHandlerControlSequence (char ch) + { + if (m_top) + return m_top->GetControlSequence(ch); + return ConstString(); + } + + protected: + + std::stack<lldb::IOHandlerSP> m_stack; + mutable Mutex m_mutex; + IOHandler *m_top; + + private: + + DISALLOW_COPY_AND_ASSIGN (IOHandlerStack); + }; + +} // namespace lldb_private + +#endif // #ifndef liblldb_IOHandler_h_ diff --git a/include/lldb/Core/InputReader.h b/include/lldb/Core/InputReader.h deleted file mode 100644 index fa86e9a39e2b..000000000000 --- a/include/lldb/Core/InputReader.h +++ /dev/null @@ -1,274 +0,0 @@ -//===-- 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 <string.h> - -#include "lldb/lldb-public.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/StringList.h" -#include "lldb/Host/Predicate.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); - - struct HandlerData - { - InputReader& reader; - const char *bytes; - size_t bytes_len; - void* baton; - - HandlerData(InputReader& r, - const char* b, - size_t l, - void* t) : - reader(r), - bytes(b), - bytes_len(l), - baton(t) - { - } - - lldb::StreamSP - GetOutStream(); - - bool - GetBatchMode(); - }; - - struct InitializationParameters - { - private: - void* m_baton; - lldb::InputReaderGranularity m_token_size; - char* m_end_token; - char* m_prompt; - bool m_echo; - bool m_save_user_input; - public: - InitializationParameters() : - m_baton(NULL), - m_token_size(lldb::eInputReaderGranularityLine), - m_echo(true), - m_save_user_input(false) - { - SetEndToken("DONE"); - SetPrompt("> "); - } - - InitializationParameters& - SetEcho(bool e) - { - m_echo = e; - return *this; - } - - InitializationParameters& - SetSaveUserInput(bool s) - { - m_save_user_input = s; - return *this; - } - - InitializationParameters& - SetBaton(void* b) - { - m_baton = b; - return *this; - } - - InitializationParameters& - SetGranularity(lldb::InputReaderGranularity g) - { - m_token_size = g; - return *this; - } - - InitializationParameters& - SetEndToken(const char* e) - { - m_end_token = new char[strlen(e)+1]; - ::strcpy(m_end_token,e); - return *this; - } - - InitializationParameters& - SetPrompt(const char* p) - { - m_prompt = new char[strlen(p)+1]; - ::strcpy(m_prompt,p); - return *this; - } - - friend class InputReaderEZ; - - }; - - InputReader (Debugger &debugger); - - virtual - ~InputReader (); - - virtual Error - Initialize (Callback callback, - void *baton, - lldb::InputReaderGranularity token_size, - const char *end_token, - const char *prompt, - bool echo); - - virtual Error Initialize(void* baton, - lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine, - const char* end_token = "DONE", - const char *prompt = "> ", - bool echo = true) - { - return Error("unimplemented"); - } - - virtual Error - Initialize(InitializationParameters& params) - { - return Error("unimplemented"); - } - - // to use these handlers instead of the Callback function, you must subclass - // InputReaderEZ, and redefine the handlers for the events you care about - virtual void - ActivateHandler(HandlerData&) {} - - virtual void - DeactivateHandler(HandlerData&) {} - - virtual void - ReactivateHandler(HandlerData&) {} - - virtual void - AsynchronousOutputWrittenHandler(HandlerData&) {} - - virtual void - GotTokenHandler(HandlerData&) {} - - virtual void - InterruptHandler(HandlerData&) {} - - virtual void - EOFHandler(HandlerData&) {} - - virtual void - DoneHandler(HandlerData&) {} - - 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; - } - - StringList& - GetUserInput() - { - return m_user_input; - } - - virtual bool - GetSaveUserInput() - { - return false; - } - - // 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); - - Debugger & - GetDebugger() - { - return m_debugger; - } - - bool - IsActive () const - { - return m_active; - } - - const char * - GetPrompt () const; - - void - RefreshPrompt(); - - // If you want to read from an input reader synchronously, then just initialize the - // reader and then call WaitOnReaderIsDone, which will return when the reader is popped. - void - WaitOnReaderIsDone (); - - static const char * - GranularityAsCString (lldb::InputReaderGranularity granularity); - -protected: - friend class Debugger; - - void - Notify (lldb::InputReaderAction notification); - - Debugger &m_debugger; - 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; - Predicate<bool> m_reader_done; - StringList m_user_input; - bool m_save_user_input; - -private: - DISALLOW_COPY_AND_ASSIGN (InputReader); - -}; - -} // namespace lldb_private - -#endif // #ifndef liblldb_InputReader_h_ diff --git a/include/lldb/Core/InputReaderEZ.h b/include/lldb/Core/InputReaderEZ.h deleted file mode 100644 index 85561b6f0a9e..000000000000 --- a/include/lldb/Core/InputReaderEZ.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- InputReaderEZ.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_InputReaderEZ_h_ -#define liblldb_InputReaderEZ_h_ - -#include "lldb/Core/InputReader.h" - -namespace lldb_private { - -class InputReaderEZ : public InputReader -{ - -private: - - static size_t Callback_Impl(void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); -public: - - InputReaderEZ (Debugger &debugger) : - InputReader(debugger) - {} - - virtual - ~InputReaderEZ (); - - using InputReader::Initialize; - virtual Error - Initialize(void* baton, - lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine, - const char* end_token = "DONE", - const char *prompt = "> ", - bool echo = true); - - virtual Error - Initialize(InitializationParameters& params); - - virtual void - ActivateHandler(HandlerData&) {} - - virtual void - DeactivateHandler(HandlerData&) {} - - virtual void - ReactivateHandler(HandlerData&) {} - - virtual void - AsynchronousOutputWrittenHandler(HandlerData&) {} - - virtual void - GotTokenHandler(HandlerData&) {} - - virtual void - InterruptHandler(HandlerData&) {} - - virtual void - EOFHandler(HandlerData&) {} - - virtual void - DoneHandler(HandlerData&) {} - - virtual bool - GetSaveUserInput() - { - return m_save_user_input; - } - -protected: - friend class Debugger; - -private: - DISALLOW_COPY_AND_ASSIGN (InputReaderEZ); - -}; - -} // namespace lldb_private - -#endif // #ifndef liblldb_InputReaderEZ_h_ diff --git a/include/lldb/Core/InputReaderStack.h b/include/lldb/Core/InputReaderStack.h deleted file mode 100644 index a73b97cad571..000000000000 --- a/include/lldb/Core/InputReaderStack.h +++ /dev/null @@ -1,58 +0,0 @@ -//===-- InputReaderStack.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_InputReaderStack_h_ -#define liblldb_InputReaderStack_h_ - -#include <stack> - -#include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" - -namespace lldb_private { - -class InputReaderStack -{ -public: - - InputReaderStack (); - - ~InputReaderStack (); - - size_t - GetSize () const; - - void - Push (const lldb::InputReaderSP& reader_sp); - - bool - IsEmpty () const; - - lldb::InputReaderSP - Top (); - - void - Pop (); - - Mutex & - GetStackMutex (); - -protected: - - std::stack<lldb::InputReaderSP> m_input_readers; - mutable Mutex m_input_readers_mutex; - -private: - - DISALLOW_COPY_AND_ASSIGN (InputReaderStack); -}; - -} // namespace lldb_private - -#endif // liblldb_InputReaderStack_h_ diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h index 80d249d4cc9e..4b77ff1ab8fc 100644 --- a/include/lldb/Core/MappedHash.h +++ b/include/lldb/Core/MappedHash.h @@ -382,9 +382,9 @@ public: lldb::offset_t offset = m_header.Read (data, 0); if (offset != LLDB_INVALID_OFFSET && IsValid ()) { - m_hash_indexes = (uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t)); - m_hash_values = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t)); - m_hash_offsets = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t)); + m_hash_indexes = (const uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t)); + m_hash_values = (const uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t)); + m_hash_offsets = (const uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t)); } } @@ -542,9 +542,9 @@ public: protected: // Implementation agnostic information HeaderType m_header; - uint32_t *m_hash_indexes; - uint32_t *m_hash_values; - uint32_t *m_hash_offsets; + const uint32_t *m_hash_indexes; + const uint32_t *m_hash_values; + const uint32_t *m_hash_offsets; }; }; diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h index cae5a30be704..56650582791b 100644 --- a/include/lldb/Core/Module.h +++ b/include/lldb/Core/Module.h @@ -113,10 +113,18 @@ public: /// @param[in] target /// The target in which to apply the section load addresses. /// - /// @param[in] offset - /// The offset to apply to all file addresses for all top - /// level sections in the object file as each section load - /// address is being set. + /// @param[in] value + /// if \a value_is_offset is true, then value is the offset to + /// apply to all file addresses for all top level sections in + /// the object file as each section load address is being set. + /// If \a value_is_offset is false, then "value" is the new + /// absolute base address for the image. + /// + /// @param[in] value_is_offset + /// If \b true, then \a value is an offset to apply to each + /// file address of each top level section. + /// If \b false, then \a value is the image base address that + /// will be used to rigidly slide all loadable sections. /// /// @param[out] changed /// If any section load addresses were changed in \a target, @@ -133,7 +141,8 @@ public: //------------------------------------------------------------------ bool SetLoadAddress (Target &target, - lldb::addr_t offset, + lldb::addr_t value, + bool value_is_offset, bool &changed); //------------------------------------------------------------------ diff --git a/include/lldb/Core/Opcode.h b/include/lldb/Core/Opcode.h index fd80231a44e7..57b8077477ce 100644 --- a/include/lldb/Core/Opcode.h +++ b/include/lldb/Core/Opcode.h @@ -15,7 +15,9 @@ // C++ Includes // Other libraries and framework includes +#include "llvm/Support/MathExtras.h" // Project includes +#include "lldb/Host/Endian.h" #include "lldb/lldb-public.h" namespace lldb @@ -39,31 +41,31 @@ namespace lldb_private { eTypeBytes }; - Opcode () : m_type (eTypeInvalid) + Opcode () : m_byte_order (lldb::eByteOrderInvalid), m_type (eTypeInvalid) { } - Opcode (uint8_t inst) : m_type (eType8) + Opcode (uint8_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType8) { m_data.inst8 = inst; } - Opcode (uint16_t inst) : m_type (eType16) + Opcode (uint16_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType16) { m_data.inst16 = inst; } - Opcode (uint32_t inst) : m_type (eType32) + Opcode (uint32_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType32) { m_data.inst32 = inst; } - Opcode (uint64_t inst) : m_type (eType64) + Opcode (uint64_t inst, lldb::ByteOrder order) : m_byte_order (order), m_type (eType64) { m_data.inst64 = inst; } - Opcode (uint8_t *bytes, size_t length) + Opcode (uint8_t *bytes, size_t length) : m_byte_order (lldb::eByteOrderInvalid) { SetOpcodeBytes (bytes, length); } @@ -71,6 +73,7 @@ namespace lldb_private { void Clear() { + m_byte_order = lldb::eByteOrderInvalid; m_type = Opcode::eTypeInvalid; } Opcode::Type @@ -102,7 +105,7 @@ namespace lldb_private { { case Opcode::eTypeInvalid: break; case Opcode::eType8: return m_data.inst8; - case Opcode::eType16: return m_data.inst16; + case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16; case Opcode::eType16_2: break; case Opcode::eType32: break; case Opcode::eType64: break; @@ -118,9 +121,9 @@ namespace lldb_private { { case Opcode::eTypeInvalid: break; case Opcode::eType8: return m_data.inst8; - case Opcode::eType16: return m_data.inst16; + case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16; case Opcode::eType16_2: // passthrough - case Opcode::eType32: return m_data.inst32; + case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32; case Opcode::eType64: break; case Opcode::eTypeBytes: break; } @@ -134,48 +137,53 @@ namespace lldb_private { { case Opcode::eTypeInvalid: break; case Opcode::eType8: return m_data.inst8; - case Opcode::eType16: return m_data.inst16; + case Opcode::eType16: return GetEndianSwap() ? llvm::ByteSwap_16(m_data.inst16) : m_data.inst16; case Opcode::eType16_2: // passthrough - case Opcode::eType32: return m_data.inst32; - case Opcode::eType64: return m_data.inst64; + case Opcode::eType32: return GetEndianSwap() ? llvm::ByteSwap_32(m_data.inst32) : m_data.inst32; + case Opcode::eType64: return GetEndianSwap() ? llvm::ByteSwap_64(m_data.inst64) : m_data.inst64; case Opcode::eTypeBytes: break; } return invalid_opcode; } void - SetOpcode8 (uint8_t inst) + SetOpcode8 (uint8_t inst, lldb::ByteOrder order) { m_type = eType8; m_data.inst8 = inst; + m_byte_order = order; } void - SetOpcode16 (uint16_t inst) + SetOpcode16 (uint16_t inst, lldb::ByteOrder order) { m_type = eType16; m_data.inst16 = inst; + m_byte_order = order; } void - SetOpcode16_2 (uint32_t inst) + SetOpcode16_2 (uint32_t inst, lldb::ByteOrder order) { m_type = eType16_2; m_data.inst32 = inst; + m_byte_order = order; } void - SetOpcode32 (uint32_t inst) + SetOpcode32 (uint32_t inst, lldb::ByteOrder order) { m_type = eType32; m_data.inst32 = inst; + m_byte_order = order; } void - SetOpcode64 (uint64_t inst) + SetOpcode64 (uint64_t inst, lldb::ByteOrder order) { m_type = eType64; m_data.inst64 = inst; + m_byte_order = order; } void @@ -187,6 +195,7 @@ namespace lldb_private { m_data.inst.length = length; assert (length < sizeof (m_data.inst.bytes)); memcpy (m_data.inst.bytes, bytes, length); + m_byte_order = lldb::eByteOrderInvalid; } else { @@ -249,6 +258,15 @@ namespace lldb_private { lldb::ByteOrder GetDataByteOrder () const; + bool + GetEndianSwap() const + { + return (m_byte_order == lldb::eByteOrderBig && lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) || + (m_byte_order == lldb::eByteOrderLittle && lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig); + } + + lldb::ByteOrder m_byte_order; + Opcode::Type m_type; union { diff --git a/include/lldb/Core/SourceManager.h b/include/lldb/Core/SourceManager.h index b850df774bac..d8c9eccd3477 100644 --- a/include/lldb/Core/SourceManager.h +++ b/include/lldb/Core/SourceManager.h @@ -70,6 +70,15 @@ public: return m_source_map_mod_id; } + const char * + PeekLineData (uint32_t line); + + uint32_t + GetLineLength (uint32_t line, bool include_newline_chars); + + uint32_t + GetNumLines (); + protected: bool @@ -167,11 +176,11 @@ public: uint32_t start_line, uint32_t end_line, std::vector<uint32_t> &match_lines); - -protected: - + FileSP GetFile (const FileSpec &file_spec); + +protected: //------------------------------------------------------------------ // Classes that inherit from SourceManager can see and modify these diff --git a/include/lldb/Core/StreamAsynchronousIO.h b/include/lldb/Core/StreamAsynchronousIO.h index 0e3e9ee9bcf1..a73a9567fe83 100644 --- a/include/lldb/Core/StreamAsynchronousIO.h +++ b/include/lldb/Core/StreamAsynchronousIO.h @@ -13,7 +13,6 @@ #include <string> #include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" namespace lldb_private { @@ -35,7 +34,7 @@ public: private: Broadcaster &m_broadcaster; uint32_t m_broadcast_event_type; - StreamString m_accumulated_data; + std::string m_accumulated_data; }; } // namespace lldb_private diff --git a/include/lldb/Core/StringList.h b/include/lldb/Core/StringList.h index 5503274173cb..b68ab4be2d6d 100644 --- a/include/lldb/Core/StringList.h +++ b/include/lldb/Core/StringList.h @@ -34,6 +34,9 @@ public: AppendString (const std::string &s); void + AppendString (std::string &&s); + + void AppendString (const char *str); void @@ -51,6 +54,34 @@ public: size_t GetSize () const; + void + SetSize (size_t n) + { + m_strings.resize(n); + } + + size_t + GetMaxStringLength () const; + + std::string & + operator [](size_t idx) + { + // No bounds checking, verify "idx" is good prior to calling this function + return m_strings[idx]; + } + + const std::string & + operator [](size_t idx) const + { + // No bounds checking, verify "idx" is good prior to calling this function + return m_strings[idx]; + } + + void + PopBack () + { + m_strings.pop_back(); + } const char * GetStringAtIndex (size_t idx) const; @@ -64,6 +95,12 @@ public: LongestCommonPrefix (std::string &common_prefix); void + InsertStringAtIndex (size_t idx, const std::string &str); + + void + InsertStringAtIndex (size_t idx, std::string &&str); + + void InsertStringAtIndex (size_t id, const char *str); void @@ -73,11 +110,14 @@ public: RemoveBlankLines (); size_t + SplitIntoLines (const std::string &lines); + + size_t SplitIntoLines (const char *lines, size_t len); std::string CopyList(const char* item_preamble = NULL, - const char* items_sep = "\n"); + const char* items_sep = "\n") const; StringList& operator << (const char* str); diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h index 1ef421676ee1..e2847c778484 100644 --- a/include/lldb/Core/ValueObject.h +++ b/include/lldb/Core/ValueObject.h @@ -499,6 +499,10 @@ public: GetValueAsCString (); virtual bool + GetValueAsCString (const lldb_private::TypeFormatImpl& format, + std::string& destination); + + bool GetValueAsCString (lldb::Format format, std::string& destination); @@ -615,7 +619,8 @@ public: DumpPrintableRepresentation (Stream& s, ValueObjectRepresentationStyle val_obj_display = eValueObjectRepresentationStyleSummary, lldb::Format custom_format = lldb::eFormatInvalid, - PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow); + PrintableRepresentationSpecialCases special = ePrintableRepresentationSpecialCasesAllow, + bool do_dump_error = true); bool GetValueIsValid () const; diff --git a/include/lldb/Core/ValueObjectList.h b/include/lldb/Core/ValueObjectList.h index 5bfe40b2e952..6565367cc61c 100644 --- a/include/lldb/Core/ValueObjectList.h +++ b/include/lldb/Core/ValueObjectList.h @@ -75,6 +75,12 @@ public: void Swap (ValueObjectList &value_object_list); + void + Clear () + { + m_value_objects.clear(); + } + protected: typedef std::vector<lldb::ValueObjectSP> collection; //------------------------------------------------------------------ diff --git a/include/lldb/DataFormatters/CXXFormatterFunctions.h b/include/lldb/DataFormatters/CXXFormatterFunctions.h index 415ef9be59ef..c53ef9589eea 100644 --- a/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -79,6 +79,9 @@ namespace lldb_private { bool LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring + + bool + LibcxxSmartPointerSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::shared_ptr<> and std::weak_ptr<> bool ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream); @@ -594,10 +597,11 @@ namespace lldb_private { virtual ~LibcxxVectorBoolSyntheticFrontEnd (); private: + ClangASTType m_bool_type; ExecutionContextRef m_exe_ctx_ref; uint64_t m_count; lldb::addr_t m_base_data_address; - EvaluateExpressionOptions m_options; + std::map<size_t,lldb::ValueObjectSP> m_children; }; SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP); diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h index 750e53008318..24ec877ee515 100644 --- a/include/lldb/DataFormatters/FormatManager.h +++ b/include/lldb/DataFormatters/FormatManager.h @@ -20,7 +20,7 @@ #include "lldb/DataFormatters/FormatCache.h" #include "lldb/DataFormatters/FormatClasses.h" -#include "lldb/DataFormatters/FormatNavigator.h" +#include "lldb/DataFormatters/FormattersContainer.h" #include "lldb/DataFormatters/TypeCategory.h" #include "lldb/DataFormatters/TypeCategoryMap.h" @@ -44,7 +44,7 @@ public: FormatManager (); NamedSummariesMap& - GetNamedSummaryNavigator () + GetNamedSummaryContainer () { return m_named_summaries_map; } diff --git a/include/lldb/DataFormatters/FormatNavigator.h b/include/lldb/DataFormatters/FormattersContainer.h index 1b82776fb28c..de838d1ab9c1 100644 --- a/include/lldb/DataFormatters/FormatNavigator.h +++ b/include/lldb/DataFormatters/FormattersContainer.h @@ -1,4 +1,4 @@ -//===-- FormatNavigator.h ----------------------------------------*- C++ -*-===// +//===-- FormattersContainer.h ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_FormatNavigator_h_ -#define lldb_FormatNavigator_h_ +#ifndef lldb_FormattersContainer_h_ +#define lldb_FormattersContainer_h_ // C Includes // C++ Includes @@ -104,7 +104,7 @@ GetValidTypeName_Impl (const ConstString& type) } template<typename KeyType, typename ValueType> -class FormatNavigator; +class FormattersContainer; template<typename KeyType, typename ValueType> class FormatMap @@ -243,13 +243,13 @@ protected: return m_map_mutex; } - friend class FormatNavigator<KeyType, ValueType>; + friend class FormattersContainer<KeyType, ValueType>; friend class FormatManager; }; template<typename KeyType, typename ValueType> -class FormatNavigator +class FormattersContainer { protected: typedef FormatMap<KeyType,ValueType> BackEndType; @@ -260,11 +260,11 @@ public: typedef typename MapType::key_type MapKeyType; typedef typename MapType::mapped_type MapValueType; typedef typename BackEndType::CallbackType CallbackType; - typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer; + typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType> > SharedPointer; friend class TypeCategoryImpl; - FormatNavigator(std::string name, + FormattersContainer(std::string name, IFormatChangeListener* lst) : m_format_map(lst), m_name(name), @@ -350,7 +350,7 @@ protected: std::string m_name; - DISALLOW_COPY_AND_ASSIGN(FormatNavigator); + DISALLOW_COPY_AND_ASSIGN(FormattersContainer); ConstString m_id_cs; @@ -470,6 +470,7 @@ protected: { for (const FormattersMatchCandidate& candidate : candidates) { + // FIXME: could we do the IsMatch() check first? if (Get(candidate.GetTypeName(),entry)) { if (candidate.IsMatch(entry) == false) @@ -491,4 +492,4 @@ protected: } // namespace lldb_private -#endif // lldb_FormatNavigator_h_ +#endif // lldb_FormattersContainer_h_ diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h index 082395a04616..491fef29b5c5 100644 --- a/include/lldb/DataFormatters/TypeCategory.h +++ b/include/lldb/DataFormatters/TypeCategory.h @@ -19,108 +19,131 @@ #include "lldb/lldb-enumerations.h" #include "lldb/DataFormatters/FormatClasses.h" -#include "lldb/DataFormatters/FormatNavigator.h" +#include "lldb/DataFormatters/FormattersContainer.h" -namespace lldb_private { - class TypeCategoryImpl +namespace lldb_private { + + template <typename FormatterImpl> + class FormatterContainerPair { - private: - typedef FormatNavigator<ConstString, TypeFormatImpl> ValueNavigator; - typedef FormatNavigator<lldb::RegularExpressionSP, TypeFormatImpl> RegexValueNavigator; + public: + typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer; + typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl> RegexMatchContainer; - typedef FormatNavigator<ConstString, TypeSummaryImpl> SummaryNavigator; - typedef FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl> RegexSummaryNavigator; + typedef typename ExactMatchContainer::MapType ExactMatchMap; + typedef typename RegexMatchContainer::MapType RegexMatchMap; + + typedef typename ExactMatchContainer::MapValueType MapValueType; - typedef FormatNavigator<ConstString, TypeFilterImpl> FilterNavigator; - typedef FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl> RegexFilterNavigator; + typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP; + typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP; -#ifndef LLDB_DISABLE_PYTHON - typedef FormatNavigator<ConstString, ScriptedSyntheticChildren> SynthNavigator; - typedef FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren> RegexSynthNavigator; -#endif // #ifndef LLDB_DISABLE_PYTHON - - typedef ValueNavigator::MapType ValueMap; - typedef RegexValueNavigator::MapType RegexValueMap; - - typedef SummaryNavigator::MapType SummaryMap; - typedef RegexSummaryNavigator::MapType RegexSummaryMap; + FormatterContainerPair (const char* exact_name, + const char* regex_name, + IFormatChangeListener* clist) : + m_exact_sp(new ExactMatchContainer(std::string(exact_name),clist)), + m_regex_sp(new RegexMatchContainer(std::string(regex_name),clist)) + { + } + + ~FormatterContainerPair () = default; + + ExactMatchContainerSP + GetExactMatch () const + { + return m_exact_sp; + } - typedef FilterNavigator::MapType FilterMap; - typedef RegexFilterNavigator::MapType RegexFilterMap; + RegexMatchContainerSP + GetRegexMatch () const + { + return m_regex_sp; + } + + private: + ExactMatchContainerSP m_exact_sp; + RegexMatchContainerSP m_regex_sp; + }; + class TypeCategoryImpl + { + private: + typedef FormatterContainerPair<TypeFormatImpl> FormatContainer; + typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer; + typedef FormatterContainerPair<TypeFilterImpl> FilterContainer; + #ifndef LLDB_DISABLE_PYTHON - typedef SynthNavigator::MapType SynthMap; - typedef RegexSynthNavigator::MapType RegexSynthMap; + typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer; #endif // #ifndef LLDB_DISABLE_PYTHON - + public: typedef uint16_t FormatCategoryItems; static const uint16_t ALL_ITEM_TYPES = UINT16_MAX; - typedef ValueNavigator::SharedPointer ValueNavigatorSP; - typedef RegexValueNavigator::SharedPointer RegexValueNavigatorSP; + typedef FormatContainer::ExactMatchContainerSP FormatContainerSP; + typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP; - typedef SummaryNavigator::SharedPointer SummaryNavigatorSP; - typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP; + typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP; + typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP; - typedef FilterNavigator::SharedPointer FilterNavigatorSP; - typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP; + typedef FilterContainer::ExactMatchContainerSP FilterContainerSP; + typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP; #ifndef LLDB_DISABLE_PYTHON - typedef SynthNavigator::SharedPointer SynthNavigatorSP; - typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP; + typedef SynthContainer::ExactMatchContainerSP SynthContainerSP; + typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP; #endif // #ifndef LLDB_DISABLE_PYTHON TypeCategoryImpl (IFormatChangeListener* clist, ConstString name); - ValueNavigatorSP - GetValueNavigator () + FormatContainerSP + GetTypeFormatsContainer () { - return ValueNavigatorSP(m_value_nav); + return m_format_cont.GetExactMatch(); } - RegexValueNavigatorSP - GetRegexValueNavigator () + RegexFormatContainerSP + GetRegexTypeFormatsContainer () { - return RegexValueNavigatorSP(m_regex_value_nav); + return m_format_cont.GetRegexMatch(); } - SummaryNavigatorSP - GetSummaryNavigator () + SummaryContainerSP + GetTypeSummariesContainer () { - return SummaryNavigatorSP(m_summary_nav); + return m_summary_cont.GetExactMatch(); } - RegexSummaryNavigatorSP - GetRegexSummaryNavigator () + RegexSummaryContainerSP + GetRegexTypeSummariesContainer () { - return RegexSummaryNavigatorSP(m_regex_summary_nav); + return m_summary_cont.GetRegexMatch(); } - FilterNavigatorSP - GetFilterNavigator () + FilterContainerSP + GetTypeFiltersContainer () { - return FilterNavigatorSP(m_filter_nav); + return m_filter_cont.GetExactMatch(); } - RegexFilterNavigatorSP - GetRegexFilterNavigator () + RegexFilterContainerSP + GetRegexTypeFiltersContainer () { - return RegexFilterNavigatorSP(m_regex_filter_nav); + return m_filter_cont.GetRegexMatch(); } - ValueNavigator::MapValueType + FormatContainer::MapValueType GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp); - SummaryNavigator::MapValueType + SummaryContainer::MapValueType GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp); - FilterNavigator::MapValueType + FilterContainer::MapValueType GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp); #ifndef LLDB_DISABLE_PYTHON - SynthNavigator::MapValueType + SynthContainer::MapValueType GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp); #endif @@ -130,32 +153,32 @@ namespace lldb_private { lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForSummaryAtIndex (size_t index); - ValueNavigator::MapValueType + FormatContainer::MapValueType GetFormatAtIndex (size_t index); - SummaryNavigator::MapValueType + SummaryContainer::MapValueType GetSummaryAtIndex (size_t index); - FilterNavigator::MapValueType + FilterContainer::MapValueType GetFilterAtIndex (size_t index); lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierForFilterAtIndex (size_t index); #ifndef LLDB_DISABLE_PYTHON - SynthNavigatorSP - GetSyntheticNavigator () + SynthContainerSP + GetTypeSyntheticsContainer () { - return SynthNavigatorSP(m_synth_nav); + return m_synth_cont.GetExactMatch(); } - RegexSynthNavigatorSP - GetRegexSyntheticNavigator () + RegexSynthContainerSP + GetRegexTypeSyntheticsContainer () { - return RegexSynthNavigatorSP(m_regex_synth_nav); + return m_synth_cont.GetRegexMatch(); } - SynthNavigator::MapValueType + SynthContainer::MapValueType GetSyntheticAtIndex (size_t index); lldb::TypeNameSpecifierImplSP @@ -222,18 +245,14 @@ namespace lldb_private { typedef std::shared_ptr<TypeCategoryImpl> SharedPointer; private: - ValueNavigator::SharedPointer m_value_nav; - RegexValueNavigator::SharedPointer m_regex_value_nav; + FormatContainer m_format_cont; - SummaryNavigator::SharedPointer m_summary_nav; - RegexSummaryNavigator::SharedPointer m_regex_summary_nav; + SummaryContainer m_summary_cont; - FilterNavigator::SharedPointer m_filter_nav; - RegexFilterNavigator::SharedPointer m_regex_filter_nav; + FilterContainer m_filter_cont; #ifndef LLDB_DISABLE_PYTHON - SynthNavigator::SharedPointer m_synth_nav; - RegexSynthNavigator::SharedPointer m_regex_synth_nav; + SynthContainer m_synth_cont; #endif // #ifndef LLDB_DISABLE_PYTHON bool m_enabled; @@ -257,18 +276,18 @@ namespace lldb_private { friend class TypeCategoryMap; - friend class FormatNavigator<ConstString, TypeFormatImpl>; - friend class FormatNavigator<lldb::RegularExpressionSP, TypeFormatImpl>; + friend class FormattersContainer<ConstString, TypeFormatImpl>; + friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>; - friend class FormatNavigator<ConstString, TypeSummaryImpl>; - friend class FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl>; + friend class FormattersContainer<ConstString, TypeSummaryImpl>; + friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>; - friend class FormatNavigator<ConstString, TypeFilterImpl>; - friend class FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl>; + friend class FormattersContainer<ConstString, TypeFilterImpl>; + friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>; #ifndef LLDB_DISABLE_PYTHON - friend class FormatNavigator<ConstString, ScriptedSyntheticChildren>; - friend class FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren>; + friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>; + friend class FormattersContainer<lldb::RegularExpressionSP, ScriptedSyntheticChildren>; #endif // #ifndef LLDB_DISABLE_PYTHON }; diff --git a/include/lldb/DataFormatters/TypeCategoryMap.h b/include/lldb/DataFormatters/TypeCategoryMap.h index 6bed18719893..88aaeb23bfd8 100644 --- a/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/include/lldb/DataFormatters/TypeCategoryMap.h @@ -18,7 +18,7 @@ #include "lldb/lldb-public.h" #include "lldb/lldb-enumerations.h" -#include "lldb/DataFormatters/FormatNavigator.h" +#include "lldb/DataFormatters/FormattersContainer.h" #include "lldb/DataFormatters/TypeCategory.h" namespace lldb_private { @@ -144,7 +144,7 @@ namespace lldb_private { return m_map_mutex; } - friend class FormatNavigator<KeyType, ValueType>; + friend class FormattersContainer<KeyType, ValueType>; friend class FormatManager; }; } // namespace lldb_private diff --git a/include/lldb/DataFormatters/TypeFormat.h b/include/lldb/DataFormatters/TypeFormat.h index 77135c448ed1..20fa8f2d4e7f 100644 --- a/include/lldb/DataFormatters/TypeFormat.h +++ b/include/lldb/DataFormatters/TypeFormat.h @@ -130,15 +130,12 @@ namespace lldb_private { uint32_t m_flags; }; - TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid, - const Flags& flags = Flags()); + TypeFormatImpl (const Flags& flags = Flags()); typedef std::shared_ptr<TypeFormatImpl> SharedPointer; typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&); - ~TypeFormatImpl () - { - } + virtual ~TypeFormatImpl () = default; bool Cascades () const @@ -173,6 +170,66 @@ namespace lldb_private { { m_flags.SetSkipReferences(value); } + + uint32_t + GetOptions () + { + return m_flags.GetValue(); + } + + void + SetOptions (uint32_t value) + { + m_flags.SetValue(value); + } + + uint32_t& + GetRevision () + { + return m_my_revision; + } + + enum class Type + { + eTypeUnknown, + eTypeFormat, + eTypeEnum + }; + + virtual Type + GetType () + { + return Type::eTypeUnknown; + } + + // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for + // extended periods of time and we trust the ValueObject to stay around for as long as it is required + // for us to generate its value + virtual bool + FormatObject (ValueObject *valobj, + std::string& dest) const = 0; + + virtual std::string + GetDescription() = 0; + + protected: + Flags m_flags; + uint32_t m_my_revision; + + private: + DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl); + }; + + class TypeFormatImpl_Format : public TypeFormatImpl + { + public: + TypeFormatImpl_Format (lldb::Format f = lldb::eFormatInvalid, + const TypeFormatImpl::Flags& flags = Flags()); + + typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer; + typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_Format::SharedPointer&); + + virtual ~TypeFormatImpl_Format () = default; lldb::Format GetFormat () const @@ -186,35 +243,69 @@ namespace lldb_private { m_format = fmt; } - uint32_t - GetOptions () + virtual TypeFormatImpl::Type + GetType () { - return m_flags.GetValue(); + return TypeFormatImpl::Type::eTypeFormat; + } + + virtual bool + FormatObject (ValueObject *valobj, + std::string& dest) const; + + virtual std::string + GetDescription(); + + protected: + lldb::Format m_format; + + private: + DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_Format); + }; + + class TypeFormatImpl_EnumType : public TypeFormatImpl + { + public: + TypeFormatImpl_EnumType (ConstString type_name = ConstString(""), + const TypeFormatImpl::Flags& flags = Flags()); + + typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer; + typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_EnumType::SharedPointer&); + + ~TypeFormatImpl_EnumType () = default; + + ConstString + GetTypeName () + { + return m_enum_type; } void - SetOptions (uint32_t value) + SetTypeName (ConstString enum_type) { - m_flags.SetValue(value); + m_enum_type = enum_type; } - uint32_t& - GetRevision () + virtual TypeFormatImpl::Type + GetType () { - return m_my_revision; + return TypeFormatImpl::Type::eTypeEnum; } - std::string + virtual bool + FormatObject (ValueObject *valobj, + std::string& dest) const; + + virtual std::string GetDescription(); protected: - Flags m_flags; - lldb::Format m_format; - uint32_t m_my_revision; + ConstString m_enum_type; + mutable std::map<void*,ClangASTType> m_types; private: - DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl); - }; + DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType); + }; } // namespace lldb_private #endif // lldb_TypeFormat_h_ diff --git a/include/lldb/DataFormatters/TypeSynthetic.h b/include/lldb/DataFormatters/TypeSynthetic.h index 18b9d011e96a..a25f11d64392 100644 --- a/include/lldb/DataFormatters/TypeSynthetic.h +++ b/include/lldb/DataFormatters/TypeSynthetic.h @@ -32,10 +32,24 @@ namespace lldb_private { { protected: ValueObject &m_backend; + + void + SetValid (bool valid) + { + m_valid = valid; + } + + bool + IsValid () + { + return m_valid; + } + public: SyntheticChildrenFrontEnd (ValueObject &backend) : - m_backend(backend) + m_backend(backend), + m_valid(true) {} virtual @@ -71,6 +85,7 @@ namespace lldb_private { typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer; private: + bool m_valid; DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd); }; diff --git a/include/lldb/DataFormatters/ValueObjectPrinter.h b/include/lldb/DataFormatters/ValueObjectPrinter.h index 4e23ceedcc16..375bb50c876d 100644 --- a/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -265,9 +265,6 @@ public: bool PrintValueObject (); - bool - PrintChildrenOneLiner (bool hide_names); - protected: // only this class (and subclasses, if any) should ever be concerned with @@ -366,6 +363,9 @@ protected: PrintChildrenIfNeeded (bool value_printed, bool summary_printed); + bool + PrintChildrenOneLiner (bool hide_names); + private: ValueObject *m_orig_valobj; @@ -386,6 +386,8 @@ private: std::string m_summary; std::string m_error; + friend class StringSummaryFormat; + DISALLOW_COPY_AND_ASSIGN(ValueObjectPrinter); }; diff --git a/include/lldb/Expression/ClangFunction.h b/include/lldb/Expression/ClangFunction.h index 9c14ddb53230..e150d389b416 100644 --- a/include/lldb/Expression/ClangFunction.h +++ b/include/lldb/Expression/ClangFunction.h @@ -300,7 +300,7 @@ public: /// @param[in] args_addr /// The address of the argument struct. /// - /// @param[in] ret_value + /// @param[out] ret_value /// The value returned by the function. /// /// @return diff --git a/include/lldb/Expression/IRForTarget.h b/include/lldb/Expression/IRForTarget.h index 566328772502..502f796d15a1 100644 --- a/include/lldb/Expression/IRForTarget.h +++ b/include/lldb/Expression/IRForTarget.h @@ -30,6 +30,7 @@ namespace llvm { class GlobalValue; class GlobalVariable; class Instruction; + class IntegerType; class Module; class StoreInst; class DataLayout; @@ -650,6 +651,7 @@ private: StaticDataAllocator m_data_allocator; ///< The allocator to use for constant strings llvm::Constant *m_CFStringCreateWithBytes; ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type + llvm::IntegerType *m_intptr_ty; ///< The type of an integer large enough to hold a pointer. lldb_private::Stream *m_error_stream; ///< If non-NULL, the stream on which errors should be printed llvm::StoreInst *m_result_store; ///< If non-NULL, the store instruction that writes to the result variable. If m_has_side_effects is true, this is NULL. diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h new file mode 100644 index 000000000000..b92de1052f29 --- /dev/null +++ b/include/lldb/Host/Editline.h @@ -0,0 +1,209 @@ +//===-- Editline.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_Editline_h_ +#define liblldb_Editline_h_ +#if defined(__cplusplus) + +#include "lldb/lldb-private.h" + +#include <stdio.h> +#ifdef _WIN32 +#include "lldb/Host/windows/editlinewin.h" +#else +#include <histedit.h> +#endif + +#include <string> +#include <vector> + +#include "lldb/Host/Condition.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Editline Editline.h "lldb/Host/Editline.h" +/// @brief A class that encapsulates editline functionality. +//---------------------------------------------------------------------- +class Editline +{ +public: + typedef LineStatus (*LineCompletedCallbackType) ( + Editline *editline, + StringList &lines, + uint32_t line_idx, + Error &error, + void *baton); + + typedef int (*CompleteCallbackType) ( + const char *current_line, + const char *cursor, + const char *last_char, + int skip_first_n_matches, + int max_matches, + StringList &matches, + void *baton); + + typedef int (*GetCharCallbackType) ( + ::EditLine *, + char *c); + + Editline(const char *prog, // Used for the history file and for editrc program name + const char *prompt, + FILE *fin, + FILE *fout, + FILE *ferr); + + ~Editline(); + + Error + GetLine (std::string &line); + + Error + GetLines (const std::string &end_line, StringList &lines); + + bool + LoadHistory (); + + bool + SaveHistory (); + + FILE * + GetInputFile (); + + FILE * + GetOutputFile (); + + FILE * + GetErrorFile (); + + bool + GettingLine () const + { + return m_getting_line; + } + + void + Hide (); + + void + Refresh(); + + void + Interrupt (); + + void + SetAutoCompleteCallback (CompleteCallbackType callback, + void *baton) + { + m_completion_callback = callback; + m_completion_callback_baton = baton; + } + + void + SetLineCompleteCallback (LineCompletedCallbackType callback, + void *baton) + { + m_line_complete_callback = callback; + m_line_complete_callback_baton = baton; + } + + size_t + Push (const char *bytes, size_t len); + + // Cache bytes and use them for input without using a FILE. Calling this function + // will set the getc callback in the editline + size_t + SetInputBuffer (const char *c, size_t len); + + static int + GetCharFromInputFileCallback (::EditLine *e, char *c); + + void + SetGetCharCallback (GetCharCallbackType callback); + + const char * + GetPrompt(); + + void + SetPrompt (const char *p); + +private: + + Error + PrivateGetLine(std::string &line); + + FileSpec + GetHistoryFile(); + + unsigned char + HandleCompletion (int ch); + + int + GetChar (char *c); + + + static unsigned char + CallbackEditPrevLine (::EditLine *e, int ch); + + static unsigned char + CallbackEditNextLine (::EditLine *e, int ch); + + static unsigned char + CallbackComplete (::EditLine *e, int ch); + + static const char * + GetPromptCallback (::EditLine *e); + + static Editline * + GetClientData (::EditLine *e); + + static FILE * + GetFilePointer (::EditLine *e, int fd); + + static int + GetCharInputBufferCallback (::EditLine *e, char *c); + + enum class Command + { + None = 0, + EditPrevLine, + EditNextLine, + }; + ::EditLine *m_editline; + ::History *m_history; + ::HistEvent m_history_event; + std::string m_program; + std::string m_prompt; + std::string m_lines_prompt; + std::string m_getc_buffer; + Mutex m_getc_mutex; + Condition m_getc_cond; + CompleteCallbackType m_completion_callback; + void *m_completion_callback_baton; +// Mutex m_gets_mutex; // Make sure only one thread + LineCompletedCallbackType m_line_complete_callback; + void *m_line_complete_callback_baton; + Command m_lines_command; + uint32_t m_lines_curr_line; + uint32_t m_lines_max_line; + bool m_prompt_with_line_numbers; + bool m_getting_line; + bool m_got_eof; // Set to true when we detect EOF + bool m_interrupted; + + DISALLOW_COPY_AND_ASSIGN(Editline); +}; + +} // namespace lldb_private + +#endif // #if defined(__cplusplus) +#endif // liblldb_Host_h_ diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h index 607efa029c09..814d96059f37 100644 --- a/include/lldb/Host/File.h +++ b/include/lldb/Host/File.h @@ -51,7 +51,10 @@ public: m_descriptor (kInvalidDescriptor), m_stream (kInvalidStream), m_options (0), - m_owned (false) + m_own_stream (false), + m_own_descriptor (false), + m_is_interactive (eLazyBoolCalculate), + m_is_real_terminal (eLazyBoolCalculate) { } @@ -59,7 +62,10 @@ public: m_descriptor (kInvalidDescriptor), m_stream (fh), m_options (0), - m_owned (transfer_ownership) + m_own_stream (transfer_ownership), + m_own_descriptor (false), + m_is_interactive (eLazyBoolCalculate), + m_is_real_terminal (eLazyBoolCalculate) { } @@ -111,13 +117,15 @@ public: uint32_t options, uint32_t permissions = lldb::eFilePermissionsFileDefault); - File (int fd, bool tranfer_ownership) : + File (int fd, bool transfer_ownership) : m_descriptor (fd), m_stream (kInvalidStream), m_options (0), - m_owned (tranfer_ownership) + m_own_stream (false), + m_own_descriptor (transfer_ownership) { } + //------------------------------------------------------------------ /// Destructor. /// @@ -458,6 +466,32 @@ public: static uint32_t GetPermissions (const char *path, Error &error); + + //------------------------------------------------------------------ + /// Return true if this file is interactive. + /// + /// @return + /// True if this file is a terminal (tty or pty), false + /// otherwise. + //------------------------------------------------------------------ + bool + GetIsInteractive (); + + //------------------------------------------------------------------ + /// Return true if this file from a real terminal. + /// + /// Just knowing a file is a interactive isn't enough, we also need + /// to know if the terminal has a width and height so we can do + /// cursor movement and other terminal maninpulations by sending + /// escape sequences. + /// + /// @return + /// True if this file is a terminal (tty, not a pty) that has + /// a non-zero width and height, false otherwise. + //------------------------------------------------------------------ + bool + GetIsRealTerminal (); + //------------------------------------------------------------------ /// Output printf formatted output to the stream. /// @@ -476,6 +510,12 @@ public: size_t PrintfVarArg(const char *format, va_list args); + + void + SetOptions (uint32_t options) + { + m_options = options; + } protected: @@ -491,13 +531,19 @@ protected: return m_stream != kInvalidStream; } + void + CalculateInteractiveAndTerminal (); + //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ int m_descriptor; FILE *m_stream; uint32_t m_options; - bool m_owned; + bool m_own_stream; + bool m_own_descriptor; + LazyBool m_is_interactive; + LazyBool m_is_real_terminal; }; } // namespace lldb_private diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h index 086c8f200567..dfc4e4ae0fe3 100644 --- a/include/lldb/Host/FileSpec.h +++ b/include/lldb/Host/FileSpec.h @@ -534,7 +534,7 @@ public: /// as many bytes as possible. /// /// @return - /// A shared pointer to the memeory mapped data. This shared + /// A shared pointer to the memory mapped data. This shared /// pointer can contain a NULL DataBuffer pointer, so the contained /// pointer must be checked prior to using it. //------------------------------------------------------------------ diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index fe0f6f62b3bc..862b1ed79432 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -202,6 +202,23 @@ public: GetTargetTriple (); //------------------------------------------------------------------ + /// Gets the name of the distribution (i.e. distributor id). + /// + /// On Linux, this will return the equivalent of lsb_release -i. + /// Android will return 'android'. Other systems may return + /// nothing. + /// + /// @return + /// A ConstString reference containing the OS distribution id. + /// The return string will be all lower case, with whitespace + /// replaced with underscores. The return string will be + /// empty (result.AsCString() will return NULL) if the distribution + /// cannot be obtained. + //------------------------------------------------------------------ + static const ConstString & + GetDistributionId (); + + //------------------------------------------------------------------ /// Get the process ID for the calling process. /// /// @return @@ -459,7 +476,15 @@ public: static bool GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); - + +#if defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) + static short + GetPosixspawnFlags (ProcessLaunchInfo &launch_info); + + static Error + LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid); +#endif + static lldb::pid_t LaunchApplication (const FileSpec &app_file_spec); diff --git a/include/lldb/Host/HostGetOpt.h b/include/lldb/Host/HostGetOpt.h new file mode 100644 index 000000000000..6fb7b51dddba --- /dev/null +++ b/include/lldb/Host/HostGetOpt.h @@ -0,0 +1,20 @@ +//===-- GetOpt.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#pragma once + +#ifndef _MSC_VER + +#include <unistd.h> +#include <getopt.h> + +#else + +#include <lldb/Host/windows/GetOptInc.h> + +#endif
\ No newline at end of file diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h index 5e79e94fa9ec..4dc62102103a 100644 --- a/include/lldb/Host/SocketAddress.h +++ b/include/lldb/Host/SocketAddress.h @@ -18,7 +18,6 @@ #include <winsock2.h> #include <WS2tcpip.h> typedef ADDRESS_FAMILY sa_family_t; -typedef USHORT in_port_t; #else #include <sys/socket.h> #include <netdb.h> @@ -103,7 +102,7 @@ public: //------------------------------------------------------------------ // Get the port if the socket address for the family has a port //------------------------------------------------------------------ - in_port_t + uint16_t GetPort () const; //------------------------------------------------------------------ @@ -111,7 +110,7 @@ public: // The family must be set correctly prior to calling this function. //------------------------------------------------------------------ bool - SetPort (in_port_t port); + SetPort (uint16_t port); //------------------------------------------------------------------ // Set the socket address according to the first match from a call @@ -121,10 +120,12 @@ public: // address. //------------------------------------------------------------------ bool - SetAddress (const struct addrinfo *hints_ptr, // Optional hints where the family, protocol and other things can be specified. - const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334") - const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81") - struct addrinfo *addr_info_ptr); // If non-NULL, this will get filled in with the match + getaddrinfo (const char *host, // Hostname ("foo.bar.com" or "foo" or IP address string ("123.234.12.1" or "2001:0db8:85a3:0000:0000:8a2e:0370:7334") + const char *service, // Protocol name ("tcp", "http", etc) or a raw port number string ("81") + int ai_family = PF_UNSPEC, + int ai_socktype = 0, + int ai_protocol = 0, + int ai_flags = 0); //------------------------------------------------------------------ // Quick way to set the SocketAddress to localhost given the family. @@ -133,7 +134,11 @@ public: //------------------------------------------------------------------ bool SetToLocalhost (sa_family_t family, - in_port_t port); + uint16_t port); + + bool + SetToAnyAddress (sa_family_t family, + uint16_t port); //------------------------------------------------------------------ // Returns true if there is a valid socket address in this object. diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h index 31fcc38eed9a..bcb9b5538c84 100644 --- a/include/lldb/Interpreter/CommandInterpreter.h +++ b/include/lldb/Interpreter/CommandInterpreter.h @@ -17,6 +17,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/IOHandler.h" #include "lldb/Core/Log.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandObject.h" @@ -29,7 +30,8 @@ namespace lldb_private { class CommandInterpreter : public Broadcaster, - public Properties + public Properties, + public IOHandlerDelegate { public: typedef std::map<std::string, OptionArgVectorSP> OptionArgMap; @@ -213,10 +215,10 @@ public: void HandleCommandsFromFile (FileSpec &file, ExecutionContext *context, - bool stop_on_continue, - bool stop_on_error, - bool echo_commands, - bool print_results, + LazyBool stop_on_continue, + LazyBool stop_on_error, + LazyBool echo_commands, + LazyBool print_results, LazyBool add_to_history, CommandReturnObject &result); @@ -305,7 +307,8 @@ public: ExecutionContext GetExecutionContext() { - return m_exe_ctx_ref.Lock(); + const bool thread_and_frame_only_if_stopped = true; + return m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped); } void @@ -317,20 +320,12 @@ public: const char * ProcessEmbeddedScriptCommands (const char *arg); - const char * - GetPrompt (); - void - SetPrompt (const char *); - - bool Confirm (const char *message, bool default_answer); + UpdatePrompt (const char *); - static size_t - GetConfirmationInputReaderCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction action, - const char *bytes, - size_t bytes_len); + bool + Confirm (const char *message, + bool default_answer); void LoadCommandDictionary (); @@ -395,8 +390,12 @@ public: bool GetBatchCommandMode () { return m_batch_command_mode; } - void - SetBatchCommandMode (bool value) { m_batch_command_mode = value; } + bool + SetBatchCommandMode (bool value) { + const bool old_value = m_batch_command_mode; + m_batch_command_mode = value; + return old_value; + } void ChildrenTruncated () @@ -435,6 +434,25 @@ public: return m_command_history; } + bool + IsActive (); + + void + RunCommandInterpreter (bool auto_handle_events, + bool spawn_thread); + + void + GetLLDBCommandsFromIOHandler (const char *prompt, + IOHandlerDelegate &delegate, + bool asynchronously, + void *baton); + + void + GetPythonCommandsFromIOHandler (const char *prompt, + IOHandlerDelegate &delegate, + bool asynchronously, + void *baton); + //------------------------------------------------------------------ // Properties //------------------------------------------------------------------ @@ -450,12 +468,31 @@ public: protected: friend class Debugger; + //------------------------------------------------------------------ + // IOHandlerDelegate functions + //------------------------------------------------------------------ + virtual void + IOHandlerInputComplete (IOHandler &io_handler, + std::string &line); + + virtual ConstString + GetControlSequence (char ch) + { + if (ch == 'd') + return ConstString("quit\n"); + return ConstString(); + } + + size_t + GetProcessOutput (); + void SetSynchronous (bool value); lldb::CommandObjectSP GetCommandSP (const char *cmd, bool include_aliases = true, bool exact = true, StringList *matches = NULL); + private: Error @@ -473,10 +510,12 @@ private: CommandHistory m_command_history; std::string m_repeat_command; // Stores the command that will be executed for an empty command string. std::unique_ptr<ScriptInterpreter> m_script_interpreter_ap; + lldb::IOHandlerSP m_command_io_handler_sp; char m_comment_char; bool m_batch_command_mode; ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated children and whether the user has been told uint32_t m_command_source_depth; + std::vector<uint32_t> m_command_source_flags; }; diff --git a/include/lldb/Interpreter/PythonDataObjects.h b/include/lldb/Interpreter/PythonDataObjects.h index 2762d452c0c8..55df4fd1b0a1 100644 --- a/include/lldb/Interpreter/PythonDataObjects.h +++ b/include/lldb/Interpreter/PythonDataObjects.h @@ -31,7 +31,7 @@ namespace lldb_private { { } - PythonObject (PyObject* py_obj) : + explicit PythonObject (PyObject* py_obj) : m_py_obj(NULL) { Reset (py_obj); @@ -43,7 +43,7 @@ namespace lldb_private { Reset (rhs.m_py_obj); } - PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp); + explicit PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp); virtual ~PythonObject () @@ -51,18 +51,10 @@ namespace lldb_private { Reset (NULL); } - const PythonObject & - operator = (const PythonObject &rhs) - { - if (this != &rhs) - Reset (rhs.m_py_obj); - return *this; - } - bool Reset (const PythonObject &object) { - return Reset(object.GetPythonObject()); + return Reset(object.get()); } virtual bool @@ -90,11 +82,11 @@ namespace lldb_private { Dump (Stream &strm) const; PyObject* - GetPythonObject () const + get () const { return m_py_obj; } - + PythonString Repr (); @@ -159,7 +151,7 @@ namespace lldb_private { { public: - PythonList (); + PythonList (bool create_empty); PythonList (PyObject* py_obj); PythonList (const PythonObject &object); PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp); @@ -186,7 +178,7 @@ namespace lldb_private { { public: - PythonDictionary (); + explicit PythonDictionary (bool create_empty); PythonDictionary (PyObject* object); PythonDictionary (const PythonObject &object); PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp); @@ -221,6 +213,9 @@ namespace lldb_private { GetValueAtPosition (uint32_t pos) const; void + SetItemForKey (const PythonString &key, PyObject *value); + + void SetItemForKey (const PythonString &key, const PythonObject& value); }; diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h index 9f529b822910..1d62c9b0fb52 100644 --- a/include/lldb/Interpreter/ScriptInterpreter.h +++ b/include/lldb/Interpreter/ScriptInterpreter.h @@ -245,11 +245,13 @@ public: return true; } - virtual bool + virtual Error ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options = ExecuteScriptOptions()) { - return true; + Error error; + error.SetErrorString("not implemented"); + return error; } virtual bool diff --git a/include/lldb/Interpreter/ScriptInterpreterPython.h b/include/lldb/Interpreter/ScriptInterpreterPython.h index b729cb628007..ba532808673f 100644 --- a/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -19,16 +19,21 @@ #include "lldb/lldb-python.h" #include "lldb/lldb-private.h" +#include "lldb/Core/IOHandler.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Core/InputReader.h" +#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Host/Terminal.h" namespace lldb_private { -class ScriptInterpreterPython : public ScriptInterpreter +class ScriptInterpreterPython : + public ScriptInterpreter, + public IOHandlerDelegateMultiline { public: + friend class IOHandlerPythonInterpreter; + ScriptInterpreterPython (CommandInterpreter &interpreter); ~ScriptInterpreterPython (); @@ -47,7 +52,7 @@ public: void *ret_value, const ExecuteScriptOptions &options = ExecuteScriptOptions()); - bool + lldb_private::Error ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options = ExecuteScriptOptions()); @@ -134,20 +139,20 @@ public: bool GenerateWatchpointCommandCallbackData (StringList &input, std::string& output); - static size_t - GenerateBreakpointOptionsCommandCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - - static size_t - GenerateWatchpointOptionsCommandCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - +// static size_t +// GenerateBreakpointOptionsCommandCallback (void *baton, +// InputReader &reader, +// lldb::InputReaderAction notification, +// const char *bytes, +// size_t bytes_len); +// +// static size_t +// GenerateWatchpointOptionsCommandCallback (void *baton, +// InputReader &reader, +// lldb::InputReaderAction notification, +// const char *bytes, +// size_t bytes_len); + static bool BreakpointCallbackFunction (void *baton, StoppointCallbackContext *context, @@ -238,9 +243,6 @@ public: virtual void ResetOutputFileHandle (FILE *new_fh); - static lldb::thread_result_t - RunEmbeddedPythonInterpreter (lldb::thread_arg_t baton); - static void InitializePrivate (); @@ -266,10 +268,29 @@ public: SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame, SWIGPython_GetDynamicSetting swig_plugin_get); + const char * + GetDictionaryName () + { + return m_dictionary_name.c_str(); + } + + + //---------------------------------------------------------------------- + // IOHandlerDelegate + //---------------------------------------------------------------------- + virtual void + IOHandlerActivated (IOHandler &io_handler); + + virtual void + IOHandlerInputComplete (IOHandler &io_handler, std::string &data); + protected: bool - EnterSession (bool init_lldb_globals); + EnterSession (uint16_t on_entry_flags, + FILE *in, + FILE *out, + FILE *err); void LeaveSession (); @@ -279,8 +300,6 @@ protected: void RestoreTerminalState (); - -private: class SynchronicityHandler { @@ -322,7 +341,7 @@ private: private: DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject); }; - +public: class Locker : public ScriptInterpreterLocker { public: @@ -331,7 +350,8 @@ private: { AcquireLock = 0x0001, InitSession = 0x0002, - InitGlobals = 0x0004 + InitGlobals = 0x0004, + NoSTDIN = 0x0008 }; enum OnLeave @@ -344,7 +364,9 @@ private: Locker (ScriptInterpreterPython *py_interpreter = NULL, uint16_t on_entry = AcquireLock | InitSession, uint16_t on_leave = FreeLock | TearDownSession, - FILE* wait_msg_handle = NULL); + FILE *in = NULL, + FILE *out = NULL, + FILE *err = NULL); ~Locker (); @@ -354,7 +376,7 @@ private: DoAcquireLock (); bool - DoInitSession (bool init_lldb_globals); + DoInitSession (uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); bool DoFreeLock (); @@ -367,59 +389,40 @@ private: bool m_teardown_session; ScriptInterpreterPython *m_python_interpreter; - FILE* m_tmp_fh; +// FILE* m_tmp_fh; PyGILState_STATE m_GILState; }; - - class PythonInputReaderManager - { - public: - PythonInputReaderManager (ScriptInterpreterPython *interpreter); - - explicit operator bool() - { - return m_error; - } - - ~PythonInputReaderManager(); - - private: - - static size_t - InputReaderCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - - static lldb::thread_result_t - RunPythonInputReader (lldb::thread_arg_t baton); - - ScriptInterpreterPython *m_interpreter; - lldb::DebuggerSP m_debugger_sp; - lldb::InputReaderSP m_reader_sp; - bool m_error; +private: + + enum ActiveIOHandler { + eIOHandlerNone, + eIOHandlerBreakpoint, + eIOHandlerWatchpoint }; + PythonObject & + GetMainModule (); + + PythonDictionary & + GetSessionDictionary (); + + PythonDictionary & + GetSysModuleDictionary (); - static size_t - InputReaderCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - - - lldb_utility::PseudoTerminal m_embedded_thread_pty; - lldb_utility::PseudoTerminal m_embedded_python_pty; - lldb::InputReaderSP m_embedded_thread_input_reader_sp; - lldb::InputReaderSP m_embedded_python_input_reader_sp; - FILE *m_dbg_stdout; - PyObject *m_new_sysout; - PyObject *m_old_sysout; - PyObject *m_old_syserr; - PyObject *m_run_one_line; + bool + GetEmbeddedInterpreterModuleObjects (); + + PythonObject m_saved_stdin; + PythonObject m_saved_stdout; + PythonObject m_saved_stderr; + PythonObject m_main_module; + PythonObject m_lldb_module; + PythonDictionary m_session_dict; + PythonDictionary m_sys_module_dict; + PythonObject m_run_one_line_function; + PythonObject m_run_one_line_str_global; std::string m_dictionary_name; TerminalState m_terminal_state; + ActiveIOHandler m_active_io_handler; bool m_session_is_active; bool m_pty_slave_is_open; bool m_valid_session; diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index fa48dc27e123..7af063402289 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -31,7 +31,7 @@ public: // instructions are finished for migrating breakpoints past the // stack frame setup instructions when we don't have line table information. - FuncUnwinders (lldb_private::UnwindTable& unwind_table, lldb_private::UnwindAssembly *assembly_profiler, AddressRange range); + FuncUnwinders (lldb_private::UnwindTable& unwind_table, const lldb::UnwindAssemblySP& assembly_profiler, AddressRange range); ~FuncUnwinders (); @@ -77,7 +77,7 @@ public: private: UnwindTable& m_unwind_table; - UnwindAssembly *m_assembly_profiler; + lldb::UnwindAssemblySP m_assembly_profiler; AddressRange m_range; Mutex m_mutex; diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index 787f81c5ad27..dcea24c0b632 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -608,6 +608,17 @@ public: size_t MemorySize () const; + lldb::DisassemblerSP + GetInstructions (const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache); + + bool + GetDisassembly (const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache, + Stream &strm); + protected: enum diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index ad500f5413b8..afa1f9b40902 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -451,6 +451,21 @@ public: } //------------------------------------------------------------------ + /// Sets the load address for an entire module, assuming a rigid + /// slide of sections, if possible in the implementation. + /// + /// @return + /// Returns true iff any section's load address changed. + //------------------------------------------------------------------ + virtual bool + SetLoadAddress(Target &target, + lldb::addr_t value, + bool value_is_offset) + { + return false; + } + + //------------------------------------------------------------------ /// Gets whether endian swapping should occur when extracting data /// from this object file. /// diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index 75e0900ab640..db32ba373e42 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -291,6 +291,17 @@ public: virtual void DumpSymbolContext (Stream *s); + lldb::DisassemblerSP + GetInstructions (const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache); + + bool + GetDisassembly (const ExecutionContext &exe_ctx, + const char *flavor, + bool prefer_file_cache, + Stream &strm); + protected: uint32_t m_uid; // User ID (usually the original symbol table index) diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index a0501440f18c..6fdd828bd9f2 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -17,6 +17,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Mangled.h" #include "lldb/Symbol/LineEntry.h" +#include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -552,6 +553,14 @@ protected: // Member variables. //------------------------------------------------------------------ collection m_symbol_contexts; ///< The list of symbol contexts. + +public: + typedef AdaptedIterable<collection, SymbolContext, vector_adapter> SymbolContextIterable; + SymbolContextIterable + SymbolContexts() + { + return SymbolContextIterable(m_symbol_contexts); + } }; bool operator== (const SymbolContext& lhs, const SymbolContext& rhs); diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index 920f571fa1e9..da327439936c 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -417,7 +417,15 @@ public: return type_sp->GetClangLayoutType().GetLValueReferenceType(); return clang_type.GetLValueReferenceType(); } - + + ClangASTType + GetTypedefedType () const + { + if (type_sp) + return type_sp->GetClangFullType().GetTypedefedType(); + return clang_type.GetTypedefedType(); + } + ClangASTType GetDereferencedType () const { @@ -513,6 +521,9 @@ public: GetReferenceType () const; TypeImpl + GetTypedefedType () const; + + TypeImpl GetDereferencedType () const; TypeImpl diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index cefb91eb371a..3a99eb463df4 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -57,7 +57,7 @@ private: bool m_initialized; // delay some initialization until ObjectFile is set up - UnwindAssembly* m_assembly_profiler; + lldb::UnwindAssemblySP m_assembly_profiler; DWARFCallFrameInfo* m_eh_frame; diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h index 272f64f33113..6652a5ec144f 100644 --- a/include/lldb/Target/DynamicLoader.h +++ b/include/lldb/Target/DynamicLoader.h @@ -246,6 +246,60 @@ public: protected: //------------------------------------------------------------------ + // Utility methods for derived classes + //------------------------------------------------------------------ + + /// Checks to see if the target module has changed, updates the target + /// accordingly and returns the target executable module. + lldb::ModuleSP + GetTargetExecutable(); + + /// Updates the load address of every allocatable section in @p module. + /// + /// @param module The module to traverse. + /// + /// @param link_map_addr The virtual address of the link map for the @p module. + /// + /// @param base_addr The virtual base address @p module is loaded at. + virtual void + UpdateLoadedSections(lldb::ModuleSP module, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr); + + // Utility method so base classes can share implementation of UpdateLoadedSections + void + UpdateLoadedSectionsCommon(lldb::ModuleSP module, + lldb::addr_t base_addr); + + /// Removes the loaded sections from the target in @p module. + /// + /// @param module The module to traverse. + virtual void + UnloadSections(const lldb::ModuleSP module); + + // Utility method so base classes can share implementation of UnloadSections + void + UnloadSectionsCommon(const lldb::ModuleSP module); + + /// Locates or creates a module given by @p file and updates/loads the + /// resulting module at the virtual base address @p base_addr. + lldb::ModuleSP + LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr); + + const lldb_private::SectionList * + GetSectionListFromModule(const lldb::ModuleSP module) const; + + // Read an unsigned int of the given size from memory at the given addr. + // Return -1 if the read fails, otherwise return the result as an int64_t. + int64_t + ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes); + + // Read a pointer from memory at the given addr. + // Return LLDB_INVALID_ADDRESS if the read fails. + lldb::addr_t + ReadPointer(lldb::addr_t addr); + + //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ Process* m_process; ///< The process that this dynamic loader plug-in is tracking. diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h index 4038e70b0c56..f825c2e72e6d 100644 --- a/include/lldb/Target/ExecutionContext.h +++ b/include/lldb/Target/ExecutionContext.h @@ -298,7 +298,7 @@ public: /// any valid weak references in this object. //------------------------------------------------------------------ ExecutionContext - Lock () const; + Lock (bool thread_and_frame_only_if_stopped) const; //------------------------------------------------------------------ /// Returns true if this object has a weak reference to a thread. @@ -402,7 +402,7 @@ public: ExecutionContext (const lldb::ThreadWP &thread_wp); ExecutionContext (const lldb::StackFrameWP &frame_wp); ExecutionContext (const ExecutionContextRef &exe_ctx_ref); - ExecutionContext (const ExecutionContextRef *exe_ctx_ref); + ExecutionContext (const ExecutionContextRef *exe_ctx_ref, bool thread_and_frame_only_if_stopped = false); // These two variants take in a locker, and grab the target, lock the API mutex into locker, then // fill in the rest of the shared pointers. diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index 355c0528bed8..80011fd120de 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -314,9 +314,9 @@ namespace lldb_private { /// An error object. //------------------------------------------------------------------ virtual Error - GetFile (const FileSpec &platform_file, - const UUID *uuid_ptr, - FileSpec &local_file); + GetFileWithUUID (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file); //---------------------------------------------------------------------- // Locate the scripting resource given a module specification. @@ -835,6 +835,29 @@ namespace lldb_private { return LLDB_INVALID_QUEUE_ID; } + //------------------------------------------------------------------ + /// Provide a list of trap handler function names for this platform + /// + /// The unwinder needs to treat trap handlers specially -- the stack + /// frame may not be aligned correctly for a trap handler (the kernel + /// often won't perturb the stack pointer, or won't re-align it properly, + /// in the process of calling the handler) and the frame above the handler + /// needs to be treated by the unwinder's "frame 0" rules instead of its + /// "middle of the stack frame" rules. + /// + /// In a user process debugging scenario, the list of trap handlers is + /// typically just "_sigtramp". + /// + /// The Platform base class provides the m_trap_handlers ivar but it does + /// not populate it. Subclasses should add the names of the asynchronous + /// signal handler routines as needed. For most Unix platforms, add _sigtramp. + /// + /// @return + /// A list of symbol names. The list may be empty. + //------------------------------------------------------------------ + virtual const std::vector<ConstString> & + GetTrapHandlerSymbolNames (); + protected: bool m_is_host; // Set to true when we are able to actually set the OS version while @@ -867,6 +890,24 @@ namespace lldb_private { std::string m_ssh_opts; bool m_ignores_remote_hostname; std::string m_local_cache_directory; + std::vector<ConstString> m_trap_handlers; + bool m_calculated_trap_handlers; + + //------------------------------------------------------------------ + /// Ask the Platform subclass to fill in the list of trap handler names + /// + /// For most Unix user process environments, this will be a single + /// function name, _sigtramp. More specialized environments may have + /// additional handler names. The unwinder code needs to know when a + /// trap handler is on the stack because the unwind rules for the frame + /// that caused the trap are different. + /// + /// The base class Platform ivar m_trap_handlers should be updated by + /// the Platform subclass when this method is called. If there are no + /// predefined trap handlers, this method may be a no-op. + //------------------------------------------------------------------ + virtual void + CalculateTrapHandlerSymbolNames () = 0; const char * GetCachedUserName (uint32_t uid) @@ -1115,7 +1156,9 @@ namespace lldb_private { bool m_ssh; std::string m_ssh_opts; + private: + DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH); }; diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index cda9b4f57118..f52b54da52cf 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -43,6 +43,7 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/PseudoTerminal.h" @@ -534,7 +535,8 @@ public: m_resume_count (0), m_monitor_callback (NULL), m_monitor_callback_baton (NULL), - m_monitor_signals (false) + m_monitor_signals (false), + m_hijack_listener_sp () { } @@ -553,7 +555,8 @@ public: m_resume_count (0), m_monitor_callback (NULL), m_monitor_callback_baton (NULL), - m_monitor_signals (false) + m_monitor_signals (false), + m_hijack_listener_sp () { if (stdin_path) { @@ -780,6 +783,7 @@ public: m_flags.Clear(); m_file_actions.clear(); m_resume_count = 0; + m_hijack_listener_sp.reset(); } bool @@ -799,6 +803,18 @@ public: m_monitor_signals = monitor_signals; } + Host::MonitorChildProcessCallback + GetMonitorProcessCallback () + { + return m_monitor_callback; + } + + const void* + GetMonitorProcessBaton () const + { + return m_monitor_callback_baton; + } + bool MonitorProcess () const { @@ -818,6 +834,19 @@ public: { return m_pty; } + + lldb::ListenerSP + GetHijackListener () const + { + return m_hijack_listener_sp; + } + + void + SetHijackListener (const lldb::ListenerSP &listener_sp) + { + m_hijack_listener_sp = listener_sp; + } + protected: std::string m_working_dir; @@ -830,7 +859,7 @@ protected: Host::MonitorChildProcessCallback m_monitor_callback; void *m_monitor_callback_baton; bool m_monitor_signals; - + lldb::ListenerSP m_hijack_listener_sp; }; //---------------------------------------------------------------------- @@ -863,6 +892,7 @@ public: ProcessInfo::operator= (launch_info); SetProcessPluginName (launch_info.GetProcessPluginName()); SetResumeCount (launch_info.GetResumeCount()); + SetHijackListener(launch_info.GetHijackListener()); } bool @@ -952,7 +982,22 @@ public: return true; return false; } + + lldb::ListenerSP + GetHijackListener () const + { + return m_hijack_listener_sp; + } + + void + SetHijackListener (const lldb::ListenerSP &listener_sp) + { + m_hijack_listener_sp = listener_sp; + } + + protected: + lldb::ListenerSP m_hijack_listener_sp; std::string m_plugin_name; uint32_t m_resume_count; // How many times do we resume after launching bool m_wait_for_launch; @@ -1366,10 +1411,11 @@ class Process : public ExecutionContextScope, public PluginInterface { -friend class ThreadList; -friend class ClangFunction; // For WaitForStateChangeEventsPrivate -friend class ProcessEventData; -friend class StopInfo; + friend class ClangFunction; // For WaitForStateChangeEventsPrivate + friend class ProcessEventData; + friend class StopInfo; + friend class Target; + friend class ThreadList; public: @@ -2112,21 +2158,15 @@ public: /// @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. - /// /// @param[in] attach_info /// Information on how to do the attach. For example, GetUserID() /// will return the uid to attach as. /// /// @return - /// Returns \a pid if attaching was successful, or - /// LLDB_INVALID_PROCESS_ID if attaching fails. + /// Returns an error object. //------------------------------------------------------------------ virtual Error - DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info) + DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info) { Error error; error.SetErrorString("attach by name is not supported"); @@ -2225,7 +2265,7 @@ public: //------------------------------------------------------------------ virtual Error DoLaunch (Module *exe_module, - const ProcessLaunchInfo &launch_info) + ProcessLaunchInfo &launch_info) { Error error; error.SetErrorStringWithFormat("error: %s does not support launching processes", GetPluginName().GetCString()); @@ -2991,15 +3031,11 @@ public: //------------------------------------------------------------------ virtual lldb::addr_t - ResolveIndirectFunction(const Address *address, Error &error) - { - error.SetErrorStringWithFormat("error: %s does not support indirect functions in the debug process", GetPluginName().GetCString()); - return LLDB_INVALID_ADDRESS; - } + ResolveIndirectFunction(const Address *address, Error &error); virtual Error - GetMemoryRegionInfo (lldb::addr_t load_addr, - MemoryRegionInfo &range_info) + GetMemoryRegionInfo (lldb::addr_t load_addr, + MemoryRegionInfo &range_info) { Error error; error.SetErrorString ("Process::GetMemoryRegionInfo() not supported"); @@ -3317,10 +3353,10 @@ public: { return m_thread_list.Threads(); } - + uint32_t GetNextThreadIndexID (uint64_t thread_id); - + lldb::ThreadSP CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context); @@ -3334,6 +3370,27 @@ public: AssignIndexIDToThread(uint64_t thread_id); //------------------------------------------------------------------ + // Queue Queries + //------------------------------------------------------------------ + + void + UpdateQueueListIfNeeded (); + + QueueList & + GetQueueList () + { + UpdateQueueListIfNeeded(); + return m_queue_list; + } + + QueueList::QueueIterable + Queues () + { + UpdateQueueListIfNeeded(); + return m_queue_list.Queues(); + } + + //------------------------------------------------------------------ // Event Handling //------------------------------------------------------------------ lldb::StateType @@ -3343,10 +3400,15 @@ public: // is set to the event which triggered the stop. If wait_always = false, // and the process is already stopped, this function returns immediately. lldb::StateType - WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL, bool wait_always = true); + WaitForProcessToStop (const TimeValue *timeout, + lldb::EventSP *event_sp_ptr = NULL, + bool wait_always = true, + Listener *hijack_listener = NULL); lldb::StateType - WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp); + WaitForStateChangedEvents (const TimeValue *timeout, + lldb::EventSP &event_sp, + Listener *hijack_listener); // Pass NULL to use builtin listener Event * PeekAtStateChangedEvents (); @@ -3513,6 +3575,12 @@ public: void SetSTDIOFileDescriptor (int file_descriptor); + void + WatchForSTDIN (IOHandler &io_handler); + + void + CancelWatchForSTDIN (bool exited); + //------------------------------------------------------------------ // Add a permanent region of memory that should never be read or // written to. This can be used to ensure that memory reads or writes @@ -3645,6 +3713,12 @@ protected: { return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread); } + + void + ForceNextEventDelivery() + { + m_force_next_event_delivery = true; + } //------------------------------------------------------------------ // Type definitions @@ -3685,6 +3759,8 @@ protected: ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads ThreadList m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops uint32_t m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated + QueueList m_queue_list; ///< The list of libdispatch queues at a given stop point + uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver. std::vector<lldb::addr_t> m_image_tokens; Listener &m_listener; @@ -3695,7 +3771,7 @@ protected: std::unique_ptr<SystemRuntime> m_system_runtime_ap; UnixSignals m_unix_signals; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; - lldb::InputReaderSP m_process_input_reader; + lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; Mutex m_stdio_communication_mutex; std::string m_stdout_data; @@ -3715,7 +3791,9 @@ protected: bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check. bool m_finalize_called; bool m_clear_thread_plans_on_stop; + bool m_force_next_event_delivery; lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent. + std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses; bool m_destroy_in_process; enum { @@ -3790,21 +3868,14 @@ protected: STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len); void - PushProcessInputReader (); + PushProcessIOHandler (); void - PopProcessInputReader (); + PopProcessIOHandler (); void - ResetProcessInputReader (); - - static size_t - ProcessInputReaderCallback (void *baton, - InputReader &reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - + ResetProcessIOHandler (); + Error HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp); diff --git a/include/lldb/Target/Queue.h b/include/lldb/Target/Queue.h new file mode 100644 index 000000000000..32ee24aebc11 --- /dev/null +++ b/include/lldb/Target/Queue.h @@ -0,0 +1,189 @@ +//===-- Queue.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_Queue_h_ +#define liblldb_Queue_h_ + +#include <vector> +#include <string> + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" +#include "lldb/Target/QueueItem.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// Queue: +// This class represents a libdispatch aka Grand Central Dispatch +// queue in the process. +// +// A program using libdispatch will create queues, put work items +// (functions, blocks) on the queues. The system will create / +// reassign pthreads to execute the work items for the queues. A +// serial queue will be associated with a single thread (or possibly +// no thread, if it is not doing any work). A concurrent queue may +// be associated with multiple threads. +//------------------------------------------------------------------ + + +class Queue : + public std::enable_shared_from_this<Queue> +{ +public: + + Queue (lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name); + + ~Queue (); + + //------------------------------------------------------------------ + /// Get the QueueID for this Queue + /// + /// A 64-bit ID number that uniquely identifies a queue at this particular + /// stop_id. Currently the libdispatch serialnum is used for the QueueID; + /// it is a number that starts at 1 for each process and increments with + /// each queue. A serialnum is not reused for a different queue in the + /// lifetime of that process execution. + /// + /// @return + /// The QueueID for this Queue. + //------------------------------------------------------------------ + lldb::queue_id_t + GetID (); + + //------------------------------------------------------------------ + /// Get the name of this Queue + /// + /// @return + /// The name of the queue, if one is available. + /// A NULL pointer is returned if none is available. + //------------------------------------------------------------------ + const char * + GetName (); + + //------------------------------------------------------------------ + /// Get the IndexID for this Queue + /// + /// This is currently the same as GetID(). If it changes in the future, + /// it will be a small integer value (starting with 1) assigned to + /// each queue that is seen during a Process lifetime. + /// + /// Both the GetID and GetIndexID are being retained for Queues to + /// maintain similar API to the Thread class, and allow for the + /// possibility of GetID changing to a different source in the future. + /// + /// @return + /// The IndexID for this queue. + //------------------------------------------------------------------ + uint32_t + GetIndexID (); + + //------------------------------------------------------------------ + /// Return the threads currently associated with this queue + /// + /// Zero, one, or many threads may be executing code for a queue at + /// a given point in time. This call returns the list of threads + /// that are currently executing work for this queue. + /// + /// @return + /// The threads currently performing work for this queue + //------------------------------------------------------------------ + std::vector<lldb::ThreadSP> + GetThreads (); + + //------------------------------------------------------------------ + /// Return the items that are currently enqueued + /// + /// "Enqueued" means that the item has been added to the queue to + /// be done, but has not yet been done. When the item is going to + /// be processed it is "dequeued". + /// + /// @return + /// The vector of enqueued items for this queue + //------------------------------------------------------------------ + const std::vector<lldb::QueueItemSP> & + GetPendingItems(); + + lldb::ProcessSP + GetProcess() const + { + return m_process_wp.lock(); + } + + //------------------------------------------------------------------ + /// Get the number of work items that this queue is currently running + /// + /// @return + /// The number of work items currently executing. For a serial + /// queue, this will be 0 or 1. For a concurrent queue, this + /// may be any number. + //------------------------------------------------------------------ + uint32_t + GetNumRunningWorkItems () const; + + //------------------------------------------------------------------ + /// Get the number of work items enqueued on this queue + /// + /// @return + /// The number of work items currently enqueued, waiting to + /// execute. + //------------------------------------------------------------------ + uint32_t + GetNumPendingWorkItems () const; + + //------------------------------------------------------------------ + /// Get the dispatch_queue_t structure address for this Queue + /// + /// Get the address in the inferior process' memory of this Queue's + /// dispatch_queue_t structure. + /// + /// @return + /// The address of the dispatch_queue_t structure, if known. + /// LLDB_INVALID_ADDRESS will be returned if it is unavailable. + //------------------------------------------------------------------ + lldb::addr_t + GetLibdispatchQueueAddress () const; + + + void + SetNumRunningWorkItems (uint32_t count); + + void + SetNumPendingWorkItems (uint32_t count); + + void + SetLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t_addr); + + void + PushPendingQueueItem (lldb::QueueItemSP item) + { + m_pending_items.push_back (item); + } + +private: + //------------------------------------------------------------------ + // For Queue only + //------------------------------------------------------------------ + + lldb::ProcessWP m_process_wp; + lldb::queue_id_t m_queue_id; + std::string m_queue_name; + uint32_t m_running_work_items_count; + uint32_t m_pending_work_items_count; + std::vector<lldb::QueueItemSP> m_pending_items; + lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch dispatch_queue_t for this Queue + + DISALLOW_COPY_AND_ASSIGN (Queue); +}; + +} // namespace lldb_private + +#endif // liblldb_Queue_h_ diff --git a/include/lldb/Target/QueueItem.h b/include/lldb/Target/QueueItem.h new file mode 100644 index 000000000000..76270da3bee6 --- /dev/null +++ b/include/lldb/Target/QueueItem.h @@ -0,0 +1,244 @@ +//===-- QueueItem.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_QueueItem_h_ +#define liblldb_QueueItem_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ConstString.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueItem: +// This class represents a work item enqueued on a libdispatch aka +// Grand Central Dispatch (GCD) queue. Most often, this will be a +// function or block. +// "enqueued" here means that the work item has been added to a queue +// but it has not yet started executing. When it is "dequeued", +// execution of the item begins. +//------------------------------------------------------------------ + + +class QueueItem : + public std::enable_shared_from_this<QueueItem> +{ +public: + + QueueItem (lldb::QueueSP queue_sp); + + ~QueueItem (); + + //------------------------------------------------------------------ + /// Get the kind of work item this is + /// + /// @return + /// The type of work item that this QueueItem object + /// represents. eQueueItemKindUnknown may be returned. + //------------------------------------------------------------------ + lldb::QueueItemKind + GetKind () const; + + //------------------------------------------------------------------ + /// Set the type of work item this is + /// + /// @param [in] item_kind + /// Set the kind of this work item object. + //------------------------------------------------------------------ + void + SetKind (lldb::QueueItemKind item_kind); + + //------------------------------------------------------------------ + /// Get the code address that will be executed when this work item + /// is executed. + /// + /// @return + /// The address that will be invoked when this work item is + /// executed. Not all types of QueueItems will have an + /// address associated with them; check that the returned + /// Address is valid, or check that the WorkItemKind is a + /// kind that involves an address, such as eQueueItemKindFunction + /// or eQueueItemKindBlock. + //------------------------------------------------------------------ + lldb_private::Address & + GetAddress (); + + //------------------------------------------------------------------ + /// Set the work item address for this object + /// + /// @param [in] addr + /// The address that will be invoked when this work item + /// is executed. + //------------------------------------------------------------------ + void + SetAddress (lldb_private::Address addr); + + //------------------------------------------------------------------ + /// Check if this QueueItem object is valid + /// + /// If the weak pointer to the parent Queue cannot be revivified, + /// it is invalid. + /// + /// @return + /// True if this object is valid. + //------------------------------------------------------------------ + bool + IsValid () + { + return m_queue_wp.lock() != NULL; + } + + //------------------------------------------------------------------ + /// Get an extended backtrace thread for this queue item, if available + /// + /// If the backtrace/thread information was collected when this item + /// was enqueued, this call will provide it. + /// + /// @param [in] type + /// The type of extended backtrace being requested, e.g. "libdispatch" + /// or "pthread". + /// + /// @return + /// A thread shared pointer which will have a reference to an extended + /// thread if one was available. + //------------------------------------------------------------------ + lldb::ThreadSP + GetExtendedBacktraceThread (ConstString type); + + void + SetItemThatEnqueuedThis (lldb::addr_t address_of_item) + { + m_item_that_enqueued_this_ref = address_of_item; + } + + lldb::addr_t + GetItemThatEnqueuedThis () + { + return m_item_that_enqueued_this_ref; + } + + void + SetEnqueueingThreadID (lldb::tid_t tid) + { + m_enqueueing_thread_id = tid; + } + + lldb::tid_t + GetEnqueueingThreadID () + { + return m_enqueueing_thread_id; + } + + void + SetEnqueueingQueueID (lldb::queue_id_t qid) + { + m_enqueueing_queue_id = qid; + } + + lldb::queue_id_t + GetEnqueueingQueueID () + { + return m_enqueueing_queue_id; + } + + void + SetTargetQueueID (lldb::queue_id_t qid) + { + m_target_queue_id = qid; + } + + void + SetStopID (uint32_t stop_id) + { + m_stop_id = stop_id; + } + + uint32_t + GetStopID () + { + return m_stop_id; + } + + void + SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace) + { + m_backtrace = backtrace; + } + + std::vector<lldb::addr_t> & + GetEnqueueingBacktrace () + { + return m_backtrace; + } + + void + SetThreadLabel (std::string thread_name) + { + m_thread_label = thread_name; + } + + std::string + GetThreadLabel () + { + return m_thread_label; + } + + void + SetQueueLabel (std::string queue_name) + { + m_queue_label = queue_name; + } + + std::string + GetQueueLabel () + { + return m_queue_label; + } + + void + SetTargetQueueLabel (std::string queue_name) + { + m_target_queue_label = queue_name; + } + +protected: + lldb::QueueWP m_queue_wp; + lldb::QueueItemKind m_kind; + lldb_private::Address m_address; + + lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording + // to get the QueueItem that enqueued this item + lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item + lldb::queue_id_t m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue + lldb::queue_id_t m_target_queue_id; + uint32_t m_stop_id; // indicates when this backtrace was recorded in time + std::vector<lldb::addr_t> m_backtrace; + std::string m_thread_label; + std::string m_queue_label; + std::string m_target_queue_label; + + +private: + //------------------------------------------------------------------ + // For QueueItem only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (QueueItem); + +}; + +} // namespace lldb_private + +#endif // liblldb_QueueItem_h_ diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h new file mode 100644 index 000000000000..964c1099233e --- /dev/null +++ b/include/lldb/Target/QueueList.h @@ -0,0 +1,141 @@ +//===-- QueueList.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_QueueList_h_ +#define liblldb_QueueList_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Utility/Iterable.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueList: +// This is the container for libdispatch aka Grand Central Dispatch +// Queue objects. +// +// Each Process will have a QueueList. When the process execution is +// paused, the QueueList may be populated with Queues by the +// SystemRuntime. +//------------------------------------------------------------------ + +class QueueList +{ +friend class Process; + +public: + + QueueList (Process *process); + + ~QueueList (); + + //------------------------------------------------------------------ + /// Get the number of libdispatch queues that are available + /// + /// @return + /// The number of queues that are stored in the QueueList. + //------------------------------------------------------------------ + uint32_t + GetSize(); + + //------------------------------------------------------------------ + /// Get the Queue at a given index number + /// + /// @param [in] idx + /// The index number (0-based) of the queue. + /// @return + /// The Queue at that index number. + //------------------------------------------------------------------ + lldb::QueueSP + GetQueueAtIndex (uint32_t idx); + + typedef std::vector<lldb::QueueSP> collection; + typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable; + + //------------------------------------------------------------------ + /// Iterate over the list of queues + /// + /// @return + /// An Iterable object which can be used to loop over the queues + /// that exist. + //------------------------------------------------------------------ + QueueIterable + Queues () + { + return QueueIterable(m_queues, m_mutex); + } + + //------------------------------------------------------------------ + /// Clear out the list of queues from the QueueList + //------------------------------------------------------------------ + void + Clear(); + + //------------------------------------------------------------------ + /// Add a Queue to the QueueList + /// + /// @param [in] queue + /// Used by the SystemRuntime to populate the QueueList + //------------------------------------------------------------------ + void + AddQueue (lldb::QueueSP queue); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by QueueID + /// + /// @param [in] qid + /// The QueueID (same as returned by Thread::GetQueueID()) to find. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByID (lldb::queue_id_t qid); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by IndexID + /// + /// @param [in] index_id + /// Find a queue by IndexID. This is an integer associated with each + /// unique queue seen during a debug session and will not be reused + /// for a different queue. Unlike the QueueID, a 64-bit value, this + /// will tend to be an integral value like 1 or 7. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByIndexID (uint32_t index_id); + + lldb_private::Mutex & + GetMutex (); + +protected: + + //------------------------------------------------------------------ + // Classes that inherit from Process can see and modify these + //------------------------------------------------------------------ + Process *m_process; ///< The process that manages this queue list. + uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for. + collection m_queues; ///< The queues for this process. + Mutex m_mutex; + +private: + QueueList (); +}; + +} // namespace lldb_private + +#endif // liblldb_QueueList_h_ diff --git a/include/lldb/Target/SectionLoadHistory.h b/include/lldb/Target/SectionLoadHistory.h new file mode 100644 index 000000000000..50dcfd3cc870 --- /dev/null +++ b/include/lldb/Target/SectionLoadHistory.h @@ -0,0 +1,109 @@ +//===-- SectionLoadHistory.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_SectionLoadHistory_h_ +#define liblldb_SectionLoadHistory_h_ + +// C Includes +// C++ Includes +#include <map> + +// Project includes +#include "lldb/lldb-public.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +class SectionLoadHistory +{ +public: + enum { + // Pass eStopIDNow to any function that takes a stop ID to get + // the current value. + eStopIDNow = UINT32_MAX + }; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SectionLoadHistory () : + m_stop_id_to_section_load_list(), + m_mutex (Mutex::eMutexTypeRecursive) + { + } + + ~SectionLoadHistory() + { + // Call clear since this takes a lock and clears the section load list + // in case another thread is currently using this section load list + Clear(); + } + + SectionLoadList & + GetCurrentSectionLoadList (); + + bool + IsEmpty() const; + + void + Clear (); + + uint32_t + GetLastStopID() const; + + // Get the section load address given a process stop ID + lldb::addr_t + GetSectionLoadAddress (uint32_t stop_id, + const lldb::SectionSP §ion_sp); + + bool + ResolveLoadAddress (uint32_t stop_id, + lldb::addr_t load_addr, + Address &so_addr); + + bool + SetSectionLoadAddress (uint32_t stop_id, + const lldb::SectionSP §ion_sp, + lldb::addr_t load_addr, + bool warn_multiple = false); + + // 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 + SetSectionUnloaded (uint32_t stop_id, + const lldb::SectionSP §ion_sp, + 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 + SetSectionUnloaded (uint32_t stop_id, + const lldb::SectionSP §ion_sp); + + void + Dump (Stream &s, + Target *target); + +protected: + + SectionLoadList * + GetSectionLoadListForStopID (uint32_t stop_id, bool read_only); + + typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList; + StopIDToSectionLoadList m_stop_id_to_section_load_list; + mutable Mutex m_mutex; + +private: + DISALLOW_COPY_AND_ASSIGN (SectionLoadHistory); +}; + +} // namespace lldb_private + +#endif // liblldb_SectionLoadHistory_h_ diff --git a/include/lldb/Target/SectionLoadList.h b/include/lldb/Target/SectionLoadList.h index ac05bf7a9cb4..6a9bbab93c98 100644 --- a/include/lldb/Target/SectionLoadList.h +++ b/include/lldb/Target/SectionLoadList.h @@ -36,6 +36,8 @@ public: { } + SectionLoadList (const SectionLoadList& rhs); + ~SectionLoadList() { // Call clear since this takes a lock and clears the section load list @@ -43,6 +45,9 @@ public: Clear(); } + void + operator=(const SectionLoadList &rhs); + bool IsEmpty() const; @@ -79,9 +84,6 @@ protected: addr_to_sect_collection m_addr_to_sect; sect_to_addr_collection m_sect_to_addr; mutable Mutex m_mutex; - -private: - DISALLOW_COPY_AND_ASSIGN (SectionLoadList); }; } // namespace lldb_private diff --git a/include/lldb/Target/SystemRuntime.h b/include/lldb/Target/SystemRuntime.h index 7a0703e6cc34..363ce122c4f3 100644 --- a/include/lldb/Target/SystemRuntime.h +++ b/include/lldb/Target/SystemRuntime.h @@ -20,9 +20,10 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/QueueList.h" +#include "lldb/Target/QueueItem.h" #include "lldb/lldb-private.h" - namespace lldb_private { //---------------------------------------------------------------------- @@ -103,6 +104,14 @@ public: virtual void ModulesDidLoad(lldb_private::ModuleList &module_list); + //------------------------------------------------------------------ + /// Called before detaching from a process. + /// + /// This will give a SystemRuntime plugin a chance to free any resources + /// in the inferior process before we detach. + //------------------------------------------------------------------ + virtual void + Detach (); //------------------------------------------------------------------ /// Return a list of thread origin extended backtraces that may @@ -160,6 +169,107 @@ public: virtual lldb::ThreadSP GetExtendedBacktraceThread (lldb::ThreadSP thread, ConstString type); + //------------------------------------------------------------------ + /// Get the extended backtrace thread for a QueueItem + /// + /// A QueueItem represents a function/block that will be executed on + /// a libdispatch queue in the future, or it represents a function/block + /// that is currently executing on a thread. + /// + /// This method will report a thread backtrace of the function that + /// enqueued it originally, if possible. + /// + /// @param [in] queue_item_sp + /// The QueueItem that we are getting an extended backtrace for. + /// + /// @param [in] type + /// The type of extended backtrace to fetch. The types supported + /// are returned from SystemRuntime::GetExtendedBacktraceTypes. + /// + /// @return + /// If an extended backtrace is available, it is returned. Else + /// an empty ThreadSP is returned. + //------------------------------------------------------------------ + virtual lldb::ThreadSP + GetExtendedBacktraceForQueueItem (lldb::QueueItemSP queue_item_sp, ConstString type) + { + return lldb::ThreadSP(); + } + + //------------------------------------------------------------------ + /// Populate the Process' QueueList with libdispatch / GCD queues that exist. + /// + /// When process execution is paused, the SystemRuntime may be called to fill + /// in the list of Queues that currently exist. + /// + /// @param [out] queue_list + /// This QueueList will be cleared, and any queues that currently exist + /// will be added. An empty QueueList will be returned if no queues + /// exist or if this Systemruntime does not support libdispatch queues. + //------------------------------------------------------------------ + virtual void + PopulateQueueList (lldb_private::QueueList &queue_list) + { + } + + //------------------------------------------------------------------ + /// Get the queue name for a thread given a thread's dispatch_qaddr. + /// + /// On systems using libdispatch queues, a thread may be associated with a queue. + /// There will be a call to get the thread's dispatch_qaddr. At the dispatch_qaddr + /// we will find the address of this thread's dispatch_queue_t structure. + /// Given the address of the dispatch_queue_t structure for a thread, + /// get the queue name and return it. + /// + /// @param [in] dispatch_qaddr + /// The address of the dispatch_queue_t structure for this thread. + /// + /// @return + /// The string of this queue's name. An empty string is returned if the + /// name could not be found. + //------------------------------------------------------------------ + virtual std::string + GetQueueNameFromThreadQAddress (lldb::addr_t dispatch_qaddr) + { + return ""; + } + + //------------------------------------------------------------------ + /// Get the QueueID for the libdispatch queue given the thread's dispatch_qaddr. + /// + /// On systems using libdispatch queues, a thread may be associated with a queue. + /// There will be a call to get the thread's dispatch_qaddr. At the dispatch_qaddr + /// we will find the address of this thread's dispatch_queue_t structure. + /// Given the address of the dispatch_queue_t structure for a thread, + /// get the queue ID and return it. + /// + /// @param [in] dispatch_qaddr + /// The address of the dispatch_queue_t structure for this thread. + /// + /// @return + /// The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID. + //------------------------------------------------------------------ + virtual lldb::queue_id_t + GetQueueIDFromThreadQAddress (lldb::addr_t dispatch_qaddr) + { + return LLDB_INVALID_QUEUE_ID; + } + + //------------------------------------------------------------------ + /// Get the pending work items for a libdispatch Queue + /// + /// If this system/process is using libdispatch and the runtime can do so, + /// retrieve the list of pending work items for the specified Queue and + /// add it to the Queue. + /// + /// @param [in] queue + /// The queue of interest. + //------------------------------------------------------------------ + virtual void + PopulatePendingItemsForQueue (lldb_private::Queue *queue) + { + } + protected: //------------------------------------------------------------------ // Member variables. diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index d874891a6aff..e65a511ab77a 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -35,7 +35,7 @@ #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/PathMappingList.h" -#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/SectionLoadHistory.h" namespace lldb_private { @@ -164,6 +164,9 @@ public: bool GetUseFastStepping() const; + + bool + GetDisplayExpressionsInCrashlogs () const; LoadScriptFromSymFile GetLoadScriptFromSymbolFile() const; @@ -174,6 +177,11 @@ public: MemoryModuleLoadLevel GetMemoryModuleLoadLevel() const; + bool + GetUserSpecifiedTrapHandlerNames (Args &args) const; + + void + SetUserSpecifiedTrapHandlerNames (const Args &args); }; typedef std::shared_ptr<TargetProperties> TargetPropertiesSP; @@ -526,6 +534,10 @@ public: void Destroy(); + + Error + Launch (Listener &listener, + ProcessLaunchInfo &launch_info); //------------------------------------------------------------------ // This part handles the breakpoints. @@ -630,7 +642,8 @@ public: CreateBreakpoint (lldb::SearchFilterSP &filter_sp, lldb::BreakpointResolverSP &resolver_sp, bool internal, - bool request_hardware); + bool request_hardware, + bool resolve_indirect_symbols); // Use this to create a watchpoint: lldb::WatchpointSP @@ -1001,14 +1014,14 @@ public: SectionLoadList& GetSectionLoadList() { - return m_section_load_list; + return m_section_load_history.GetCurrentSectionLoadList(); } - const SectionLoadList& - GetSectionLoadList() const - { - return m_section_load_list; - } +// const SectionLoadList& +// GetSectionLoadList() const +// { +// return const_cast<SectionLoadHistory *>(&m_section_load_history)->GetCurrentSectionLoadList(); +// } static Target * GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr, @@ -1048,6 +1061,26 @@ public: Error Install(ProcessLaunchInfo *launch_info); + + bool + ResolveLoadAddress (lldb::addr_t load_addr, + Address &so_addr, + uint32_t stop_id = SectionLoadHistory::eStopIDNow); + + bool + SetSectionLoadAddress (const lldb::SectionSP §ion, + lldb::addr_t load_addr, + bool warn_multiple = false); + + bool + SetSectionUnloaded (const lldb::SectionSP §ion_sp); + + bool + SetSectionUnloaded (const lldb::SectionSP §ion_sp, lldb::addr_t load_addr); + + void + ClearAllLoadedSections (); + // Since expressions results can persist beyond the lifetime of a process, // and the const expression results are available after a process is gone, // we provide a way for expressions to be evaluated from the Target itself. @@ -1144,7 +1177,7 @@ public: std::unique_ptr<ThreadSpec> m_thread_spec_ap; bool m_active; - // Use AddStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands, + // Use CreateStopHook to make a new empty stop hook. The GetCommandPointer and fill it with commands, // and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.) StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid); friend class Target; @@ -1153,8 +1186,8 @@ public: // Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook. // Returns the id of the new hook. - lldb::user_id_t - AddStopHook (StopHookSP &new_hook); + StopHookSP + CreateStopHook (); void RunStopHooks (); @@ -1250,7 +1283,7 @@ protected: Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe ArchSpec m_arch; ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded). - SectionLoadList m_section_load_list; + SectionLoadHistory m_section_load_history; BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; lldb::BreakpointSP m_last_created_breakpoint; @@ -1260,7 +1293,6 @@ protected: // 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; - bool m_valid; lldb::SearchFilterSP m_search_filter_sp; PathMappingList m_image_search_paths; std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap; @@ -1273,8 +1305,8 @@ protected: typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection; StopHookCollection m_stop_hooks; lldb::user_id_t m_stop_hook_next_id; + bool m_valid; bool m_suppress_stop_hooks; - bool m_suppress_synthetic_value; static void ImageSearchPathsChanged (const PathMappingList &path_list, diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h index 4f78b0fe6998..20687e977bff 100644 --- a/include/lldb/Target/Thread.h +++ b/include/lldb/Target/Thread.h @@ -44,6 +44,9 @@ public: const RegularExpression * GetSymbolsToAvoidRegexp(); + FileSpecList & + GetLibrariesToAvoid() const; + bool GetTraceEnabledState() const; }; @@ -410,6 +413,55 @@ public: DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx); //------------------------------------------------------------------ + /// Default implementation for stepping into. + /// + /// This function is designed to be used by commands where the + /// process is publicly stopped. + /// + /// @param[in] source_step + /// If true and the frame has debug info, then do a source level + /// step in, else do a single instruction step in. + /// + /// @param[in] avoid_code_without_debug_info + /// If \a true, then avoid stepping into code that doesn't have + /// debug info, else step into any code regardless of wether it + /// has debug info. + /// + /// @return + /// An error that describes anything that went wrong + //------------------------------------------------------------------ + virtual Error + StepIn (bool source_step, + bool avoid_code_without_debug_info); + + //------------------------------------------------------------------ + /// Default implementation for stepping over. + /// + /// This function is designed to be used by commands where the + /// process is publicly stopped. + /// + /// @param[in] source_step + /// If true and the frame has debug info, then do a source level + /// step over, else do a single instruction step over. + /// + /// @return + /// An error that describes anything that went wrong + //------------------------------------------------------------------ + virtual Error + StepOver (bool source_step); + + //------------------------------------------------------------------ + /// Default implementation for stepping out. + /// + /// This function is designed to be used by commands where the + /// process is publicly stopped. + /// + /// @return + /// An error that describes anything that went wrong + //------------------------------------------------------------------ + virtual Error + StepOut (); + //------------------------------------------------------------------ /// Retrieves the per-thread data area. /// Most OSs maintain a per-thread pointer (e.g. the FS register on /// x64), which we return the value of here. diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h index f4dfdb23ec0f..65d9b74098a6 100644 --- a/include/lldb/Target/ThreadList.h +++ b/include/lldb/Target/ThreadList.h @@ -45,6 +45,8 @@ public: void AddThread (const lldb::ThreadSP &thread_sp); + void + InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx); // Return the selected thread if there is one. Otherwise, return the thread // selected at index 0. lldb::ThreadSP diff --git a/include/lldb/Target/ThreadPlanStepInRange.h b/include/lldb/Target/ThreadPlanStepInRange.h index dbc8446b2e18..2f741f179bd4 100644 --- a/include/lldb/Target/ThreadPlanStepInRange.h +++ b/include/lldb/Target/ThreadPlanStepInRange.h @@ -73,7 +73,7 @@ protected: SetFlagsToDefault (); bool - FrameMatchesAvoidRegexp (); + FrameMatchesAvoidCriteria (); private: diff --git a/include/lldb/Target/UnwindAssembly.h b/include/lldb/Target/UnwindAssembly.h index 6a4ae0c30f27..254382ac029d 100644 --- a/include/lldb/Target/UnwindAssembly.h +++ b/include/lldb/Target/UnwindAssembly.h @@ -17,10 +17,11 @@ namespace lldb_private { class UnwindAssembly : + public std::enable_shared_from_this<UnwindAssembly>, public PluginInterface { public: - static UnwindAssembly* + static lldb::UnwindAssemblySP FindPlugin (const ArchSpec &arch); virtual diff --git a/include/lldb/Utility/Iterable.h b/include/lldb/Utility/Iterable.h index 9b91cae37eef..17335373e72d 100644 --- a/include/lldb/Utility/Iterable.h +++ b/include/lldb/Utility/Iterable.h @@ -147,9 +147,14 @@ public: return m_iter >= rhs.m_iter; } - friend AdaptedConstIterator operator+(typename BackingIterator::difference_type, AdaptedConstIterator &); - friend typename BackingIterator::difference_type operator-(AdaptedConstIterator &, AdaptedConstIterator &); - friend void swap(AdaptedConstIterator &, AdaptedConstIterator &); + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend AdaptedConstIterator<C1, E1, A1> operator+(typename C1::const_iterator::difference_type, AdaptedConstIterator<C1, E1, A1> &); + + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend typename C1::const_iterator::difference_type operator-(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); + + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend void swap(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); }; template <typename C, typename E, E (*A)(typename C::const_iterator &)> diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index 0b341575be46..c8294960a7b2 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -726,6 +726,19 @@ namespace lldb { eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX, } FilePermissions; + //---------------------------------------------------------------------- + // Queue work item types + // + // The different types of work that can be enqueued on a libdispatch + // aka Grand Central Dispatch (GCD) queue. + //---------------------------------------------------------------------- + typedef enum QueueItemKind + { + eQueueItemKindUnknown = 0, + eQueueItemKindFunction, + eQueueItemKindBlock + } QueueItemKind; + } // namespace lldb diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index 68d85f081e25..43e589e39521 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -82,6 +82,7 @@ class Disassembler; struct DumpValueObjectOptions; class DynamicLibrary; class DynamicLoader; +class Editline; class EmulateInstruction; class Error; class EvaluateExpressionOptions; @@ -102,9 +103,9 @@ class FuncUnwinders; class Function; class FunctionInfo; class InlineFunctionInfo; -class InputReader; class Instruction; class InstructionList; +class IOHandler; class IRExecutionUnit; class LanguageRuntime; class SystemRuntime; @@ -181,6 +182,8 @@ class SearchFilter; class Section; class SectionImpl; class SectionList; +class SectionLoadHistory; +class SectionLoadList; class Settings; class SourceManager; class SourceManagerImpl; @@ -214,6 +217,9 @@ class TypeFilterImpl; #ifndef LLDB_DISABLE_PYTHON class ScriptedSyntheticChildren; #endif +class Queue; +class QueueItem; +class QueueImpl; class Target; class TargetList; class Thread; @@ -297,8 +303,8 @@ namespace lldb { typedef std::shared_ptr<lldb_private::Function> FunctionSP; typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP; typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP; - typedef std::shared_ptr<lldb_private::InputReader> InputReaderSP; typedef std::shared_ptr<lldb_private::Instruction> InstructionSP; + typedef std::shared_ptr<lldb_private::IOHandler> IOHandlerSP; typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP; typedef std::shared_ptr<lldb_private::SystemRuntime> SystemRuntimeSP; typedef std::shared_ptr<lldb_private::LineTable> LineTableSP; @@ -334,12 +340,16 @@ namespace lldb { typedef std::shared_ptr<lldb_private::RegisterCheckpoint> RegisterCheckpointSP; typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP; typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP; + typedef std::shared_ptr<lldb_private::Queue> QueueSP; + typedef std::weak_ptr<lldb_private::Queue> QueueWP; + typedef std::shared_ptr<lldb_private::QueueItem> QueueItemSP; typedef std::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP; #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; #endif // #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::Section> SectionSP; typedef std::weak_ptr<lldb_private::Section> SectionWP; + typedef std::shared_ptr<lldb_private::SectionLoadList> SectionLoadListSP; typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP; typedef std::shared_ptr<lldb_private::Settings> SettingsSP; typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP; @@ -349,6 +359,7 @@ namespace lldb { typedef std::shared_ptr<lldb_private::StoppointLocation> StoppointLocationSP; typedef std::shared_ptr<lldb_private::Stream> StreamSP; typedef std::weak_ptr<lldb_private::Stream> StreamWP; + typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP; typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP; typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP; typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP; @@ -373,6 +384,7 @@ namespace lldb { #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptedSyntheticChildren> ScriptedSyntheticChildrenSP; #endif + typedef std::shared_ptr<lldb_private::UnwindAssembly> UnwindAssemblySP; typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP; typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP; typedef std::shared_ptr<lldb_private::Value> ValueSP; diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h index 98919422be58..c2273f5dfe2e 100644 --- a/include/lldb/lldb-private-enumerations.h +++ b/include/lldb/lldb-private-enumerations.h @@ -117,7 +117,9 @@ typedef enum PathType ePathTypeHeaderDir, // Find LLDB header file directory ePathTypePythonDir, // Find Python modules (PYTHONPATH) directory ePathTypeLLDBSystemPlugins, // System plug-ins directory - ePathTypeLLDBUserPlugins // User plug-ins directory + ePathTypeLLDBUserPlugins, // User plug-ins directory + ePathTypeLLDBTempSystemDir // The LLDB temp directory for this system + } PathType; @@ -251,6 +253,15 @@ typedef enum MemoryModuleLoadLevel { } MemoryModuleLoadLevel; +//---------------------------------------------------------------------- +// Result enums for when reading multiple lines from IOHandlers +//---------------------------------------------------------------------- +enum class LineStatus { + Success, // The line that was just edited if good and should be added to the lines + Error, // There is an error with the current line and it needs to be re-edited before it can be accepted + Done // Lines are complete +}; + } // namespace lldb_private diff --git a/include/lldb/lldb-private-log.h b/include/lldb/lldb-private-log.h index 48cce69d36cc..9d8d735dcf41 100644 --- a/include/lldb/lldb-private-log.h +++ b/include/lldb/lldb-private-log.h @@ -45,6 +45,7 @@ #define LIBLLDB_LOG_MMAP (1u << 23) #define LIBLLDB_LOG_OS (1u << 24) #define LIBLLDB_LOG_PLATFORM (1u << 25) +#define LIBLLDB_LOG_SYSTEM_RUNTIME (1u << 26) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ |