From johnny.chen at apple.com Mon Sep 5 21:52:28 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 06 Sep 2011 02:52:28 -0000 Subject: [Lldb-commits] [lldb] r139131 - in /lldb/trunk: include/lldb/Breakpoint/WatchpointLocation.h source/Breakpoint/WatchpointLocation.cpp Message-ID: <20110906025228.A4D0C2A6C12C@llvm.org> Author: johnny Date: Mon Sep 5 21:52:28 2011 New Revision: 139131 URL: http://llvm.org/viewvc/llvm-project?rev=139131&view=rev Log: Change the signature of WatchpointLocation ctor so that the second param becomes 'size_t size', instead of 'lldb::tid_t tid'. Pass size to the StoppointLocation ctor as well. Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h lldb/trunk/source/Breakpoint/WatchpointLocation.cpp Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h?rev=139131&r1=139130&r2=139131&view=diff ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h (original) +++ lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h Mon Sep 5 21:52:28 2011 @@ -29,7 +29,7 @@ { public: - WatchpointLocation (lldb::addr_t m_addr, lldb::tid_t tid, bool hardware); + WatchpointLocation (lldb::addr_t m_addr, size_t size, bool hardware); ~WatchpointLocation (); Modified: lldb/trunk/source/Breakpoint/WatchpointLocation.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointLocation.cpp?rev=139131&r1=139130&r2=139131&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/WatchpointLocation.cpp (original) +++ lldb/trunk/source/Breakpoint/WatchpointLocation.cpp Mon Sep 5 21:52:28 2011 @@ -18,8 +18,8 @@ using namespace lldb; using namespace lldb_private; -WatchpointLocation::WatchpointLocation (lldb::addr_t addr, lldb::tid_t tid, bool hardware) : - StoppointLocation (GetNextID(), addr, tid, hardware), +WatchpointLocation::WatchpointLocation (lldb::addr_t addr, size_t size, bool hardware) : + StoppointLocation (GetNextID(), addr, size, hardware), m_enabled(0), m_watch_read(0), m_watch_write(0), From granata.enrico at gmail.com Tue Sep 6 14:20:52 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Tue, 06 Sep 2011 19:20:52 -0000 Subject: [Lldb-commits] [lldb] r139160 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Symbol/ include/lldb/Target/ lldb.xcodeproj/ lldb.xcodeproj/xcshareddata/xcschemes/ scripts/ scripts/Python/ scripts/Python/interface/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Plugins/OperatingSystem/Darwin-Kernel/ source/Symbol/ source/Target/ test/e... Message-ID: <20110906192052.DFAB72A6C12C@llvm.org> Author: enrico Date: Tue Sep 6 14:20:51 2011 New Revision: 139160 URL: http://llvm.org/viewvc/llvm-project?rev=139160&view=rev Log: Redesign of the interaction between Python and frozen objects: - introduced two new classes ValueObjectConstResultChild and ValueObjectConstResultImpl: the first one is a ValueObjectChild obtained from a ValueObjectConstResult, the second is a common implementation backend for VOCR and VOCRCh of method calls meant to read through pointers stored in frozen objects ; now such reads transparently move from host to target as required - as a consequence of the above, removed code that made target-memory copies of expression results in several places throughout LLDB, and also removed code that enabled to recognize an expression result VO as such - introduced a new GetPointeeData() method in ValueObject that lets you read a given amount of objects of type T from a VO representing a T* or T[], and doing dereferences transparently in private layer it returns a DataExtractor ; in public layer it returns an instance of a newly created lldb::SBData - as GetPointeeData() does the right thing for both frozen and non-frozen ValueObject's, reimplemented ReadPointedString() to use it en lieu of doing the raw read itself - introduced a new GetData() method in ValueObject that lets you get a copy of the data that backs the ValueObject (for pointers, this returns the address without any previous dereferencing steps ; for arrays it actually reads the whole chunk of memory) in public layer this returns an SBData, just like GetPointeeData() - introduced a new CreateValueFromData() method in SBValue that lets you create a new SBValue from a chunk of data wrapped in an SBData the limitation to remember for this kind of SBValue is that they have no address: extracting the address-of for these objects (with any of GetAddress(), GetLoadAddress() and AddressOf()) will return invalid values - added several tests to check that "p"-ing objects (STL classes, char* and char[]) will do the right thing Solved a bug where global pointers to global variables were not dereferenced correctly for display New target setting "max-string-summary-length" gives the maximum number of characters to show in a string when summarizing it, instead of the hardcoded 128 Solved a bug where the summary for char[] and char* would not be shown if the ValueObject's were dumped via the "p" command Removed m_pointers_point_to_load_addrs from ValueObject. Introduced a new m_address_type_of_children, which each ValueObject can set to tell the address type of any pointers and/or references it creates. In the current codebase, this is load address most of the time (the only notable exception being file addresses that generate file address children UNLESS we have a live process) Updated help text for summary-string Fixed an issue in STL formatters where std::stlcontainer::iterator would match the container's synthetic children providers Edited the syntax and help for some commands to have proper argument types Added: lldb/trunk/include/lldb/API/SBData.h lldb/trunk/include/lldb/Core/ValueObjectConstResultChild.h lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h lldb/trunk/scripts/Python/interface/SBData.i lldb/trunk/source/API/SBData.cpp lldb/trunk/source/Core/ValueObjectConstResultChild.cpp lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp lldb/trunk/test/expression_command/formatters/ lldb/trunk/test/expression_command/formatters/Makefile lldb/trunk/test/expression_command/formatters/TestFormatters.py lldb/trunk/test/expression_command/formatters/foosynth.py lldb/trunk/test/expression_command/formatters/formatters.py lldb/trunk/test/expression_command/formatters/main.cpp lldb/trunk/test/python_api/sbdata/ lldb/trunk/test/python_api/sbdata/Makefile lldb/trunk/test/python_api/sbdata/TestSBData.py lldb/trunk/test/python_api/sbdata/main.cpp Modified: lldb/trunk/include/lldb/API/LLDB.h lldb/trunk/include/lldb/API/SBAddress.h lldb/trunk/include/lldb/API/SBDefines.h lldb/trunk/include/lldb/API/SBError.h lldb/trunk/include/lldb/API/SBStream.h lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/include/lldb/Core/DataExtractor.h lldb/trunk/include/lldb/Core/FormatClasses.h lldb/trunk/include/lldb/Core/FormatManager.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/include/lldb/Core/ValueObjectChild.h lldb/trunk/include/lldb/Core/ValueObjectConstResult.h lldb/trunk/include/lldb/Core/ValueObjectVariable.h lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h lldb/trunk/include/lldb/Symbol/ClangASTType.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme lldb/trunk/scripts/Python/build-swig-Python.sh lldb/trunk/scripts/Python/interface/SBValue.i lldb/trunk/scripts/Python/python-extensions.swig lldb/trunk/scripts/Python/python-wrapper.swig lldb/trunk/scripts/lldb.swig lldb/trunk/source/API/SBCommandInterpreter.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Commands/CommandObjectType.cpp lldb/trunk/source/Core/DataExtractor.cpp lldb/trunk/source/Core/DataVisualization.cpp lldb/trunk/source/Core/FormatClasses.cpp lldb/trunk/source/Core/FormatManager.cpp lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/Core/ValueObjectChild.cpp lldb/trunk/source/Core/ValueObjectConstResult.cpp lldb/trunk/source/Core/ValueObjectVariable.cpp lldb/trunk/source/Interpreter/CommandObject.cpp lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp lldb/trunk/source/Symbol/ClangASTType.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py lldb/trunk/test/functionalities/target_command/TestTargetCommand.py lldb/trunk/test/functionalities/target_command/globals.c lldb/trunk/test/lang/c/strings/TestCStrings.py Modified: lldb/trunk/include/lldb/API/LLDB.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/LLDB.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/LLDB.h (original) +++ lldb/trunk/include/lldb/API/LLDB.h Tue Sep 6 14:20:51 2011 @@ -24,6 +24,7 @@ #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBCommunication.h" #include "lldb/API/SBCompileUnit.h" +#include "lldb/API/SBData.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" Modified: lldb/trunk/include/lldb/API/SBAddress.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBAddress.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBAddress.h (original) +++ lldb/trunk/include/lldb/API/SBAddress.h Tue Sep 6 14:20:51 2011 @@ -106,6 +106,7 @@ friend class SBSymbolContext; friend class SBTarget; friend class SBThread; + friend class SBValue; #ifndef SWIG Added: lldb/trunk/include/lldb/API/SBData.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBData.h?rev=139160&view=auto ============================================================================== --- lldb/trunk/include/lldb/API/SBData.h (added) +++ lldb/trunk/include/lldb/API/SBData.h Tue Sep 6 14:20:51 2011 @@ -0,0 +1,136 @@ +//===-- SBData.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_SBData_h_ +#define LLDB_SBData_h_ + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +class SBData +{ +public: + + SBData (); + + SBData (const SBData &rhs); + +#ifndef SWIG + const SBData & + operator = (const SBData &rhs); +#endif + + ~SBData (); + + uint8_t + GetAddressByteSize (); + + void + Clear (); + + bool + IsValid(); + + size_t + GetByteSize (); + + lldb::ByteOrder + GetByteOrder(); + + float + GetFloat (lldb::SBError& error, uint32_t offset); + + double + GetDouble (lldb::SBError& error, uint32_t offset); + + long double + GetLongDouble (lldb::SBError& error, uint32_t offset); + + lldb::addr_t + GetAddress (lldb::SBError& error, uint32_t offset); + + uint8_t + GetUnsignedInt8 (lldb::SBError& error, uint32_t offset); + + uint16_t + GetUnsignedInt16 (lldb::SBError& error, uint32_t offset); + + uint32_t + GetUnsignedInt32 (lldb::SBError& error, uint32_t offset); + + uint64_t + GetUnsignedInt64 (lldb::SBError& error, uint32_t offset); + + int8_t + GetSignedInt8 (lldb::SBError& error, uint32_t offset); + + int16_t + GetSignedInt16 (lldb::SBError& error, uint32_t offset); + + int32_t + GetSignedInt32 (lldb::SBError& error, uint32_t offset); + + int64_t + GetSignedInt64 (lldb::SBError& error, uint32_t offset); + + const char* + GetString (lldb::SBError& error, uint32_t offset); + + size_t + ReadRawData (lldb::SBError& error, + uint32_t offset, + void *buf, + size_t size); + + bool + GetDescription (lldb::SBStream &description); + + // it would be nice to have SetData(SBError, const void*, size_t) when endianness and address size can be + // inferred from the existing DataExtractor, but having two SetData() signatures triggers a SWIG bug where + // the typemap isn't applied before resolving the overload, and thus the right function never gets called + void + SetData(lldb::SBError& error, const void *buf, size_t size, lldb::ByteOrder endian, uint8_t addr_size); + + // see SetData() for why we don't have Append(const void* buf, size_t size) + bool + Append(const SBData& rhs); + +protected: + +#ifndef SWIG + // Mimic shared pointer... + lldb_private::DataExtractor * + get() const; + + lldb_private::DataExtractor * + operator->() const; + + lldb::DataExtractorSP & + operator*(); + + const lldb::DataExtractorSP & + operator*() const; +#endif + + SBData (const lldb::DataExtractorSP &data_sp); + + void + SetOpaque (const lldb::DataExtractorSP &data_sp); + +private: + friend class SBValue; + + lldb::DataExtractorSP m_opaque_sp; +}; + + +} // namespace lldb + +#endif // LLDB_SBData_h_ Modified: lldb/trunk/include/lldb/API/SBDefines.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDefines.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBDefines.h (original) +++ lldb/trunk/include/lldb/API/SBDefines.h Tue Sep 6 14:20:51 2011 @@ -34,6 +34,7 @@ class SBCommandReturnObject; class SBCommunication; class SBCompileUnit; +class SBData; class SBDebugger; class SBError; class SBEvent; Modified: lldb/trunk/include/lldb/API/SBError.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBError.h (original) +++ lldb/trunk/include/lldb/API/SBError.h Tue Sep 6 14:20:51 2011 @@ -72,6 +72,7 @@ #ifndef SWIG friend class SBArguments; + friend class SBData; friend class SBDebugger; friend class SBCommunication; friend class SBHostOS; Modified: lldb/trunk/include/lldb/API/SBStream.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStream.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBStream.h (original) +++ lldb/trunk/include/lldb/API/SBStream.h Tue Sep 6 14:20:51 2011 @@ -62,6 +62,7 @@ friend class SBBreakpoint; friend class SBBreakpointLocation; friend class SBCompileUnit; + friend class SBData; friend class SBEvent; friend class SBFrame; friend class SBFunction; Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Tue Sep 6 14:20:51 2011 @@ -10,14 +10,10 @@ #ifndef LLDB_SBValue_h_ #define LLDB_SBValue_h_ +#include "lldb/API/SBData.h" #include "lldb/API/SBDefines.h" #include "lldb/API/SBType.h" -#include - -#ifndef SWIG -class lldb_private::SyntheticScriptProvider; -#endif namespace lldb { @@ -130,6 +126,13 @@ lldb::SBValue CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type); + + // this has no address! GetAddress() and GetLoadAddress() as well as AddressOf() + // on the return of this call all return invalid + lldb::SBValue + CreateValueFromData (const char* name, + const SBData& data, + const SBType& type); //------------------------------------------------------------------ /// Get a child value by index from a value. @@ -207,7 +210,51 @@ lldb::SBValue AddressOf(); + + lldb::addr_t + GetLoadAddress(); + + lldb::SBAddress + GetAddress(); + //------------------------------------------------------------------ + /// Get an SBData wrapping what this SBValue points to. + /// + /// This method will dereference the current SBValue, if its + /// data type is a T* or T[], and extract item_count elements + /// of type T from it, copying their contents in an SBData. + /// + /// @param[in] item_idx + /// The index of the first item to retrieve. For an array + /// this is equivalent to array[item_idx], for a pointer + /// to *(pointer + item_idx). In either case, the measurement + /// unit for item_idx is the sizeof(T) rather than the byte + /// + /// @param[in] item_count + /// How many items should be copied into the output. By default + /// only one item is copied, but more can be asked for. + /// + /// @return + /// An SBData with the contents of the copied items, on success. + /// An empty SBData otherwise. + //------------------------------------------------------------------ + lldb::SBData + GetPointeeData (uint32_t item_idx = 0, + uint32_t item_count = 1); + + //------------------------------------------------------------------ + /// Get an SBData wrapping the contents of this SBValue. + /// + /// This method will read the contents of this object in memory + /// and copy them into an SBData for future use. + /// + /// @return + /// An SBData with the contents of this SBValue, on success. + /// An empty SBData otherwise. + //------------------------------------------------------------------ + lldb::SBData + GetData (); + uint32_t GetNumChildren (); @@ -245,15 +292,24 @@ GetExpressionPath (lldb::SBStream &description, bool qualify_cxx_base_classes); SBValue (const lldb::ValueObjectSP &value_sp); - + +#ifndef SWIG + // this must be defined in the .h file because synthetic children as implemented in the core + // currently rely on being able to extract the SharedPointer out of an SBValue. if the implementation + // is deferred to the .cpp file instead of being inlined here, the platform will fail to link + // correctly. however, this is temporary till a better general solution is found. FIXME + const lldb::ValueObjectSP& + get_sp() const + { + return m_opaque_sp; + } +#endif + protected: friend class SBValueList; friend class SBFrame; #ifndef SWIG - // need this to decapsulate the SP from here - friend class lldb_private::SyntheticScriptProvider; - // Mimic shared pointer... lldb_private::ValueObject * get() const; Modified: lldb/trunk/include/lldb/Core/DataExtractor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataExtractor.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/DataExtractor.h (original) +++ lldb/trunk/include/lldb/Core/DataExtractor.h Tue Sep 6 14:20:51 2011 @@ -364,7 +364,10 @@ /// The size in bytes of address values that will be extracted. //------------------------------------------------------------------ uint8_t - GetAddressByteSize () const; + GetAddressByteSize () const + { + return m_addr_size; + } //------------------------------------------------------------------ /// Get the number of bytes contained in this object. @@ -373,7 +376,10 @@ /// The total number of bytes of data this object refers to. //------------------------------------------------------------------ size_t - GetByteSize () const; + GetByteSize () const + { + return m_end - m_start; + } //------------------------------------------------------------------ /// Extract a C string from \a *offset_ptr. @@ -480,7 +486,10 @@ /// object's data, or NULL of there is no data in this object. //------------------------------------------------------------------ const uint8_t * - GetDataEnd () const; + GetDataEnd () const + { + return m_end; + } //------------------------------------------------------------------ /// Get the shared data offset. @@ -503,7 +512,10 @@ /// object's data, or NULL of there is no data in this object. //------------------------------------------------------------------ const uint8_t * - GetDataStart () const; + GetDataStart () const + { + return m_start; + } //------------------------------------------------------------------ @@ -519,7 +531,7 @@ /// unmodified. /// /// @return - /// The integer value that was extracted, or zero on failure. + /// The floating value that was extracted, or zero on failure. //------------------------------------------------------------------ float GetFloat (uint32_t *offset_ptr) const; @@ -751,7 +763,10 @@ /// state. //------------------------------------------------------------------ lldb::ByteOrder - GetByteOrder() const; + GetByteOrder() const + { + return m_byte_order; + } //------------------------------------------------------------------ /// Extract a uint8_t value from \a *offset_ptr. @@ -1046,7 +1061,10 @@ /// The size in bytes to use when extracting addresses. //------------------------------------------------------------------ void - SetAddressByteSize (uint8_t addr_size); + SetAddressByteSize (uint8_t addr_size) + { + m_addr_size = addr_size; + } //------------------------------------------------------------------ /// Set data with a buffer that is caller owned. @@ -1139,7 +1157,10 @@ /// The byte order value to use when extracting data. //------------------------------------------------------------------ void - SetByteOrder (lldb::ByteOrder byte_order); + SetByteOrder (lldb::ByteOrder byte_order) + { + m_byte_order = byte_order; + } //------------------------------------------------------------------ /// Skip an LEB128 number at \a *offset_ptr. @@ -1170,7 +1191,10 @@ /// object, \b false otherwise. //------------------------------------------------------------------ bool - ValidOffset (uint32_t offset) const; + ValidOffset (uint32_t offset) const + { + return offset < GetByteSize(); + } //------------------------------------------------------------------ /// Test the availability of \a length bytes of data from \a offset. @@ -1182,6 +1206,15 @@ bool ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const; + size_t + Copy (DataExtractor& dest_data) const; + + bool + Append (DataExtractor& rhs); + + bool + Append (void* bytes, uint32_t length); + protected: //------------------------------------------------------------------ // Member variables Modified: lldb/trunk/include/lldb/Core/FormatClasses.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/FormatClasses.h (original) +++ lldb/trunk/include/lldb/Core/FormatClasses.h Tue Sep 6 14:20:51 2011 @@ -76,10 +76,7 @@ { return m_format; } - - std::string - FormatObject(lldb::ValueObjectSP object); - + }; class SyntheticChildrenFrontEnd Modified: lldb/trunk/include/lldb/Core/FormatManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/FormatManager.h (original) +++ lldb/trunk/include/lldb/Core/FormatManager.h Tue Sep 6 14:20:51 2011 @@ -410,17 +410,17 @@ } lldb::FormatCategorySP - Category (const char* category_name = NULL, - bool can_create = true) + GetCategory (const char* category_name = NULL, + bool can_create = true) { if (!category_name) - return Category(m_default_category_name); - return Category(ConstString(category_name)); + return GetCategory(m_default_category_name); + return GetCategory(ConstString(category_name)); } lldb::FormatCategorySP - Category (const ConstString& category_name, - bool can_create = true); + GetCategory (const ConstString& category_name, + bool can_create = true); bool Get (ValueObject& valobj, Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Tue Sep 6 14:20:51 2011 @@ -679,23 +679,25 @@ bool UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format = true); - void + bool UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic = lldb::eNoDynamicValues); - DataExtractor & - GetDataExtractor (); - lldb::ValueObjectSP GetSP () { return m_manager->GetSharedPointer(this); } -protected: void - AddSyntheticChild (const ConstString &key, - ValueObject *valobj); -public: + SetName (const ConstString &name); + + lldb::addr_t + GetAddressOf (bool scalar_is_load_address = true, + AddressType *address_type = NULL); + + lldb::addr_t + GetPointerValue (AddressType *address_type = NULL); + lldb::ValueObjectSP GetSyntheticChild (const ConstString &key) const; @@ -762,6 +764,9 @@ return false; } + virtual SymbolContextScope * + GetSymbolContextScope(); + static void DumpValueObject (Stream &s, ValueObject *valobj) @@ -864,14 +869,22 @@ // if it is a char* and check_pointer is true, // it also checks that the pointer is valid bool - IsCStringContainer(bool check_pointer = false); + IsCStringContainer (bool check_pointer = false); void - ReadPointedString(Stream& s, - Error& error, - uint32_t max_length = 0, - bool honor_array = true, - lldb::Format item_format = lldb::eFormatCharArray); + ReadPointedString (Stream& s, + Error& error, + uint32_t max_length = 0, + bool honor_array = true, + lldb::Format item_format = lldb::eFormatCharArray); + + virtual size_t + GetPointeeData (DataExtractor& data, + uint32_t item_idx = 0, + uint32_t item_count = 1); + + virtual size_t + GetData (DataExtractor& data); bool GetIsConstant () const @@ -894,18 +907,6 @@ } void - SetIsExpressionResult(bool expr) - { - m_is_expression_result = expr; - } - - bool - GetIsExpressionResult() - { - return m_is_expression_result; - } - - void SetFormat (lldb::Format format) { if (format != m_format) @@ -968,11 +969,22 @@ GetNonBaseClassParent(); void - SetPointersPointToLoadAddrs (bool b) + SetAddressTypeOfChildren(AddressType at) { - m_pointers_point_to_load_addrs = b; + m_address_type_of_ptr_or_ref_children = at; } - + + AddressType + GetAddressTypeOfChildren() + { + if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) + { + if (m_parent) + return m_parent->GetAddressTypeOfChildren(); + } + return m_address_type_of_ptr_or_ref_children; + } + protected: typedef ClusterManager ValueObjectManager; @@ -1021,19 +1033,21 @@ m_value_did_change:1, m_children_count_valid:1, m_old_value_valid:1, - m_pointers_point_to_load_addrs:1, m_is_deref_of_parent:1, m_is_array_item_for_pointer:1, m_is_bitfield_for_scalar:1, m_is_expression_path_child:1, - m_is_child_at_offset:1, - m_is_expression_result:1; + m_is_child_at_offset:1; - // used to prevent endless looping into GetpPrintableRepresentation() + // used to prevent endless looping into GetPrintableRepresentation() uint32_t m_dump_printable_counter; + + AddressType m_address_type_of_ptr_or_ref_children; + friend class ClangExpressionDeclMap; // For GetValue friend class ClangExpressionVariable; // For SetName friend class Target; // For SetName + friend class ValueObjectConstResultImpl; //------------------------------------------------------------------ // Constructors and Destructors @@ -1046,7 +1060,8 @@ // Use this constructor to create a "root variable object". The ValueObject will be locked to this context // through-out its lifespan. - ValueObject (ExecutionContextScope *exe_scope); + ValueObject (ExecutionContextScope *exe_scope, + AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad); // Use this constructor to create a ValueObject owned by another ValueObject. It will inherit the ExecutionContext // of its parent. @@ -1088,19 +1103,14 @@ void ClearUserVisibleData(); - -public: void - SetName (const ConstString &name); + AddSyntheticChild (const ConstString &key, + ValueObject *valobj); + + DataExtractor & + GetDataExtractor (); - lldb::addr_t - GetPointerValue (AddressType &address_type, - bool scalar_is_load_address); - - lldb::addr_t - GetAddressOf (AddressType &address_type, - bool scalar_is_load_address); private: //------------------------------------------------------------------ // For ValueObject only Modified: lldb/trunk/include/lldb/Core/ValueObjectChild.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectChild.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectChild.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectChild.h Tue Sep 6 14:20:51 2011 @@ -104,8 +104,9 @@ // void // ReadValueFromMemory (ValueObject* parent, lldb::addr_t address); -private: +protected: friend class ValueObject; + friend class ValueObjectConstResult; ValueObjectChild (ValueObject &parent, clang::ASTContext *clang_ast, void *clang_type, @@ -115,7 +116,8 @@ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool is_base_class, - bool is_deref_of_parent); + bool is_deref_of_parent, + AddressType child_ptr_or_ref_addr_type); DISALLOW_COPY_AND_ASSIGN (ValueObjectChild); }; Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResult.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResult.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectConstResult.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectConstResult.h Tue Sep 6 14:20:51 2011 @@ -16,10 +16,12 @@ // Project includes #include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectConstResultImpl.h" + namespace lldb_private { //---------------------------------------------------------------------- -// A child of another ValueObject. +// A frozen ValueObject copied into host memory //---------------------------------------------------------------------- class ValueObjectConstResult : public ValueObject { @@ -27,14 +29,16 @@ static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, - uint32_t addr_byte_size); + uint32_t addr_byte_size, + lldb::addr_t address = LLDB_INVALID_ADDRESS); static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, clang::ASTContext *clang_ast, void *clang_type, const ConstString &name, - const DataExtractor &data); + const DataExtractor &data, + lldb::addr_t address = LLDB_INVALID_ADDRESS); static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, @@ -43,7 +47,8 @@ const ConstString &name, const lldb::DataBufferSP &result_data_sp, lldb::ByteOrder byte_order, - uint8_t addr_size); + uint8_t addr_size, + lldb::addr_t address = LLDB_INVALID_ADDRESS); static lldb::ValueObjectSP Create (ExecutionContextScope *exe_scope, @@ -91,7 +96,24 @@ void SetByteSize (size_t size); - + + virtual lldb::ValueObjectSP + Dereference (Error &error); + + virtual ValueObject * + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + + virtual lldb::ValueObjectSP + GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create); + + virtual lldb::ValueObjectSP + AddressOf (Error &error); + + virtual size_t + GetPointeeData (DataExtractor& data, + uint32_t item_idx = 0, + uint32_t item_count = 1); + protected: virtual bool UpdateValue (); @@ -106,17 +128,22 @@ clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from ConstString m_type_name; uint32_t m_byte_size; + + ValueObjectConstResultImpl m_impl; private: + friend class ValueObjectConstResultImpl; ValueObjectConstResult (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, - uint32_t addr_byte_size); + uint32_t addr_byte_size, + lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, clang::ASTContext *clang_ast, void *clang_type, const ConstString &name, - const DataExtractor &data); + const DataExtractor &data, + lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, clang::ASTContext *clang_ast, @@ -124,7 +151,8 @@ const ConstString &name, const lldb::DataBufferSP &result_data_sp, lldb::ByteOrder byte_order, - uint8_t addr_size); + uint8_t addr_size, + lldb::addr_t address); ValueObjectConstResult (ExecutionContextScope *exe_scope, clang::ASTContext *clang_ast, Added: lldb/trunk/include/lldb/Core/ValueObjectConstResultChild.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResultChild.h?rev=139160&view=auto ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectConstResultChild.h (added) +++ lldb/trunk/include/lldb/Core/ValueObjectConstResultChild.h Tue Sep 6 14:20:51 2011 @@ -0,0 +1,78 @@ +//===-- ValueObjectConstResultChild.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_ValueObjectConstResultChild_h_ +#define liblldb_ValueObjectConstResultChild_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ValueObjectChild.h" +#include "lldb/Core/ValueObjectConstResultImpl.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A child of a ValueObjectConstResult. +//---------------------------------------------------------------------- +class ValueObjectConstResultChild : public ValueObjectChild +{ +public: + + ValueObjectConstResultChild (ValueObject &parent, + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + uint32_t byte_size, + int32_t byte_offset, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, + bool is_base_class, + bool is_deref_of_parent); + + virtual ~ValueObjectConstResultChild(); + + virtual lldb::ValueObjectSP + Dereference (Error &error); + + virtual ValueObject * + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + + virtual lldb::clang_type_t + GetClangType () + { + return ValueObjectChild::GetClangType(); + } + + virtual lldb::ValueObjectSP + GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create); + + virtual lldb::ValueObjectSP + AddressOf (Error &error); + + virtual size_t + GetPointeeData (DataExtractor& data, + uint32_t item_idx = 0, + uint32_t item_count = 1); + +protected: + ValueObjectConstResultImpl m_impl; + +private: + friend class ValueObject; + friend class ValueObjectConstResult; + friend class ValueObjectConstResultImpl; + + DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResultChild); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectConstResultChild_h_ Added: lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h?rev=139160&view=auto ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h (added) +++ lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h Tue Sep 6 14:20:51 2011 @@ -0,0 +1,89 @@ +//===-- ValueObjectConstResultImpl.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_ValueObjectConstResultImpl_h_ +#define liblldb_ValueObjectConstResultImpl_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ValueObject.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +// A class wrapping common implementation details for operations in +// ValueObjectConstResult ( & Child ) that may need to jump from the host +// memory space into the target's memory space +//---------------------------------------------------------------------- +class ValueObjectConstResultImpl +{ +public: + + ValueObjectConstResultImpl (ValueObject* valobj, + lldb::addr_t live_address = LLDB_INVALID_ADDRESS); + + virtual + ~ValueObjectConstResultImpl() + { + } + + lldb::ValueObjectSP + Dereference (Error &error); + + ValueObject * + CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index); + + lldb::ValueObjectSP + GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create); + + lldb::ValueObjectSP + AddressOf (Error &error); + + bool + NeedsDerefOnTarget() + { + m_impl_backend->UpdateValueIfNeeded(false); + return (m_impl_backend->GetValue().GetValueType() == Value::eValueTypeHostAddress); + } + + lldb::addr_t + GetLiveAddress() + { + return m_live_address; + } + + void + SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS) + { + m_live_address = addr; + } + + lldb::ValueObjectSP + DerefOnTarget(); + + virtual size_t + GetPointeeData (DataExtractor& data, + uint32_t item_idx = 0, + uint32_t item_count = 1); + +private: + + ValueObject *m_impl_backend; + lldb::addr_t m_live_address; + lldb::ValueObjectSP m_load_addr_backend; + lldb::ValueObjectSP m_address_of_backend; + + DISALLOW_COPY_AND_ASSIGN (ValueObjectConstResultImpl); +}; + +} // namespace lldb_private + +#endif // liblldb_ValueObjectConstResultImpl_h_ Modified: lldb/trunk/include/lldb/Core/ValueObjectVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectVariable.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObjectVariable.h (original) +++ lldb/trunk/include/lldb/Core/ValueObjectVariable.h Tue Sep 6 14:20:51 2011 @@ -54,6 +54,9 @@ virtual Module* GetModule(); + + virtual SymbolContextScope * + GetSymbolContextScope(); protected: virtual bool Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Tue Sep 6 14:20:51 2011 @@ -10,8 +10,6 @@ #ifndef liblldb_ScriptInterpreter_h_ #define liblldb_ScriptInterpreter_h_ -#include "lldb/API/SBValue.h" - #include "lldb/lldb-private.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Utility/PseudoTerminal.h" @@ -41,7 +39,7 @@ typedef uint32_t (*SWIGPythonCalculateNumChildren) (void *implementor); typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name); - typedef lldb::SBValue* (*SWIGPythonCastPyObjectToSBValue) (void* data); + typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data); typedef void (*SWIGPythonUpdateSynthProviderInstance) (void* data); typedef bool (*SWIGPythonCallCommand) (const char *python_function_name, @@ -160,10 +158,10 @@ return 0; } - virtual void* + virtual lldb::ValueObjectSP GetChildAtIndex (void *implementor, uint32_t idx) { - return NULL; + return lldb::ValueObjectSP(); } virtual int @@ -177,12 +175,6 @@ { } - virtual lldb::SBValue* - CastPyObjectToSBValue (void* data) - { - return NULL; - } - virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original) +++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Tue Sep 6 14:20:51 2011 @@ -23,7 +23,7 @@ #include "lldb/Host/Terminal.h" namespace lldb_private { - + class ScriptInterpreterPython : public ScriptInterpreter { public: @@ -69,7 +69,7 @@ virtual uint32_t CalculateNumChildren (void *implementor); - virtual void* + virtual lldb::ValueObjectSP GetChildAtIndex (void *implementor, uint32_t idx); virtual int @@ -78,9 +78,6 @@ virtual void UpdateSynthProviderInstance (void* implementor); - virtual lldb::SBValue* - CastPyObjectToSBValue (void* data); - virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, @@ -161,6 +158,28 @@ RestoreTerminalState (); private: + + class Locker + { + public: + Locker (ScriptInterpreterPython *py_interpreter, + FILE* wait_msg_handle = NULL, + bool need_session = true); + + bool + HasAcquiredLock () + { + return m_release_lock; + } + + ~Locker (); + + private: + bool m_need_session; + bool m_release_lock; + ScriptInterpreterPython *m_python_interpreter; + FILE* m_tmp_fh; + }; static size_t InputReaderCallback (void *baton, @@ -181,7 +200,6 @@ bool m_valid_session; }; - } // namespace lldb_private Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Tue Sep 6 14:20:51 2011 @@ -285,6 +285,21 @@ static lldb::clang_type_t GetPointeeType (lldb::clang_type_t opaque_clang_qual_type); + + lldb::clang_type_t + GetArrayElementType (uint32_t& stride); + + static lldb::clang_type_t + GetArrayElementType (clang::ASTContext* ast, + lldb::clang_type_t opaque_clang_qual_type, + uint32_t& stride); + + lldb::clang_type_t + GetPointerType (); + + static lldb::clang_type_t + GetPointerType (clang::ASTContext *ast_context, + lldb::clang_type_t opaque_clang_qual_type); static lldb::clang_type_t RemoveFastQualifiers (lldb::clang_type_t); Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Tue Sep 6 14:20:51 2011 @@ -91,7 +91,12 @@ { return m_max_children_display; } - + uint32_t + GetMaximumSizeOfStringSummary() + { + return m_max_strlen_length; + } + protected: void @@ -107,6 +112,7 @@ OptionValueBoolean m_skip_prologue; PathMappingList m_source_map; uint32_t m_max_children_display; + uint32_t m_max_strlen_length; }; @@ -478,7 +484,8 @@ bool prefer_file_cache, void *dst, size_t dst_len, - Error &error); + Error &error, + lldb::addr_t *load_addr_ptr = NULL); size_t ReadScalarIntegerFromMemory (const Address& addr, Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Sep 6 14:20:51 2011 @@ -354,6 +354,7 @@ eArgTypeCount, eArgTypeEndAddress, eArgTypeExpression, + eArgTypeExpressionPath, eArgTypeExprFormat, eArgTypeFilename, eArgTypeFormat, @@ -376,6 +377,9 @@ eArgTypePid, eArgTypePlugin, eArgTypeProcessName, + eArgTypePythonClass, + eArgTypePythonFunction, + eArgTypePythonScript, eArgTypeQueueName, eArgTypeRegisterName, eArgTypeRegularExpression, Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Tue Sep 6 14:20:51 2011 @@ -34,6 +34,7 @@ typedef SharedPtr::Type ConnectionSP; typedef SharedPtr::Type CompUnitSP; typedef SharedPtr::Type DataBufferSP; + typedef SharedPtr::Type DataExtractorSP; typedef SharedPtr::Type DebuggerSP; typedef SharedPtr::Type DisassemblerSP; typedef SharedPtr::Type DynamicLoaderSP; Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Tue Sep 6 14:20:51 2011 @@ -181,6 +181,10 @@ class ValueFormat; class ValueList; class ValueObject; +class ValueObjectChild; +class ValueObjectConstResult; +class ValueObjectConstResultChild; +class ValueObjectConstResultImpl; class ValueObjectList; class Variable; class VariableList; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Sep 6 14:20:51 2011 @@ -408,11 +408,15 @@ 4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; }; 94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; }; 9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */; }; + 9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; }; + 9443B123140C26AB0013457C /* SBData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9443B120140C18A90013457C /* SBData.h */; settings = {ATTRIBUTES = (Public, ); }; }; 94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94611EB113CCA4A4003A22AF /* RefCounter.cpp */; }; 9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; }; 9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; }; 9470A8F01402DFFB0056FF61 /* DataVisualization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9470A8EF1402DFFB0056FF61 /* DataVisualization.cpp */; }; + 949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; }; 94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; }; + 94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; }; 9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; }; 9A22A161135E30370024DDC3 /* EmulateInstructionARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A22A15D135E30370024DDC3 /* EmulateInstructionARM.cpp */; }; @@ -1188,6 +1192,8 @@ 94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = ""; }; 9415F61613B2C0DC00A52B36 /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = FormatManager.h; path = include/lldb/Core/FormatManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + 9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = ""; }; + 9443B121140C18C10013457C /* SBData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBData.cpp; path = source/API/SBData.cpp; sourceTree = ""; }; 94611EAF13CCA363003A22AF /* RefCounter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RefCounter.h; path = include/lldb/Utility/RefCounter.h; sourceTree = ""; }; 94611EB113CCA4A4003A22AF /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RefCounter.cpp; path = source/Utility/RefCounter.cpp; sourceTree = ""; }; 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = CommandObjectType.cpp; path = source/Commands/CommandObjectType.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -1196,12 +1202,18 @@ 9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = ""; }; 9470A8EE1402DF940056FF61 /* DataVisualization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataVisualization.h; path = include/lldb/Core/DataVisualization.h; sourceTree = ""; }; 9470A8EF1402DFFB0056FF61 /* DataVisualization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DataVisualization.cpp; path = source/Core/DataVisualization.cpp; sourceTree = ""; }; + 949ADF001406F62E004833E1 /* ValueObjectConstResultImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultImpl.h; path = include/lldb/Core/ValueObjectConstResultImpl.h; sourceTree = ""; }; + 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultImpl.cpp; path = source/Core/ValueObjectConstResultImpl.cpp; sourceTree = ""; }; 94A8287514031D05006C37A8 /* FormatNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatNavigator.h; path = include/lldb/Core/FormatNavigator.h; sourceTree = ""; }; 94A9112B13D5DEF80046D8A6 /* FormatClasses.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatClasses.h; path = include/lldb/Core/FormatClasses.h; sourceTree = ""; }; 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/Core/FormatClasses.cpp; sourceTree = ""; }; 94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = ""; }; 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = ""; }; + 94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "modify-python-lldb.py"; sourceTree = ""; }; + 94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = ""; }; 94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = ""; }; + 94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = ""; }; + 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultChild.cpp; path = source/Core/ValueObjectConstResultChild.cpp; sourceTree = ""; }; 94FE476613FC1DA8001F8475 /* finish-swig-Python-LLDB.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "finish-swig-Python-LLDB.sh"; sourceTree = ""; }; 961FABB81235DE1600F93A47 /* FuncUnwinders.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FuncUnwinders.cpp; path = source/Symbol/FuncUnwinders.cpp; sourceTree = ""; }; 961FABB91235DE1600F93A47 /* UnwindPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindPlan.cpp; path = source/Symbol/UnwindPlan.cpp; sourceTree = ""; }; @@ -1651,6 +1663,8 @@ 260223E8115F06E500A601A2 /* SBCommunication.cpp */, 26DE205411618FB800A093E2 /* SBCompileUnit.h */, 26DE205E1161901B00A093E2 /* SBCompileUnit.cpp */, + 9443B120140C18A90013457C /* SBData.h */, + 9443B121140C18C10013457C /* SBData.cpp */, 9A9830FB1125FC5800A56CB0 /* SBDebugger.h */, 9A9830FA1125FC5800A56CB0 /* SBDebugger.cpp */, 2682F286115EF3BD00CCFF99 /* SBError.h */, @@ -1781,7 +1795,9 @@ 266960601199F4230075C61A /* build-swig-Python.sh */, 266960611199F4230075C61A /* edit-swig-python-wrapper-file.py */, 94FE476613FC1DA8001F8475 /* finish-swig-Python-LLDB.sh */, + 94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */, 9A48A3A7124AAA5A00922451 /* python-extensions.swig */, + 94E367CE140C4EEA001C7A5A /* python-typemaps.swig */, 94005E0313F438DF001EF42D /* python-wrapper.swig */, ); path = Python; @@ -2038,6 +2054,10 @@ 26BC7E9B10F1B85900F91463 /* ValueObjectChild.cpp */, 26424E3E125986D30016D82C /* ValueObjectConstResult.h */, 26424E3C125986CB0016D82C /* ValueObjectConstResult.cpp */, + 94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */, + 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */, + 949ADF001406F62E004833E1 /* ValueObjectConstResultImpl.h */, + 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */, 4CD0BD0C134BFAB600CB44D4 /* ValueObjectDynamicValue.h */, 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */, 26BC7D8410F1B77400F91463 /* ValueObjectList.h */, @@ -2679,6 +2699,7 @@ 2668021E115FD13D008E1FE4 /* SBCommandReturnObject.h in Headers */, 2668021F115FD13D008E1FE4 /* SBCommunication.h in Headers */, 26DE205511618FB800A093E2 /* SBCompileUnit.h in Headers */, + 9443B123140C26AB0013457C /* SBData.h in Headers */, 26680220115FD13D008E1FE4 /* SBDebugger.h in Headers */, 26680221115FD13D008E1FE4 /* SBDefines.h in Headers */, 26680222115FD13D008E1FE4 /* SBError.h in Headers */, @@ -2988,6 +3009,7 @@ 268F9D55123AA16600B91E9B /* SBSymbolContextList.cpp in Sources */, 26C72C961243229A0068DC16 /* SBStream.cpp in Sources */, 26B1FA1413380E61002886E2 /* LLDBWrapPython.cpp in Sources */, + 9443B122140C18C40013457C /* SBData.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3312,6 +3334,9 @@ 9470A8F01402DFFB0056FF61 /* DataVisualization.cpp in Sources */, 26274FA214030EEF006BA130 /* OperatingSystemDarwinKernel.cpp in Sources */, 26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */, + 94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */, + 949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */, + 268ED0A5140FF54200DE830F /* DataEncoder.cpp in Sources */, 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme (original) +++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme Tue Sep 6 14:20:51 2011 @@ -1,6 +1,6 @@ + version = "1.3"> @@ -28,6 +28,15 @@ buildConfiguration = "Debug"> + + + + + debugDocumentVersioning = "YES" + allowLocationSimulation = "YES"> + ignoresPersistentStateOnLaunch = "YES" + debugDocumentVersioning = "YES"> GetDescription (description); + return PyString_FromString (description.GetData()); + } +} %extend lldb::SBDebugger { PyObject *lldb::SBDebugger::__repr__ (){ lldb::SBStream description; Modified: lldb/trunk/scripts/Python/python-wrapper.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/scripts/Python/python-wrapper.swig (original) +++ lldb/trunk/scripts/Python/python-wrapper.swig Tue Sep 6 14:20:51 2011 @@ -540,7 +540,7 @@ } -SWIGEXPORT lldb::SBValue* +SWIGEXPORT void* LLDBSWIGPython_CastPyObjectToSBValue ( PyObject* data Modified: lldb/trunk/scripts/lldb.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/scripts/lldb.swig (original) +++ lldb/trunk/scripts/lldb.swig Tue Sep 6 14:20:51 2011 @@ -51,6 +51,7 @@ #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBCommunication.h" #include "lldb/API/SBCompileUnit.h" +#include "lldb/API/SBData.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBError.h" #include "lldb/API/SBEvent.h" @@ -78,25 +79,6 @@ #include "lldb/API/SBValueList.h" %} -%{ -template -class not_owning_ap -{ -private: - std::auto_ptr m_auto_ptr; -public: - explicit not_owning_ap (T* p=0) : m_auto_ptr(p) {} - not_owning_ap (not_owning_ap& a) : m_auto_ptr(a.m_auto_ptr) {} - template - not_owning_ap (not_owning_ap& a) : m_auto_ptr(a.m_auto_ptr) {} - not_owning_ap (const not_owning_ap& r) : m_auto_ptr(r.m_auto_ptr) {} - ~not_owning_ap() { m_auto_ptr.release(); } - T* get() const { return m_auto_ptr.get(); } - T& operator*() const { return *m_auto_ptr; } - void reset (T* p=0) { m_auto_ptr.release(); m_auto_ptr.reset(p); } -}; -%} - /* Various liblldb typedefs that SWIG needs to know about. */ #define __extension__ /* Undefine GCC keyword to make Swig happy when processing glibc's stdint.h. */ %include @@ -119,6 +101,7 @@ %include "./Python/interface/SBCommandReturnObject.i" %include "./Python/interface/SBCommunication.i" %include "./Python/interface/SBCompileUnit.i" +%include "./Python/interface/SBData.i" %include "./Python/interface/SBDebugger.i" %include "./Python/interface/SBError.i" %include "./Python/interface/SBEvent.i" Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/API/SBCommandInterpreter.cpp (original) +++ lldb/trunk/source/API/SBCommandInterpreter.cpp Tue Sep 6 14:20:51 2011 @@ -334,7 +334,7 @@ extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor); extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); -extern "C" lldb::SBValue* LLDBSWIGPython_CastPyObjectToSBValue (void* data); +extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data); extern "C" void LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); extern "C" bool LLDBSwigPythonCallCommand Added: lldb/trunk/source/API/SBData.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBData.cpp?rev=139160&view=auto ============================================================================== --- lldb/trunk/source/API/SBData.cpp (added) +++ lldb/trunk/source/API/SBData.cpp Tue Sep 6 14:20:51 2011 @@ -0,0 +1,489 @@ +//===-- SBData.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBData.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" + +using namespace lldb; +using namespace lldb_private; + +SBData::SBData () +{ +} + +SBData::SBData (const lldb::DataExtractorSP& data_sp) : + m_opaque_sp (data_sp) +{ +} + +SBData::SBData(const SBData &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBData & +SBData::operator = (const SBData &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBData::~SBData () +{ +} + +void +SBData::SetOpaque (const lldb::DataExtractorSP &data_sp) +{ + m_opaque_sp = data_sp; +} + +lldb_private::DataExtractor * +SBData::get() const +{ + return m_opaque_sp.get(); +} + +lldb_private::DataExtractor * +SBData::operator->() const +{ + return m_opaque_sp.operator->(); +} + +lldb::DataExtractorSP & +SBData::operator*() +{ + return m_opaque_sp; +} + +const lldb::DataExtractorSP & +SBData::operator*() const +{ + return m_opaque_sp; +} + +bool +SBData::IsValid() +{ + return m_opaque_sp.get() != NULL; +} + +uint8_t +SBData::GetAddressByteSize () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint8_t value = 0; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetAddressByteSize(); + if (log) + log->Printf ("SBData::GetAddressByteSize () => " + "(%i)", value); + return value; +} + +void +SBData::Clear () +{ + if (m_opaque_sp.get()) + m_opaque_sp->Clear(); +} + +size_t +SBData::GetByteSize () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + size_t value = 0; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetByteSize(); + if (log) + log->Printf ("SBData::GetByteSize () => " + "(%i)", value); + return value; +} + +lldb::ByteOrder +SBData::GetByteOrder () +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::ByteOrder value = eByteOrderInvalid; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetByteOrder(); + if (log) + log->Printf ("SBData::GetByteOrder () => " + "(%i)", value); + return value; +} + +float +SBData::GetFloat (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + float value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetFloat(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetFloat (error=%p,offset=%d) => " + "(%f)", error.get(), offset, value); + return value; +} + +double +SBData::GetDouble (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + double value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetDouble(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetDouble (error=%p,offset=%d) => " + "(%f)", error.get(), offset, value); + return value; +} + +long double +SBData::GetLongDouble (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + long double value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetLongDouble(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetLongDouble (error=%p,offset=%d) => " + "(%lf)", error.get(), offset, value); + return value; +} + +lldb::addr_t +SBData::GetAddress (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::addr_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetAddress(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetAddress (error=%p,offset=%d) => " + "(%p)", error.get(), offset, (void*)value); + return value; +} + +uint8_t +SBData::GetUnsignedInt8 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint8_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU8(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%d) => " + "(%c)", error.get(), offset, value); + return value; +} + +uint16_t +SBData::GetUnsignedInt16 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint16_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU16(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%d) => " + "(%hd)", error.get(), offset, value); + return value; +} + +uint32_t +SBData::GetUnsignedInt32 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint32_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU32(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%d) => " + "(%d)", error.get(), offset, value); + return value; +} + +uint64_t +SBData::GetUnsignedInt64 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint64_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU64(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%d) => " + "(%q)", error.get(), offset, value); + return value; +} + +int8_t +SBData::GetSignedInt8 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int8_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%d) => " + "(%c)", error.get(), offset, value); + return value; +} + +int16_t +SBData::GetSignedInt16 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int16_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%d) => " + "(%hd)", error.get(), offset, value); + return value; +} + +int32_t +SBData::GetSignedInt32 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int32_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%d) => " + "(%d)", error.get(), offset, value); + return value; +} + +int64_t +SBData::GetSignedInt64 (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int64_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%d) => " + "(%q)", error.get(), offset, value); + return value; +} + +const char* +SBData::GetString (lldb::SBError& error, uint32_t offset) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char* value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetCStr(&offset); + if (offset == old_offset || (value == NULL)) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetString (error=%p,offset=%d) => " + "(%p)", error.get(), offset, value); + return value; +} + +bool +SBData::GetDescription (lldb::SBStream &description) +{ + if (m_opaque_sp) + { + description.ref(); + m_opaque_sp->Dump(description.get(), + 0, + lldb::eFormatBytesWithASCII, + 1, + m_opaque_sp->GetByteSize(), + 16, + LLDB_INVALID_ADDRESS, + 0, + 0); + } + else + description.Printf ("No Value"); + + return true; +} + +size_t +SBData::ReadRawData (lldb::SBError& error, + uint32_t offset, + void *buf, + size_t size) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + void* ok = NULL; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + ok = m_opaque_sp->GetU8(&offset, buf, size); + if ((offset == old_offset) || (ok == NULL)) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::ReadRawData (error=%p,offset=%d,buf=%p,size=%d) => " + "(%p)", error.get(), offset, buf, size, ok); + return ok ? size : 0; +} + +void +SBData::SetData(lldb::SBError& error, + const void *buf, + size_t size, + lldb::ByteOrder endian, + uint8_t addr_size) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buf, size, endian, addr_size)); + else + m_opaque_sp->SetData(buf, size, endian); + if (log) + log->Printf ("SBData::SetData (error=%p,buf=%p,size=%d,endian=%d,addr_size=%c) => " + "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get()); +} + +bool +SBData::Append(const SBData& rhs) +{ + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool value = false; + if (m_opaque_sp.get() && rhs.m_opaque_sp.get()) + value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp); + if (log) + log->Printf ("SBData::Append (rhs=%p) => " + "(%s)", rhs.get(), value ? "true" : "false"); + return value; +} \ No newline at end of file Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Tue Sep 6 14:20:51 2011 @@ -479,6 +479,38 @@ return result; } +lldb::SBValue +SBValue::CreateValueFromData (const char* name, + const SBData& data, + const SBType& type) +{ + SBValue result; + + AddressType addr_of_children_priv = eAddressTypeLoad; + + if (m_opaque_sp) + { + ValueObjectSP valobj_sp; + valobj_sp = ValueObjectConstResult::Create (m_opaque_sp->GetExecutionContextScope(), + type.m_opaque_sp->GetASTContext() , + type.m_opaque_sp->GetOpaqueQualType(), + ConstString(name), + *data.m_opaque_sp, + LLDB_INVALID_ADDRESS); + valobj_sp->SetAddressTypeOfChildren(addr_of_children_priv); + result = SBValue(valobj_sp); + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (result.IsValid()) + log->Printf ("SBValue(%p)::GetChildFromExpression => \"%s\"", m_opaque_sp.get(), result.m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetChildFromExpression => NULL", m_opaque_sp.get()); + } + return result; +} + SBValue SBValue::GetChildAtIndex (uint32_t idx) { @@ -812,9 +844,10 @@ SBProcess result; if (m_opaque_sp) { - if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) { - result = SBProcess(lldb::ProcessSP(m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetProcessSP())); + result = SBProcess(lldb::ProcessSP(target->GetProcessSP())); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -967,10 +1000,10 @@ SBValue sb_value; if (m_opaque_sp) { - if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) { - Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex()); - + Mutex::Locker api_locker (target->GetAPIMutex()); Error error; sb_value = m_opaque_sp->AddressOf (error); } @@ -981,3 +1014,127 @@ return sb_value; } + +lldb::addr_t +SBValue::GetLoadAddress() +{ + lldb::addr_t value = LLDB_INVALID_ADDRESS; + if (m_opaque_sp) + { + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) + { + Mutex::Locker api_locker (target->GetAPIMutex()); + const bool scalar_is_load_address = true; + AddressType addr_type; + value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + Module* module = m_opaque_sp->GetModule(); + if (!module) + value = LLDB_INVALID_ADDRESS; + else + { + Address addr; + module->ResolveFileAddress(value, addr); + value = addr.GetLoadAddress(m_opaque_sp->GetUpdatePoint().GetTargetSP().get()); + } + } + else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) + value = LLDB_INVALID_ADDRESS; + } + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", m_opaque_sp.get(), value); + + return value; +} + +lldb::SBAddress +SBValue::GetAddress() +{ + Address addr; + if (m_opaque_sp) + { + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) + { + lldb::addr_t value = LLDB_INVALID_ADDRESS; + Mutex::Locker api_locker (target->GetAPIMutex()); + const bool scalar_is_load_address = true; + AddressType addr_type; + value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + Module* module = m_opaque_sp->GetModule(); + if (module) + module->ResolveFileAddress(value, addr); + } + else if (addr_type == eAddressTypeLoad) + { + // no need to check the return value on this.. if it can actually do the resolve + // addr will be in the form (section,offset), otherwise it will simply be returned + // as (NULL, value) + addr.SetLoadAddress(value, target); + } + } + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); + return SBAddress(new Address(addr)); +} + +lldb::SBData +SBValue::GetPointeeData (uint32_t item_idx, + uint32_t item_count) +{ + lldb::SBData sb_data; + if (m_opaque_sp) + { + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) + { + DataExtractorSP data_sp(new DataExtractor()); + Mutex::Locker api_locker (target->GetAPIMutex()); + m_opaque_sp->GetPointeeData(*data_sp, item_idx, item_count); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", + m_opaque_sp.get(), + item_idx, + item_count, + sb_data.get()); + + return sb_data; +} + +lldb::SBData +SBValue::GetData () +{ + lldb::SBData sb_data; + if (m_opaque_sp) + { + Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); + if (target) + { + DataExtractorSP data_sp(new DataExtractor()); + Mutex::Locker api_locker (target->GetAPIMutex()); + m_opaque_sp->GetData(*data_sp); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + } + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetData () => SBData(%p)", + m_opaque_sp.get(), + sb_data.get()); + + return sb_data; +} Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Tue Sep 6 14:20:51 2011 @@ -1514,7 +1514,7 @@ OptionDefinition CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypeName, "Name of a Python function to use."}, + { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Sep 6 14:20:51 2011 @@ -321,9 +321,6 @@ { if (result_valobj_sp->GetError().Success()) { - - result_valobj_sp.get()->SetIsExpressionResult(true); - if (m_options.format != eFormatDefault) result_valobj_sp->SetFormat (m_options.format); Modified: lldb/trunk/source/Commands/CommandObjectType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectType.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectType.cpp Tue Sep 6 14:20:51 2011 @@ -1082,8 +1082,8 @@ { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, { LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, { LLDB_OPT_SET_2 , true, "summary-string", 's', required_argument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, - { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."}, - { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."}, + { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."}, + { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."}, { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."}, { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."}, @@ -3262,7 +3262,7 @@ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."}, + { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."}, { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } @@ -3548,7 +3548,7 @@ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."}, + { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; Modified: lldb/trunk/source/Core/DataExtractor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/DataExtractor.cpp (original) +++ lldb/trunk/source/Core/DataExtractor.cpp Tue Sep 6 14:20:51 2011 @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/MathExtras.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/DataBuffer.h" #include "lldb/Core/Log.h" @@ -178,15 +179,6 @@ } //------------------------------------------------------------------ -// Returns the total number of bytes that this object refers to -//------------------------------------------------------------------ -size_t -DataExtractor::GetByteSize () const -{ - return m_end - m_start; -} - -//------------------------------------------------------------------ // If this object contains shared data, this function returns the // offset into that shared data. Else zero is returned. //------------------------------------------------------------------ @@ -210,16 +202,6 @@ } //------------------------------------------------------------------ -// Returns true if OFFSET is a valid offset into the data in this -// object. -//------------------------------------------------------------------ -bool -DataExtractor::ValidOffset (uint32_t offset) const -{ - return offset < GetByteSize(); -} - -//------------------------------------------------------------------ // Returns true if there are LENGTH bytes availabe starting OFFSET // into the data that is in this object. //------------------------------------------------------------------ @@ -245,65 +227,6 @@ return ((offset + length) <= size); } -//------------------------------------------------------------------ -// Returns a pointer to the first byte contained in this object's -// data, or NULL of there is no data in this object. -//------------------------------------------------------------------ -const uint8_t * -DataExtractor::GetDataStart () const -{ - return m_start; -} -//------------------------------------------------------------------ -// Returns a pointer to the byte past the last byte contained in -// this object's data, or NULL of there is no data in this object. -//------------------------------------------------------------------ -const uint8_t * -DataExtractor::GetDataEnd () const -{ - return m_end; -} - -//------------------------------------------------------------------ -// Returns true if this object will endian swap values as it -// extracts data. -//------------------------------------------------------------------ -ByteOrder -DataExtractor::GetByteOrder () const -{ - return m_byte_order; -} -//------------------------------------------------------------------ -// Set whether this object will endian swap values as it extracts -// data. -//------------------------------------------------------------------ -void -DataExtractor::SetByteOrder (ByteOrder endian) -{ - m_byte_order = endian; -} - - -//------------------------------------------------------------------ -// Return the size in bytes of any address values this object will -// extract -//------------------------------------------------------------------ -uint8_t -DataExtractor::GetAddressByteSize () const -{ - return m_addr_size; -} - -//------------------------------------------------------------------ -// Set the size in bytes that will be used when extracting any -// address values from data contained in this object. -//------------------------------------------------------------------ -void -DataExtractor::SetAddressByteSize (uint8_t addr_size) -{ - m_addr_size = addr_size; -} - //---------------------------------------------------------------------- // Set the data with which this object will extract from to data // starting at BYTES and set the length of the data to LENGTH bytes @@ -1901,3 +1824,79 @@ base_addr, // Base address 0, 0); // Bitfield info } + +size_t +DataExtractor::Copy (DataExtractor &dest_data) const +{ + if (m_data_sp.get()) + { + // we can pass along the SP to the data + dest_data.SetData(m_data_sp); + } + else + { + const uint8_t *base_ptr = m_start; + size_t data_size = GetByteSize(); + dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size))); + } + return GetByteSize(); +} + +bool +DataExtractor::Append(DataExtractor& rhs) +{ + if (rhs.GetByteOrder() != GetByteOrder()) + return false; + + if (rhs.GetByteSize() == 0) + return true; + + if (GetByteSize() == 0) + return (rhs.Copy(*this) > 0); + + size_t bytes = GetByteSize() + rhs.GetByteSize(); + + DataBufferHeap *buffer_heap_ptr = NULL; + DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); + + if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL) + return false; + + uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes(); + + memcpy(bytes_ptr, GetDataStart(), GetByteSize()); + memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize()); + + SetData(buffer_sp); + + return true; +} + +bool +DataExtractor::Append(void* buf, uint32_t length) +{ + if (buf == NULL) + return false; + + if (length == 0) + return true; + + size_t bytes = GetByteSize() + length; + + DataBufferHeap *buffer_heap_ptr = NULL; + DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); + + if (buffer_sp.get() == NULL || buffer_heap_ptr == NULL) + return false; + + uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes(); + + if (GetByteSize() > 0) + memcpy(bytes_ptr, GetDataStart(), GetByteSize()); + + memcpy(bytes_ptr + GetByteSize(), buf, length); + + SetData(buffer_sp); + + return true; +} \ No newline at end of file Modified: lldb/trunk/source/Core/DataVisualization.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataVisualization.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/DataVisualization.cpp (original) +++ lldb/trunk/source/Core/DataVisualization.cpp Tue Sep 6 14:20:51 2011 @@ -106,14 +106,14 @@ bool DataVisualization::Categories::Get (const ConstString &category, lldb::FormatCategorySP &entry) { - entry = GetFormatManager().Category(category); + entry = GetFormatManager().GetCategory(category); return true; } void DataVisualization::Categories::Add (const ConstString &category) { - GetFormatManager().Category(category); + GetFormatManager().GetCategory(category); } bool @@ -132,13 +132,13 @@ void DataVisualization::Categories::Clear (ConstString &category) { - GetFormatManager().Category(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); + GetFormatManager().GetCategory(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); } void DataVisualization::Categories::Enable (ConstString& category) { - if (GetFormatManager().Category(category)->IsEnabled() == false) + if (GetFormatManager().GetCategory(category)->IsEnabled() == false) GetFormatManager().EnableCategory(category); else { @@ -150,7 +150,7 @@ void DataVisualization::Categories::Disable (ConstString& category) { - if (GetFormatManager().Category(category)->IsEnabled() == true) + if (GetFormatManager().GetCategory(category)->IsEnabled() == true) GetFormatManager().DisableCategory(category); } Modified: lldb/trunk/source/Core/FormatClasses.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/FormatClasses.cpp (original) +++ lldb/trunk/source/Core/FormatClasses.cpp Tue Sep 6 14:20:51 2011 @@ -41,30 +41,6 @@ { } -std::string -ValueFormat::FormatObject(lldb::ValueObjectSP object) -{ - if (!object.get()) - return "NULL"; - - StreamString sstr; - - if (ClangASTType::DumpTypeValue (object->GetClangAST(), // The clang AST - object->GetClangType(), // The clang type to display - &sstr, - m_format, // Format to display this type with - object->GetDataExtractor(), // Data to extract from - 0, // Byte offset into "data" - object->GetByteSize(), // Byte size of item in "data" - object->GetBitfieldBitSize(), // Bitfield bit size - object->GetBitfieldBitOffset())) // Bitfield bit offset - return (sstr.GetString()); - else - { - return ("unsufficient data for value"); - } -} - SummaryFormat::SummaryFormat(bool casc, bool skipptr, bool skipref, @@ -186,29 +162,8 @@ std::string ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object) { - lldb::ValueObjectSP target_object; - if (object->GetIsExpressionResult() && - ClangASTContext::IsPointerType(object->GetClangType()) && - object->GetValue().GetValueType() == Value::eValueTypeHostAddress) - { - // when using the expression parser, an additional layer of "frozen data" - // can be created, which is basically a byte-exact copy of the data returned - // by the expression, but in host memory. because Python code might need to read - // into the object memory in non-obvious ways, we need to hand it the target version - // of the expression output - lldb::addr_t tgt_address = object->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - target_object = ValueObjectConstResult::Create (object->GetExecutionContextScope(), - object->GetClangAST(), - object->GetClangType(), - object->GetName(), - tgt_address, - eAddressTypeLoad, - object->GetUpdatePoint().GetProcessSP()->GetAddressByteSize()); - } - else - target_object = object; return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(), - target_object).c_str()); + object).c_str()); } std::string @@ -282,25 +237,6 @@ return; } - if (be->GetIsExpressionResult() && - ClangASTContext::IsPointerType(be->GetClangType()) && - be->GetValue().GetValueType() == Value::eValueTypeHostAddress) - { - // when using the expression parser, an additional layer of "frozen data" - // can be created, which is basically a byte-exact copy of the data returned - // by the expression, but in host memory. because Python code might need to read - // into the object memory in non-obvious ways, we need to hand it the target version - // of the expression output - lldb::addr_t tgt_address = be->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - m_backend = ValueObjectConstResult::Create (be->GetExecutionContextScope(), - be->GetClangAST(), - be->GetClangType(), - be->GetName(), - tgt_address, - eAddressTypeLoad, - be->GetUpdatePoint().GetProcessSP()->GetAddressByteSize()); - } - m_interpreter = m_backend->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); if (m_interpreter == NULL) @@ -315,19 +251,7 @@ if (m_wrapper == NULL || m_interpreter == NULL) return lldb::ValueObjectSP(); - PyObject* py_return = (PyObject*)m_interpreter->GetChildAtIndex(m_wrapper, idx); - if (py_return == NULL || py_return == Py_None) - { - Py_XDECREF(py_return); - return lldb::ValueObjectSP(); - } - - lldb::SBValue *sb_ptr = m_interpreter->CastPyObjectToSBValue(py_return); - - if (py_return == NULL || sb_ptr == NULL) - return lldb::ValueObjectSP(); - - return sb_ptr->m_opaque_sp; + return m_interpreter->GetChildAtIndex(m_wrapper, idx); } std::string Modified: lldb/trunk/source/Core/FormatManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/FormatManager.cpp (original) +++ lldb/trunk/source/Core/FormatManager.cpp Tue Sep 6 14:20:51 2011 @@ -482,11 +482,11 @@ } lldb::FormatCategorySP -FormatManager::Category (const ConstString& category_name, +FormatManager::GetCategory (const ConstString& category_name, bool can_create) { if (!category_name) - return Category(m_default_category_name); + return GetCategory(m_default_category_name); lldb::FormatCategorySP category; if (m_categories_map.Get(category_name, category)) return category; @@ -495,7 +495,7 @@ return lldb::FormatCategorySP(); m_categories_map.Add(category_name,lldb::FormatCategorySP(new FormatCategory(this, category_name.AsCString()))); - return Category(category_name); + return GetCategory(category_name); } lldb::Format @@ -566,11 +566,13 @@ lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]")); - Category(m_system_category_name)->GetSummaryNavigator()->Add(ConstString("char *"), string_format); - Category(m_system_category_name)->GetSummaryNavigator()->Add(ConstString("const char *"), string_format); - Category(m_system_category_name)->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format); + FormatCategory::SharedPointer sys_category_sp = GetCategory(m_system_category_name); - Category(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category + sys_category_sp->GetSummaryNavigator()->Add(ConstString("char *"), string_format); + sys_category_sp->GetSummaryNavigator()->Add(ConstString("const char *"), string_format); + sys_category_sp->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format); + + GetCategory(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category // WARNING: temporary code!! // The platform should be responsible for initializing its own formatters @@ -586,24 +588,27 @@ true, false, "${var._M_dataplus._M_p}")); - Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::string"), - std_string_summary_sp); - Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::basic_string"), - std_string_summary_sp); - Category(m_gnu_cpp_category_name)->GetSummaryNavigator()->Add(ConstString("std::basic_string,std::allocator >"), - std_string_summary_sp); - Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::vector<")), + FormatCategory::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name); + + gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::string"), + std_string_summary_sp); + gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string"), + std_string_summary_sp); + gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string,std::allocator >"), + std_string_summary_sp); + + gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")), SyntheticChildrenSP(new SyntheticScriptProvider(true, false, false, "gnu_libstdcpp.StdVectorSynthProvider"))); - Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::map<")), + gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?map<.+> >$")), SyntheticChildrenSP(new SyntheticScriptProvider(true, false, false, "gnu_libstdcpp.StdMapSynthProvider"))); - Category(m_gnu_cpp_category_name)->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("std::list<")), + gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")), SyntheticChildrenSP(new SyntheticScriptProvider(true, false, false, Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Tue Sep 6 14:20:51 2011 @@ -89,14 +89,13 @@ m_value_did_change (false), m_children_count_valid (false), m_old_value_valid (false), - m_pointers_point_to_load_addrs (false), m_is_deref_of_parent (false), m_is_array_item_for_pointer(false), m_is_bitfield_for_scalar(false), m_is_expression_path_child(false), m_is_child_at_offset(false), - m_is_expression_result(parent.m_is_expression_result), - m_dump_printable_counter(0) + m_dump_printable_counter(0), + m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid) { m_manager->ManageObject(this); } @@ -104,7 +103,8 @@ //---------------------------------------------------------------------- // ValueObject constructor //---------------------------------------------------------------------- -ValueObject::ValueObject (ExecutionContextScope *exe_scope) : +ValueObject::ValueObject (ExecutionContextScope *exe_scope, + AddressType child_ptr_or_ref_addr_type) : UserID (++g_value_obj_uid), // Unique identifier for every value object m_parent (NULL), m_update_point (exe_scope), @@ -135,14 +135,13 @@ m_value_did_change (false), m_children_count_valid (false), m_old_value_valid (false), - m_pointers_point_to_load_addrs (false), m_is_deref_of_parent (false), m_is_array_item_for_pointer(false), m_is_bitfield_for_scalar(false), m_is_expression_path_child(false), m_is_child_at_offset(false), - m_is_expression_result(false), - m_dump_printable_counter(0) + m_dump_printable_counter(0), + m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type) { m_manager = new ValueObjectManager(); m_manager->ManageObject (this); @@ -165,13 +164,24 @@ ValueObject::UpdateValueIfNeeded (DynamicValueType use_dynamic, bool update_format) { + bool did_change_formats = false; + if (update_format) - UpdateFormatsIfNeeded(use_dynamic); + did_change_formats = UpdateFormatsIfNeeded(use_dynamic); // If this is a constant value, then our success is predicated on whether // we have an error or not if (GetIsConstant()) + { + // if you were asked to update your formatters, but did not get a chance to do it + // clear your own values (this serves the purpose of faking a stop-id for frozen + // objects (which are regarded as constant, but could have changes behind their backs + // because of the frozen-pointer depth limit) + // TODO: decouple summary from value and then remove this code and only force-clear the summary + if (update_format && !did_change_formats) + m_summary_str.clear(); return m_error.Success(); + } bool first_update = m_update_point.IsFirstEvaluation(); @@ -216,7 +226,7 @@ return m_error.Success(); } -void +bool ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); @@ -225,10 +235,14 @@ GetName().GetCString(), m_last_format_mgr_revision, DataVisualization::GetCurrentRevision()); + + bool any_change = false; + if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary) { ClearCustomSummaryFormat(); m_summary_str.clear(); + any_change = true; } if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) || m_last_format_mgr_dynamic != use_dynamic) @@ -242,6 +256,7 @@ m_synthetic_value = NULL; + any_change = true; DataVisualization::ValueFormats::Get(*this, eNoDynamicValues, m_last_value_format); DataVisualization::GetSummaryFormat(*this, use_dynamic, m_last_summary_format); DataVisualization::GetSyntheticChildren(*this, use_dynamic, m_last_synthetic_filter); @@ -251,6 +266,9 @@ ClearUserVisibleData(); } + + return any_change; + } void @@ -538,10 +556,11 @@ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent); - if (m_pointers_point_to_load_addrs) - valobj->SetPointersPointToLoadAddrs (m_pointers_point_to_load_addrs); - } + child_is_deref_of_parent, + eAddressTypeInvalid); + //if (valobj) + // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid); + } return valobj; } @@ -578,8 +597,7 @@ if (ClangASTContext::IsFunctionPointerType (clang_type)) { AddressType func_ptr_address_type = eAddressTypeInvalid; - addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true); - + addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type); if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) { switch (func_ptr_address_type) @@ -643,10 +661,157 @@ return true; addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; - cstr_address = GetAddressOf (cstr_address_type, true); + cstr_address = GetAddressOf (true, &cstr_address_type); return (cstr_address != LLDB_INVALID_ADDRESS); } +size_t +ValueObject::GetPointeeData (DataExtractor& data, + uint32_t item_idx, + uint32_t item_count) +{ + if (!IsPointerType() && !IsArrayType()) + return 0; + + if (item_count == 0) + return 0; + + uint32_t stride = 0; + + ClangASTType type(GetClangAST(), + GetClangType()); + + const uint64_t item_type_size = (IsPointerType() ? ClangASTType::GetTypeByteSize(GetClangAST(), type.GetPointeeType()) : + ClangASTType::GetTypeByteSize(GetClangAST(), type.GetArrayElementType(stride))); + + const uint64_t bytes = item_count * item_type_size; + + const uint64_t offset = item_idx * item_type_size; + + if (item_idx == 0 && item_count == 1) // simply a deref + { + if (IsPointerType()) + { + Error error; + ValueObjectSP pointee_sp = Dereference(error); + if (error.Fail() || pointee_sp.get() == NULL) + return 0; + return pointee_sp->GetDataExtractor().Copy(data); + } + else + { + ValueObjectSP child_sp = GetChildAtIndex(0, true); + if (child_sp.get() == NULL) + return 0; + return child_sp->GetDataExtractor().Copy(data); + } + return true; + } + else /* (items > 1) */ + { + Error error; + lldb_private::DataBufferHeap* heap_buf_ptr = NULL; + lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap()); + + AddressType addr_type; + lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type); + + ExecutionContextScope *exe_scope = m_update_point.GetExecutionContextScope(); + + + switch (addr_type) + { + case eAddressTypeFile: + { + Module* module = GetModule(); + if (module) + { + Address so_addr; + module->ResolveFileAddress(addr, so_addr); + if (exe_scope) + { + Target* target = exe_scope->CalculateTarget(); + if (target) + { + heap_buf_ptr->SetByteSize(bytes); + size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error); + if (error.Success()) + { + data.SetData(data_sp); + return bytes_read; + } + } + } + } + } + break; + case eAddressTypeLoad: + if (exe_scope) + { + Process *process = exe_scope->CalculateProcess(); + if (process) + { + heap_buf_ptr->SetByteSize(bytes); + size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error); + if (error.Success()) + { + data.SetData(data_sp); + return bytes_read; + } + } + } + break; + case eAddressTypeHost: + { + heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes); + data.SetData(data_sp); + return bytes; + } + break; + case eAddressTypeInvalid: + default: + break; + } + } + return 0; +} + +size_t +ValueObject::GetData (DataExtractor& data) +{ + UpdateValueIfNeeded(false); + ExecutionContext exe_ctx; + GetExecutionContextScope()->CalculateExecutionContext(exe_ctx); + Error error = m_value.GetValueAsData(&exe_ctx, GetClangAST(), data, 0, GetModule()); + if (error.Fail()) + return 0; + data.SetAddressByteSize(m_data.GetAddressByteSize()); + data.SetByteOrder(m_data.GetByteOrder()); + return data.GetByteSize(); +} + +// will compute strlen(str), but without consuming more than +// maxlen bytes out of str (this serves the purpose of reading +// chunks of a string without having to worry about +// missing NULL terminators in the chunk) +// of course, if strlen(str) > maxlen, the function will return +// maxlen_value (which should be != maxlen, because that allows you +// to know whether strlen(str) == maxlen or strlen(str) > maxlen) +static uint32_t +strlen_or_inf (const char* str, + uint32_t maxlen, + uint32_t maxlen_value) +{ + uint32_t len = 0; + while(*str) + { + len++;str++; + if (len > maxlen) + return maxlen_value; + } + return len; +} + void ValueObject::ReadPointedString(Stream& s, Error& error, @@ -656,7 +821,7 @@ { if (max_length == 0) - max_length = 128; // FIXME this should be a setting, or a formatting parameter + max_length = GetUpdatePoint().GetTargetSP()->GetMaximumSizeOfStringSummary(); clang_type_t clang_type = GetClangType(); clang_type_t elem_or_pointee_clang_type; @@ -690,14 +855,14 @@ capped_data = true; cstr_len = max_length; } - cstr_address = GetAddressOf (cstr_address_type, true); + cstr_address = GetAddressOf (true, &cstr_address_type); } else { // We have a pointer - cstr_address = GetPointerValue (cstr_address_type, true); + cstr_address = GetPointerValue (&cstr_address_type); } - if (cstr_address == LLDB_INVALID_ADDRESS) + if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) { s << ""; } @@ -706,18 +871,13 @@ Address cstr_so_addr (NULL, cstr_address); DataExtractor data; size_t bytes_read = 0; - std::vector data_buffer; - bool prefer_file_cache = false; if (cstr_len > 0 && honor_array) { - data_buffer.resize(cstr_len); - data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder()); - bytes_read = target->ReadMemory (cstr_so_addr, - prefer_file_cache, - &data_buffer.front(), - cstr_len, - error); - if (bytes_read > 0) + // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host + // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this + GetPointeeData(data, 0, cstr_len); + + if ( (bytes_read = data.GetByteSize()) > 0) { s << '"'; data.Dump (&s, @@ -740,29 +900,31 @@ { cstr_len = max_length; const size_t k_max_buf_size = 64; - data_buffer.resize (k_max_buf_size + 1); - // NULL terminate in case we don't get the entire C string - data_buffer.back() = '\0'; - - s << '"'; + + size_t offset = 0; bool any_data = false; - - data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder()); - while ((bytes_read = target->ReadMemory (cstr_so_addr, - prefer_file_cache, - &data_buffer.front(), - k_max_buf_size, - error)) > 0) + bool finished = false; + // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host + // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this + while ( (bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0 ) { - any_data = true; - size_t len = strlen(&data_buffer.front()); + size_t len = strlen_or_inf(data.PeekCStr(0), k_max_buf_size, k_max_buf_size+1); + if (len > k_max_buf_size) + len = k_max_buf_size; + if (!any_data) + { + s << '"'; + any_data = true; + } if (len == 0) break; if (len > bytes_read) len = bytes_read; if (len > cstr_len) len = cstr_len; + else + finished = true; data.Dump (&s, 0, // Start offset in "data" @@ -776,19 +938,22 @@ if (len < k_max_buf_size) break; + if (len >= cstr_len) - { - s << "..."; break; - } + cstr_len -= len; - cstr_so_addr.Slide (k_max_buf_size); + offset += len; } if (any_data == false) s << ""; - - s << '"'; + else + { + s << '"'; + if (finished == false) + s << "..."; + } } } } @@ -868,39 +1033,40 @@ case Value::eContextTypeLLDBType: case Value::eContextTypeVariable: { + lldb::Format my_format = GetFormat(); clang_type_t clang_type = GetClangType (); if (clang_type) { - if (m_format == lldb::eFormatDefault && m_last_value_format) - { - m_value_str = m_last_value_format->FormatObject(GetSP()); - } - else + if (m_format == lldb::eFormatDefault) { - StreamString sstr; - Format format = GetFormat(); - if (format == eFormatDefault) - format = (m_is_bitfield_for_scalar ? eFormatUnsigned : - ClangASTType::GetFormat(clang_type)); - - if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST - clang_type, // The clang type to display - &sstr, - format, // Format to display this type with - m_data, // Data to extract from - 0, // Byte offset into "m_data" - GetByteSize(), // Byte size of item in "m_data" - GetBitfieldBitSize(), // Bitfield bit size - GetBitfieldBitOffset())) // Bitfield bit offset - m_value_str.swap(sstr.GetString()); + if (m_last_value_format) + my_format = m_last_value_format->GetFormat(); else { - m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)", - m_data.GetByteSize(), - GetByteSize()); - m_value_str.clear(); + if (m_is_bitfield_for_scalar) + my_format = eFormatUnsigned; + else + my_format = ClangASTType::GetFormat(clang_type); } } + StreamString sstr; + if (ClangASTType::DumpTypeValue (GetClangAST(), // The clang AST + clang_type, // The clang type to display + &sstr, + my_format, // Format to display this type with + m_data, // Data to extract from + 0, // Byte offset into "m_data" + GetByteSize(), // Byte size of item in "m_data" + GetBitfieldBitSize(), // Bitfield bit size + GetBitfieldBitOffset())) // Bitfield bit offset + m_value_str.swap(sstr.GetString()); + else + { + m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)", + m_data.GetByteSize(), + GetByteSize()); + m_value_str.clear(); + } } } break; @@ -1218,7 +1384,7 @@ } addr_t -ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address) +ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type) { if (!UpdateValueIfNeeded(false)) return LLDB_INVALID_ADDRESS; @@ -1228,7 +1394,8 @@ case Value::eValueTypeScalar: if (scalar_is_load_address) { - address_type = eAddressTypeLoad; + if(address_type) + *address_type = eAddressTypeLoad; return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); } break; @@ -1237,20 +1404,23 @@ case Value::eValueTypeFileAddress: case Value::eValueTypeHostAddress: { - address_type = m_value.GetValueAddressType (); + if(address_type) + *address_type = m_value.GetValueAddressType (); return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); } break; } - address_type = eAddressTypeInvalid; + if (address_type) + *address_type = eAddressTypeInvalid; return LLDB_INVALID_ADDRESS; } addr_t -ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_address) +ValueObject::GetPointerValue (AddressType *address_type) { addr_t address = LLDB_INVALID_ADDRESS; - address_type = eAddressTypeInvalid; + if(address_type) + *address_type = eAddressTypeInvalid; if (!UpdateValueIfNeeded(false)) return address; @@ -1258,28 +1428,21 @@ switch (m_value.GetValueType()) { case Value::eValueTypeScalar: - if (scalar_is_load_address) - { - address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - address_type = eAddressTypeLoad; - } + address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); break; + case Value::eValueTypeHostAddress: case Value::eValueTypeLoadAddress: case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: { uint32_t data_offset = 0; address = m_data.GetPointer(&data_offset); - address_type = m_value.GetValueAddressType(); - if (address_type == eAddressTypeInvalid) - address_type = eAddressTypeLoad; } break; } - if (m_pointers_point_to_load_addrs) - address_type = eAddressTypeLoad; + if (address_type) + *address_type = GetAddressTypeOfChildren(); return address; } @@ -1553,7 +1716,8 @@ to-from+1, from, false, - false); + false, + eAddressTypeInvalid); // Cache the value if we got one back... if (synthetic_child) @@ -1633,7 +1797,8 @@ 0, 0, false, - false); + false, + eAddressTypeInvalid); if (synthetic_child) { AddSyntheticChild(name_const_str, synthetic_child); @@ -2950,7 +3115,7 @@ // We have a pointer or reference whose value is an address. // Make sure that address is not NULL AddressType ptr_address_type; - if (valobj->GetPointerValue (ptr_address_type, true) == 0) + if (valobj->GetPointerValue (&ptr_address_type) == 0) print_children = false; else if (is_ref && curr_depth == 0) @@ -3084,7 +3249,8 @@ ast, GetClangType(), name, - data); + data, + GetAddressOf()); } } @@ -3152,7 +3318,8 @@ child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent); + child_is_deref_of_parent, + eAddressTypeInvalid); } } @@ -3182,7 +3349,7 @@ AddressType address_type = eAddressTypeInvalid; const bool scalar_is_load_address = false; - addr_t addr = GetAddressOf (address_type, scalar_is_load_address); + addr_t addr = GetAddressOf (scalar_is_load_address, &address_type); error.Clear(); if (addr != LLDB_INVALID_ADDRESS) { @@ -3228,8 +3395,7 @@ { ValueObjectSP valobj_sp; AddressType address_type; - const bool scalar_is_load_address = true; - addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address); + addr_t ptr_value = GetPointerValue (&address_type); if (ptr_value != LLDB_INVALID_ADDRESS) { @@ -3248,8 +3414,7 @@ { ValueObjectSP valobj_sp; AddressType address_type; - const bool scalar_is_load_address = true; - addr_t ptr_value = GetPointerValue (address_type, scalar_is_load_address); + addr_t ptr_value = GetPointerValue (&address_type); if (ptr_value != LLDB_INVALID_ADDRESS) { @@ -3540,3 +3705,14 @@ m_summary_str.clear(); m_object_desc_str.clear(); } + +SymbolContextScope * +ValueObject::GetSymbolContextScope() +{ + if (m_parent) + { + if (!m_parent->IsPointerOrReferenceType()) + return m_parent->GetSymbolContextScope(); + } + return NULL; +} Modified: lldb/trunk/source/Core/ValueObjectChild.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectChild.cpp (original) +++ lldb/trunk/source/Core/ValueObjectChild.cpp Tue Sep 6 14:20:51 2011 @@ -35,7 +35,8 @@ uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool is_base_class, - bool is_deref_of_parent + bool is_deref_of_parent, + AddressType child_ptr_or_ref_addr_type ) : ValueObject (parent), m_clang_ast (clang_ast), @@ -48,6 +49,7 @@ m_is_deref_of_parent (is_deref_of_parent) { m_name = name; + SetAddressTypeOfChildren(child_ptr_or_ref_addr_type); } ValueObjectChild::~ValueObjectChild() @@ -108,10 +110,7 @@ if (ClangASTContext::IsPointerOrReferenceType (parent->GetClangType())) { - const bool scalar_is_load_address = true; - AddressType address_type; - - lldb::addr_t addr = parent->GetPointerValue (address_type, scalar_is_load_address); + lldb::addr_t addr = parent->GetPointerValue (); m_value.GetScalar() = addr; if (addr == LLDB_INVALID_ADDRESS) @@ -125,10 +124,28 @@ else { m_value.GetScalar() += m_byte_offset; - if (m_pointers_point_to_load_addrs || - value_type == Value::eValueTypeScalar || - value_type == Value::eValueTypeFileAddress) - m_value.SetValueType (Value::eValueTypeLoadAddress); + AddressType addr_type = parent->GetAddressTypeOfChildren(); + + switch (addr_type) + { + case eAddressTypeFile: + if (m_update_point.GetProcessSP().get() != NULL && m_update_point.GetProcessSP()->IsAlive() == true) + m_value.SetValueType (Value::eValueTypeLoadAddress); + else + m_value.SetValueType(Value::eValueTypeFileAddress); + break; + case eAddressTypeLoad: + m_value.SetValueType (Value::eValueTypeLoadAddress); + break; + case eAddressTypeHost: + m_value.SetValueType(Value::eValueTypeHostAddress); + break; + case eAddressTypeInvalid: + default: + // TODO: does this make sense? + m_value.SetValueType(Value::eValueTypeScalar); + break; + } } } else Modified: lldb/trunk/source/Core/ValueObjectConstResult.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResult.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectConstResult.cpp (original) +++ lldb/trunk/source/Core/ValueObjectConstResult.cpp Tue Sep 6 14:20:51 2011 @@ -9,6 +9,8 @@ #include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectChild.h" +#include "lldb/Core/ValueObjectConstResultChild.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/ValueObjectList.h" @@ -31,30 +33,34 @@ ( ExecutionContextScope *exe_scope, ByteOrder byte_order, - uint32_t addr_byte_size + uint32_t addr_byte_size, + lldb::addr_t address ) { return (new ValueObjectConstResult (exe_scope, byte_order, - addr_byte_size))->GetSP(); + addr_byte_size, + address))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult ( ExecutionContextScope *exe_scope, ByteOrder byte_order, - uint32_t addr_byte_size + uint32_t addr_byte_size, + lldb::addr_t address ) : ValueObject (exe_scope), m_clang_ast (NULL), m_type_name (), - m_byte_size (0) + m_byte_size (0), + m_impl(this, address) { SetIsConstant (); SetValueIsValid(true); m_data.SetByteOrder(byte_order); m_data.SetAddressByteSize(addr_byte_size); - m_pointers_point_to_load_addrs = true; + SetAddressTypeOfChildren(eAddressTypeLoad); } ValueObjectSP @@ -64,14 +70,16 @@ clang::ASTContext *clang_ast, void *clang_type, const ConstString &name, - const DataExtractor &data + const DataExtractor &data, + lldb::addr_t address ) { return (new ValueObjectConstResult (exe_scope, clang_ast, clang_type, name, - data))->GetSP(); + data, + address))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult @@ -80,12 +88,14 @@ clang::ASTContext *clang_ast, void *clang_type, const ConstString &name, - const DataExtractor &data + const DataExtractor &data, + lldb::addr_t address ) : ValueObject (exe_scope), m_clang_ast (clang_ast), m_type_name (), - m_byte_size (0) + m_byte_size (0), + m_impl(this, address) { m_data = data; m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); @@ -94,7 +104,7 @@ m_name = name; SetIsConstant (); SetValueIsValid(true); - m_pointers_point_to_load_addrs = true; + SetAddressTypeOfChildren(eAddressTypeLoad); } ValueObjectSP @@ -106,7 +116,8 @@ const ConstString &name, const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, - uint8_t data_addr_size + uint8_t data_addr_size, + lldb::addr_t address ) { return (new ValueObjectConstResult (exe_scope, @@ -115,7 +126,8 @@ name, data_sp, data_byte_order, - data_addr_size))->GetSP(); + data_addr_size, + address))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult @@ -126,12 +138,14 @@ const ConstString &name, const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, - uint8_t data_addr_size + uint8_t data_addr_size, + lldb::addr_t address ) : ValueObject (exe_scope), m_clang_ast (clang_ast), m_type_name (), - m_byte_size (0) + m_byte_size (0), + m_impl(this, address) { m_data.SetByteOrder(data_byte_order); m_data.SetAddressByteSize(data_addr_size); @@ -142,7 +156,7 @@ m_name = name; SetIsConstant (); SetValueIsValid(true); - m_pointers_point_to_load_addrs = true; + SetAddressTypeOfChildren(eAddressTypeLoad); } ValueObjectSP @@ -179,7 +193,8 @@ ValueObject (exe_scope), m_clang_ast (clang_ast), m_type_name (), - m_byte_size (0) + m_byte_size (0), + m_impl(this, address) { m_value.GetScalar() = address; m_data.SetAddressByteSize(addr_byte_size); @@ -197,7 +212,7 @@ m_name = name; SetIsConstant (); SetValueIsValid(true); - m_pointers_point_to_load_addrs = true; + SetAddressTypeOfChildren(eAddressTypeLoad); } ValueObjectSP @@ -217,11 +232,11 @@ ValueObject (exe_scope), m_clang_ast (NULL), m_type_name (), - m_byte_size (0) + m_byte_size (0), + m_impl(this) { m_error = error; SetIsConstant (); - m_pointers_point_to_load_addrs = true; } ValueObjectConstResult::~ValueObjectConstResult() @@ -244,10 +259,7 @@ ValueObjectConstResult::GetByteSize() { if (m_byte_size == 0) - { - uint64_t bit_width = ClangASTType::GetClangTypeBitWidth (GetClangAST(), GetClangType()); - m_byte_size = (bit_width + 7 ) / 8; - } + m_byte_size = ClangASTType::GetTypeByteSize(GetClangAST(), GetClangType()); return m_byte_size; } @@ -293,3 +305,35 @@ // information needed to contain the constant value. return true; } + +lldb::ValueObjectSP +ValueObjectConstResult::Dereference (Error &error) +{ + return m_impl.Dereference(error); +} + +lldb::ValueObjectSP +ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) +{ + return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); +} + +lldb::ValueObjectSP +ValueObjectConstResult::AddressOf (Error &error) +{ + return m_impl.AddressOf(error); +} + +ValueObject * +ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) +{ + return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index); +} + +size_t +ValueObjectConstResult::GetPointeeData (DataExtractor& data, + uint32_t item_idx, + uint32_t item_count) +{ + return m_impl.GetPointeeData(data, item_idx, item_count); +} Added: lldb/trunk/source/Core/ValueObjectConstResultChild.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResultChild.cpp?rev=139160&view=auto ============================================================================== --- lldb/trunk/source/Core/ValueObjectConstResultChild.cpp (added) +++ lldb/trunk/source/Core/ValueObjectConstResultChild.cpp Tue Sep 6 14:20:51 2011 @@ -0,0 +1,82 @@ +//===-- ValueObjectConstResultChild.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectConstResultChild.h" + +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectList.h" + +#include "lldb/Symbol/ClangASTContext.h" + +using namespace lldb_private; + +ValueObjectConstResultChild::ValueObjectConstResultChild +( + ValueObject &parent, + clang::ASTContext *clang_ast, + void *clang_type, + const ConstString &name, + uint32_t byte_size, + int32_t byte_offset, + uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, + bool is_base_class, + bool is_deref_of_parent +) : + ValueObjectChild (parent, + clang_ast, + clang_type, + name, + byte_size, + byte_offset, + bitfield_bit_size, + bitfield_bit_offset, + is_base_class, + is_deref_of_parent, + eAddressTypeLoad), + m_impl(this) +{ + m_name = name; +} + +ValueObjectConstResultChild::~ValueObjectConstResultChild() +{ +} + +lldb::ValueObjectSP +ValueObjectConstResultChild::Dereference (Error &error) +{ + return m_impl.Dereference(error); +} + +lldb::ValueObjectSP +ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) +{ + return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); +} + +lldb::ValueObjectSP +ValueObjectConstResultChild::AddressOf (Error &error) +{ + return m_impl.AddressOf(error); +} + +ValueObject * +ValueObjectConstResultChild::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) +{ + return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index); +} + +size_t +ValueObjectConstResultChild::GetPointeeData (DataExtractor& data, + uint32_t item_idx, + uint32_t item_count) +{ + return m_impl.GetPointeeData(data, item_idx, item_count); +} Added: lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp?rev=139160&view=auto ============================================================================== --- lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp (added) +++ lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp Tue Sep 6 14:20:51 2011 @@ -0,0 +1,221 @@ +//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectConstResultImpl.h" + +#include "lldb/Core/ValueObjectChild.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectConstResultChild.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ValueObjectList.h" + +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/Variable.h" + +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +// this macro enables a simpler implementation for some method calls in this object that relies only upon +// ValueObject knowning how to set the address type of its children correctly. the alternative implementation +// relies on being able to create a target copy of the frozen object, which makes it less bug-prone but less +// efficient as well. once we are confident the faster implementation is bug-free, this macro (and the slower +// implementations) can go +#define TRIVIAL_IMPL 1 + +ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj, + lldb::addr_t live_address) : + m_impl_backend(valobj), + m_live_address(live_address), + m_load_addr_backend(), + m_address_of_backend() +{ +} + +lldb::ValueObjectSP +ValueObjectConstResultImpl::DerefOnTarget() +{ + if (m_load_addr_backend.get() == NULL) + { + lldb::addr_t tgt_address = m_impl_backend->GetPointerValue(); + m_load_addr_backend = ValueObjectConstResult::Create (m_impl_backend->GetExecutionContextScope(), + m_impl_backend->GetClangAST(), + m_impl_backend->GetClangType(), + m_impl_backend->GetName(), + tgt_address, + eAddressTypeLoad, + m_impl_backend->GetUpdatePoint().GetProcessSP()->GetAddressByteSize()); + } + return m_load_addr_backend; +} + +lldb::ValueObjectSP +ValueObjectConstResultImpl::Dereference (Error &error) +{ + if (m_impl_backend == NULL) + return lldb::ValueObjectSP(); + +#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 + return m_impl_backend->ValueObject::Dereference(error); +#else + m_impl_backend->UpdateValueIfNeeded(false); + + if (NeedsDerefOnTarget()) + return DerefOnTarget()->Dereference(error); + else + return m_impl_backend->ValueObject::Dereference(error); +#endif +} + +ValueObject * +ValueObjectConstResultImpl::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) +{ + if (m_impl_backend == NULL) + return NULL; + + m_impl_backend->UpdateValueIfNeeded(false); + + ValueObjectConstResultChild *valobj = NULL; + + bool omit_empty_base_classes = true; + bool ignore_array_bounds = synthetic_array_member; + std::string child_name_str; + uint32_t child_byte_size = 0; + int32_t child_byte_offset = 0; + uint32_t child_bitfield_bit_size = 0; + uint32_t child_bitfield_bit_offset = 0; + bool child_is_base_class = false; + bool child_is_deref_of_parent = false; + + const bool transparent_pointers = synthetic_array_member == false; + clang::ASTContext *clang_ast = m_impl_backend->GetClangAST(); + lldb::clang_type_t clang_type = m_impl_backend->GetClangType(); + lldb::clang_type_t child_clang_type; + + ExecutionContext exe_ctx; + m_impl_backend->GetExecutionContextScope()->CalculateExecutionContext (exe_ctx); + + child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (&exe_ctx, + clang_ast, + m_impl_backend->GetName().GetCString(), + clang_type, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + if (child_clang_type && child_byte_size) + { + if (synthetic_index) + child_byte_offset += child_byte_size * synthetic_index; + + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString (child_name_str.c_str()); + + valobj = new ValueObjectConstResultChild (*m_impl_backend, + clang_ast, + child_clang_type, + child_name, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent); + valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset); + } + + return valobj; +} + +lldb::ValueObjectSP +ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create) +{ + if (m_impl_backend == NULL) + return lldb::ValueObjectSP(); + +#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 + return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); +#else + m_impl_backend->UpdateValueIfNeeded(false); + + if (NeedsDerefOnTarget()) + return DerefOnTarget()->GetSyntheticChildAtOffset(offset, type, can_create); + else + return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset, type, can_create); +#endif +} + +lldb::ValueObjectSP +ValueObjectConstResultImpl::AddressOf (Error &error) +{ + if (m_address_of_backend.get() != NULL) + return m_address_of_backend; + + if (m_impl_backend == NULL) + return lldb::ValueObjectSP(); + if (m_live_address != LLDB_INVALID_ADDRESS) + { + ClangASTType type(m_impl_backend->GetClangAST(), m_impl_backend->GetClangType()); + + lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t))); + + std::string new_name("&"); + new_name.append(m_impl_backend->GetName().AsCString("")); + + m_address_of_backend = ValueObjectConstResult::Create(m_impl_backend->GetUpdatePoint().GetExecutionContextScope(), + type.GetASTContext(), + type.GetPointerType(), + ConstString(new_name.c_str()), + buffer, + lldb::endian::InlHostByteOrder(), + m_impl_backend->GetExecutionContextScope()->CalculateProcess()->GetAddressByteSize()); + + m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); + m_address_of_backend->GetValue().GetScalar() = m_live_address; + + return m_address_of_backend; + } + else + return lldb::ValueObjectSP(); +} + +size_t +ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data, + uint32_t item_idx, + uint32_t item_count) +{ + if (m_impl_backend == NULL) + return 0; +#if defined (TRIVIAL_IMPL) && TRIVIAL_IMPL == 1 + return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); +#else + m_impl_backend->UpdateValueIfNeeded(false); + + if (NeedsDerefOnTarget() && m_impl_backend->IsPointerType()) + return DerefOnTarget()->GetPointeeData(data, item_idx, item_count); + else + return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count); +#endif +} Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObjectVariable.cpp (original) +++ lldb/trunk/source/Core/ValueObjectVariable.cpp Tue Sep 6 14:20:51 2011 @@ -145,6 +145,23 @@ m_value.SetContext(Value::eContextTypeVariable, variable); Value::ValueType value_type = m_value.GetValueType(); + + switch (value_type) + { + case Value::eValueTypeFileAddress: + SetAddressTypeOfChildren(eAddressTypeFile); + break; + case Value::eValueTypeHostAddress: + SetAddressTypeOfChildren(eAddressTypeHost); + break; + case Value::eValueTypeLoadAddress: + SetAddressTypeOfChildren(eAddressTypeLoad); + break; + case Value::eValueTypeScalar: + // TODO: is this the right thing to do? + SetAddressTypeOfChildren(eAddressTypeInvalid); + break; + } switch (value_type) { @@ -250,4 +267,10 @@ return NULL; } - +SymbolContextScope * +ValueObjectVariable::GetSymbolContextScope() +{ + if (m_variable_sp) + return m_variable_sp->GetSymbolContextScope(); + return NULL; +} Modified: lldb/trunk/source/Interpreter/CommandObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandObject.cpp (original) +++ lldb/trunk/source/Interpreter/CommandObject.cpp Tue Sep 6 14:20:51 2011 @@ -697,8 +697,8 @@ "A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n" "The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type" " (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be" - " ${var.x.y}). In expression paths you can use either . or -> without any difference in meaning. You can also use ${*var followed by an expression path and in that case" - " the object referred by the path will be dereferenced before being displayed. If the object is not a pointer, doing so will cause an error.\n" + " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed." + " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n" "By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed." "In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression" " path refers to:\n" @@ -706,7 +706,41 @@ " and displayed as an individual variable\n" " - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are" " printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n" - "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1."; + "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.\n" + "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the" + " special symbols only allowed as part of a variable:\n" + " %V: show the value of the object by default\n" + " %S: show the summary of the object by default\n" + " %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n" + " %L: show the location of the object (memory address or a register name)\n" + " %#: show the number of children of the object\n" + " %T: show the type of the object\n" + "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses" + " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would" + " count the number of actual elements stored in an std::list:\n" + "type summary add -s \"${svar%#}\" -x \"std::list<\""; +} + +static const char * +ExprPathHelpTextCallback() +{ + return + "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n" + "For instance, given a class:\n" + " class foo {\n" + " int a;\n" + " int b; .\n" + " foo* next;\n" + " };\n" + "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n" + "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n" + "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n" + "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n" + "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n" + "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract" + " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index" + " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the" + " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory)."; } const char * @@ -742,6 +776,7 @@ { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." }, { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." }, { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." }, + { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL }, { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { NULL, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" }, { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { NULL, false }, "The name of a file (can include path)." }, { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, NULL }, @@ -764,6 +799,9 @@ { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." }, { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." }, { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the process." }, + { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python class." }, + { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python function." }, + { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { NULL, false }, "Source code written in Python." }, { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." }, { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { NULL, false }, "A register name." }, { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." }, Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Sep 6 14:20:51 2011 @@ -18,9 +18,7 @@ #include -#include "lldb/API/SBFrame.h" -#include "lldb/API/SBBreakpointLocation.h" -#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBValue.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Timer.h" @@ -90,6 +88,36 @@ PythonMutexPredicate().SetValue (LLDB_INVALID_THREAD_ID, eBroadcastAlways); } +ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *pi, + FILE* tmp_fh, + bool ns) : + m_need_session(ns), + m_release_lock(false), + m_python_interpreter(pi), + m_tmp_fh(tmp_fh) +{ + // if Enter/LeaveSession() must be called, then m_python_interpreter must be != NULL + assert(m_need_session && m_python_interpreter); + if (!CurrentThreadHasPythonLock()) + { + while (!GetPythonLock (1)) + if (tmp_fh) + fprintf (tmp_fh, + "Python interpreter locked on another thread; waiting to acquire lock...\n"); + m_release_lock = true; + } + if (m_need_session) + m_python_interpreter->EnterSession (); +} + +ScriptInterpreterPython::Locker::~Locker() +{ + if (m_need_session) + m_python_interpreter->LeaveSession (); + if (m_release_lock) + ReleasePythonLock (); +} + ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) : ScriptInterpreter (interpreter, eScriptLanguagePython), m_embedded_python_pty (), @@ -226,21 +254,10 @@ m_dbg_stdout = fh; FILE *tmp_fh = (m_dbg_stdout ? m_dbg_stdout : stdout); - if (!CurrentThreadHasPythonLock ()) - { - while (!GetPythonLock (1)) - fprintf (tmp_fh, "Python interpreter locked on another thread; waiting to acquire lock...\n"); - EnterSession (); - m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush); - LeaveSession (); - ReleasePythonLock (); - } - else - { - EnterSession (); - m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush); - LeaveSession (); - } + + Locker py_lock(this, tmp_fh); + + m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush); } void @@ -1400,25 +1417,12 @@ void* ret_val; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) + { - python_interpreter->EnterSession (); + Locker py_lock(this, tmp_fh); ret_val = g_swig_synthetic_script (class_name, python_interpreter->m_dictionary_name.c_str(), valobj); - python_interpreter->LeaveSession (); - } - else - { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); - ret_val = g_swig_synthetic_script (class_name, - python_interpreter->m_dictionary_name.c_str(), - valobj); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } return ret_val; @@ -1526,25 +1530,12 @@ && *python_function_name) { FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) + { - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); ret_val = g_swig_typescript_callback (python_function_name, python_interpreter->m_dictionary_name.c_str(), valobj); - python_interpreter->LeaveSession (); - } - else - { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); - ret_val = g_swig_typescript_callback (python_function_name, - python_interpreter->m_dictionary_name.c_str(), - valobj); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } } else @@ -1595,27 +1586,13 @@ { bool ret_val = true; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - ret_val = g_swig_breakpoint_callback (python_function_name, - python_interpreter->m_dictionary_name.c_str(), - stop_frame_sp, - bp_loc_sp); - python_interpreter->LeaveSession (); - } - else + { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); ret_val = g_swig_breakpoint_callback (python_function_name, python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, bp_loc_sp); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } return ret_val; } @@ -1758,55 +1735,47 @@ uint32_t ret_val = 0; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - ret_val = g_swig_calc_children (implementor); - python_interpreter->LeaveSession (); - } - else + { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); ret_val = g_swig_calc_children (implementor); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } return ret_val; } -void* +lldb::ValueObjectSP ScriptInterpreterPython::GetChildAtIndex (void *implementor, uint32_t idx) { if (!implementor) - return 0; + return lldb::ValueObjectSP(); - if (!g_swig_get_child_index) - return 0; + if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue) + return lldb::ValueObjectSP(); ScriptInterpreterPython *python_interpreter = this; - void* ret_val = NULL; + void* child_ptr = NULL; + lldb::SBValue* value_sb = NULL; + lldb::ValueObjectSP ret_val; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - ret_val = g_swig_get_child_index (implementor,idx); - python_interpreter->LeaveSession (); - } - else + { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); - ret_val = g_swig_get_child_index (implementor,idx); - python_interpreter->LeaveSession (); - ReleasePythonLock (); + Locker py_lock(python_interpreter, tmp_fh); + child_ptr = g_swig_get_child_index (implementor,idx); + if (child_ptr != NULL && child_ptr != Py_None) + { + value_sb = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr); + if (value_sb == NULL) + Py_XDECREF(child_ptr); + else + ret_val = value_sb->get_sp(); + } + else + { + Py_XDECREF(child_ptr); + } } return ret_val; @@ -1826,21 +1795,10 @@ int ret_val = UINT32_MAX; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) + { - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); ret_val = g_swig_get_index_child (implementor, child_name); - python_interpreter->LeaveSession (); - } - else - { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); - ret_val = g_swig_get_index_child (implementor, child_name); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } return ret_val; @@ -1858,60 +1816,15 @@ ScriptInterpreterPython *python_interpreter = this; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - g_swig_update_provider (implementor); - python_interpreter->LeaveSession (); - } - else + { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); g_swig_update_provider (implementor); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } return; } -lldb::SBValue* -ScriptInterpreterPython::CastPyObjectToSBValue (void* data) -{ - if (!data) - return NULL; - - if (!g_swig_cast_to_sbvalue) - return NULL; - - ScriptInterpreterPython *python_interpreter = this; - - lldb::SBValue* ret_val = NULL; - - FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - ret_val = g_swig_cast_to_sbvalue (data); - python_interpreter->LeaveSession (); - } - else - { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); - ret_val = g_swig_cast_to_sbvalue (data); - python_interpreter->LeaveSession (); - ReleasePythonLock (); - } - - return ret_val; -} - bool ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function, const char* args, @@ -1939,31 +1852,15 @@ std::string err_msg; FILE *tmp_fh = (python_interpreter->m_dbg_stdout ? python_interpreter->m_dbg_stdout : stdout); - if (CurrentThreadHasPythonLock()) - { - python_interpreter->EnterSession (); - ret_val = g_swig_call_command (impl_function, - python_interpreter->m_dictionary_name.c_str(), - debugger_sp, - args, - err_msg, - cmd_retobj); - python_interpreter->LeaveSession (); - } - else + { - while (!GetPythonLock (1)) - fprintf (tmp_fh, - "Python interpreter locked on another thread; waiting to acquire lock...\n"); - python_interpreter->EnterSession (); + Locker py_lock(python_interpreter, tmp_fh); ret_val = g_swig_call_command (impl_function, python_interpreter->m_dictionary_name.c_str(), debugger_sp, args, err_msg, cmd_retobj); - python_interpreter->LeaveSession (); - ReleasePythonLock (); } if (!ret_val) Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Tue Sep 6 14:20:51 2011 @@ -62,7 +62,7 @@ // First job, pull out the address at 0 offset from the object. AddressType address_type; - lldb::addr_t original_ptr = in_value.GetPointerValue(address_type, true); + lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); if (original_ptr == LLDB_INVALID_ADDRESS) return false; Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Tue Sep 6 14:20:51 2011 @@ -49,17 +49,11 @@ return NULL; // Make the argument list: we pass one arg, the address of our pointer, to the print function. - Scalar scalar; + Value val; - if (!ClangASTType::GetValueAsScalar (object.GetClangAST(), - object.GetClangType(), - object.GetDataExtractor(), - 0, - object.GetByteSize(), - scalar)) + if (!object.ResolveValue(val.GetScalar())) return NULL; - Value val(scalar); return GetObjectDescription(str, val, object.GetExecutionContextScope()); } Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original) +++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Sep 6 14:20:51 2011 @@ -245,7 +245,7 @@ { // First job, pull out the address at 0 offset from the object That will be the ISA pointer. AddressType address_type; - lldb::addr_t original_ptr = in_value.GetPointerValue(address_type, true); + lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); // ObjC only has single inheritance, so the objects all start at the same pointer value. address.SetSection (NULL); @@ -584,26 +584,6 @@ lldb_private::ObjCLanguageRuntime::ObjCISA AppleObjCRuntimeV2::GetISA(ValueObject& valobj) { - - if (valobj.GetIsExpressionResult() && - valobj.GetValue().GetValueType() == Value::eValueTypeHostAddress) - { - // when using the expression parser, an additional layer of "frozen data" - // can be created, which is basically a byte-exact copy of the data returned - // by the expression, but in host memory. because this code reads memory without - // taking the debug-info-provided object layout, we need to hand it the target version - // of the expression output - lldb::addr_t tgt_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - ValueObjectSP target_object = ValueObjectConstResult::Create (valobj.GetExecutionContextScope(), - valobj.GetClangAST(), - valobj.GetClangType(), - valobj.GetName(), - tgt_address, - eAddressTypeLoad, - valobj.GetUpdatePoint().GetProcessSP()->GetAddressByteSize()); - return GetISA(*target_object); - } - if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != lldb::eLanguageTypeObjC) return 0; @@ -613,8 +593,7 @@ if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid) return 0; - uint32_t offset = 0; - uint64_t isa_pointer = valobj.GetDataExtractor().GetPointer(&offset); + lldb::addr_t isa_pointer = valobj.GetPointerValue(); // tagged pointer if (IsTaggedPointer(isa_pointer)) Modified: lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp (original) +++ lldb/trunk/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp Tue Sep 6 14:20:51 2011 @@ -156,9 +156,9 @@ ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create)); if (gpr_valobj_sp->IsPointerType ()) - base_addr = gpr_valobj_sp->GetPointerValue (addr_type, true); + base_addr = gpr_valobj_sp->GetPointerValue (&addr_type); else - base_addr = gpr_valobj_sp->GetAddressOf (addr_type, true); + base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type); ValueObjectSP child_valobj_sp; if (gpr_valobj_sp) @@ -188,7 +188,7 @@ { // Adjust the byte size and the offset to match the layout of registers in our struct reg_info.byte_size = child_valobj_sp->GetByteSize(); - reg_info.byte_offset = child_valobj_sp->GetAddressOf(addr_type, true) - base_addr; + reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr; reg_info.kinds[eRegisterKindLLDB] = reg_num++; m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name); } @@ -290,9 +290,9 @@ if (gpr_valobj_sp) { if (gpr_valobj_sp->IsPointerType ()) - base_addr = gpr_valobj_sp->GetPointerValue (addr_type, true); + base_addr = gpr_valobj_sp->GetPointerValue (&addr_type); else - base_addr = gpr_valobj_sp->GetAddressOf (addr_type, true); + base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type); reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr)); } } Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Tue Sep 6 14:20:51 2011 @@ -154,6 +154,53 @@ return NULL; } +lldb::clang_type_t +ClangASTType::GetArrayElementType (uint32_t& stride) +{ + return GetArrayElementType(m_ast, m_type, stride); +} + +lldb::clang_type_t +ClangASTType::GetArrayElementType (clang::ASTContext* ast, + lldb::clang_type_t opaque_clang_qual_type, + uint32_t& stride) +{ + if (opaque_clang_qual_type) + { + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + + lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr(); + + // TODO: the real stride will be >= this value.. find the real one! + stride = GetTypeByteSize(ast, ret_type); + + return ret_type; + + } + return NULL; + +} + +lldb::clang_type_t +ClangASTType::GetPointerType () +{ + return GetPointerType (m_ast, + m_type); +} + +lldb::clang_type_t +ClangASTType::GetPointerType (clang::ASTContext *ast_context, + lldb::clang_type_t opaque_clang_qual_type) +{ + if (opaque_clang_qual_type) + { + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type)); + + return ast_context->getPointerType(qual_type).getAsOpaquePtr(); + } + return NULL; +} + lldb::Encoding ClangASTType::GetEncoding (uint32_t &count) { Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Tue Sep 6 14:20:51 2011 @@ -623,10 +623,20 @@ } size_t -Target::ReadMemory (const Address& addr, bool prefer_file_cache, void *dst, size_t dst_len, Error &error) +Target::ReadMemory (const Address& addr, + bool prefer_file_cache, + void *dst, + size_t dst_len, + Error &error, + lldb::addr_t *load_addr_ptr) { error.Clear(); + // if we end up reading this from process memory, we will fill this + // with the actual load address + if (load_addr_ptr) + *load_addr_ptr = LLDB_INVALID_ADDRESS; + bool process_is_valid = m_process_sp && m_process_sp->IsAlive(); size_t bytes_read = 0; @@ -692,7 +702,11 @@ } } if (bytes_read) + { + if (load_addr_ptr) + *load_addr_ptr = load_addr; return bytes_read; + } // If the address is not section offset we have an address that // doesn't resolve to any address in any currently loaded shared // libaries and we failed to read memory so there isn't anything @@ -1579,6 +1593,7 @@ #define TSC_SKIP_PROLOGUE "skip-prologue" #define TSC_SOURCE_MAP "source-map" #define TSC_MAX_CHILDREN "max-children-count" +#define TSC_MAX_STRLENSUMMARY "max-string-summary-length" static const ConstString & @@ -1623,6 +1638,12 @@ return g_const_string; } +static const ConstString & +GetSettingNameForMaxStringSummaryLength () +{ + static ConstString g_const_string (TSC_MAX_STRLENSUMMARY); + return g_const_string; +} bool Target::SettingsController::SetGlobalVariable (const ConstString &var_name, @@ -1676,7 +1697,8 @@ m_prefer_dynamic_value (2), m_skip_prologue (true, true), m_source_map (NULL, NULL), - m_max_children_display(256) + m_max_children_display(256), + m_max_strlen_length(1024) { // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers. @@ -1703,7 +1725,8 @@ m_prefer_dynamic_value (rhs.m_prefer_dynamic_value), m_skip_prologue (rhs.m_skip_prologue), m_source_map (rhs.m_source_map), - m_max_children_display(rhs.m_max_children_display) + m_max_children_display(rhs.m_max_children_display), + m_max_strlen_length(rhs.m_max_strlen_length) { if (m_instance_name != InstanceSettings::GetDefaultName()) { @@ -1787,6 +1810,13 @@ if (ok) m_max_children_display = new_value; } + else if (var_name == GetSettingNameForMaxStringSummaryLength()) + { + bool ok; + uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok); + if (ok) + m_max_strlen_length = new_value; + } else if (var_name == GetSettingNameForSourcePathMap ()) { switch (op) @@ -1858,6 +1888,7 @@ m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value; m_skip_prologue = new_settings_ptr->m_skip_prologue; m_max_children_display = new_settings_ptr->m_max_children_display; + m_max_strlen_length = new_settings_ptr->m_max_strlen_length; } bool @@ -1893,6 +1924,12 @@ count_str.Printf ("%d", m_max_children_display); value.AppendString (count_str.GetData()); } + else if (var_name == GetSettingNameForMaxStringSummaryLength()) + { + StreamString count_str; + count_str.Printf ("%d", m_max_strlen_length); + value.AppendString (count_str.GetData()); + } else { if (err) @@ -1940,12 +1977,13 @@ SettingEntry Target::SettingsController::instance_settings_table[] = { - // var-name var-type default enum init'd hidden help-text - // ================= ================== =============== ======================= ====== ====== ========================================================================= - { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, - { TSC_PREFER_DYNAMIC, eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." }, - { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, - { TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, - { TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." }, - { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } + // var-name var-type default enum init'd hidden help-text + // ================= ================== =============== ======================= ====== ====== ========================================================================= + { TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." }, + { TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." }, + { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, + { TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, + { TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." }, + { TSC_MAX_STRLENSUMMARY , eSetVarTypeInt , "1024" , NULL, true, false, "Maximum number of characters to show when using %s in summary strings." }, + { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } }; Added: lldb/trunk/test/expression_command/formatters/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/formatters/Makefile?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/expression_command/formatters/Makefile (added) +++ lldb/trunk/test/expression_command/formatters/Makefile Tue Sep 6 14:20:51 2011 @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/expression_command/formatters/TestFormatters.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/formatters/TestFormatters.py?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/expression_command/formatters/TestFormatters.py (added) +++ lldb/trunk/test/expression_command/formatters/TestFormatters.py Tue Sep 6 14:20:51 2011 @@ -0,0 +1,175 @@ +""" +Test using LLDB data formatters with frozen objects coming from the expression parser. +""" + +import unittest2 +import lldb +import lldbutil +from lldbtest import * + +class ExprFormattersTestCase(TestBase): + + mydir = os.path.join("expression_command", "formatters") + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.cpp', + '// Stop here') + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_with_dsym(self): + """Test expr + formatters for good interoperability.""" + self.buildDsym() + self.do_my_test() + + def test_with_dwarf_(self): + """Test expr + formatters for good interoperability.""" + self.buildDsym() + self.do_my_test() + + def do_my_test(self): + + # This is the function to remove the custom formats in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type summary clear', check=False) + self.runCmd('type synthetic clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + """Test expr + formatters for good interoperability.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.cpp -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + self.runCmd("script import formatters") + self.runCmd("script import foosynth") + + self.runCmd("frame variable foo1 -T") + self.runCmd("frame variable foo1.b -T") + self.runCmd("frame variable foo1.b.b_ref -T") + + self.expect("p *(new foo(47))", + substrs = ['(int) a = 47', '(bar) b = {', '(int) i = 94', '(baz) b = {', '(int) k = 99']) + + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("p new int(12)", + substrs = ['(int *) $', ' = 0x']) + + self.runCmd("type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\"") + + self.expect("p new int(12)", + substrs = ['(int *) $', '= 0x', ' -> 12']) + + self.expect("p foo1.a_ptr", + substrs = ['(int *) $', '= 0x', ' -> 13']) + + self.expect("p foo1", + substrs = ['(foo) $', ' = a = 12, a_ptr = ', ' -> 13, i = 24, i_ptr = ', ' -> 25']) + + self.expect("p new foo(47)", + substrs = ['(foo *) $', ' a = 47, a_ptr = ', ' -> 48, i = 94, i_ptr = ', ' -> 95']) + + self.expect("p foo2", + substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243']) + + object_name = self.res.GetOutput() + object_name = object_name[7:] + object_name = object_name[0:object_name.find(' =')] + + self.expect("frame variable foo2", + substrs = ['(foo)', 'foo2', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243']) + + self.expect("p $" + object_name, + substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243', ', h = 245 , k = 247']) + + self.runCmd("type summary delete foo") + self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo") + + self.expect("p $" + object_name, + substrs = ['(foo) $', ' = {', '(int) *i_ptr = 243']) + + self.runCmd("n") + self.runCmd("n") + + self.runCmd("type synthetic delete foo") + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("p foo2", + substrs = ['(foo) $', ' = a = 7777, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888']) + + self.expect("p $" + object_name + '.a', + substrs = ['7777']) + + self.expect("p *$" + object_name + '.b.i_ptr', + substrs = ['8888']) + + self.expect("p $" + object_name, + substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888', 'h = 245 , k = 247']) + + self.runCmd("type summary delete foo") + self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo") + + self.expect("p $" + object_name, + substrs = ['(foo) $', ' = {', '(int) *i_ptr = 8888']) + + self.runCmd("n") + + self.runCmd("type synthetic delete foo") + self.runCmd("type summary add -F formatters.foo_SummaryProvider foo") + + self.expect("p $" + object_name, + substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888', 'h = 9999 , k = 247']) + + process = self.dbg.GetSelectedTarget().GetProcess() + thread = process.GetThreadAtIndex(0) + frame = thread.GetSelectedFrame() + + frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr") + + a_data = frozen.GetPointeeData() + + error = lldb.SBError() + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 122, '*a_ptr = 122') + + self.runCmd("n");self.runCmd("n");self.runCmd("n"); + + self.expect("frame variable numbers", + substrs = ['1','2','3','4','5']) + + self.expect("p numbers", + substrs = ['1','2','3','4','5']) + + frozen = frame.EvaluateExpression("&numbers") + + a_data = frozen.GetPointeeData(0, 1) + + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1') + self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2') + self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3') + self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4') + self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5') + + frozen = frame.EvaluateExpression("numbers") + + a_data = frozen.GetData() + + self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1') + self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2') + self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3') + self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4') + self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5') + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/expression_command/formatters/foosynth.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/formatters/foosynth.py?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/expression_command/formatters/foosynth.py (added) +++ lldb/trunk/test/expression_command/formatters/foosynth.py Tue Sep 6 14:20:51 2011 @@ -0,0 +1,29 @@ +import lldb + +class FooSyntheticProvider: + def __init__(self,valobj,dict): + self.valobj = valobj; + self.update(); + + def update(self): + self.adjust_for_architecture() + + def num_children(self): + return 1; + + def get_child_at_index(self,index): + if index != 0: + return None; + return self.i_ptr.Dereference(); + + def get_child_index(self,name): + if name == "*i_ptr": + return 0; + return None; + + def adjust_for_architecture(self): + self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + self.bar = self.valobj.GetChildMemberWithName('b'); + self.i_ptr = self.bar.GetChildMemberWithName('i_ptr'); \ No newline at end of file Added: lldb/trunk/test/expression_command/formatters/formatters.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/formatters/formatters.py?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/expression_command/formatters/formatters.py (added) +++ lldb/trunk/test/expression_command/formatters/formatters.py Tue Sep 6 14:20:51 2011 @@ -0,0 +1,17 @@ +def foo_SummaryProvider (valobj,dict): + a = valobj.GetChildMemberWithName('a'); + a_ptr = valobj.GetChildMemberWithName('a_ptr'); + bar = valobj.GetChildMemberWithName('b'); + i = bar.GetChildMemberWithName('i'); + i_ptr = bar.GetChildMemberWithName('i_ptr'); + b_ref = bar.GetChildMemberWithName('b_ref'); + b_ref_ptr = b_ref.AddressOf() + b_ref = b_ref_ptr.Dereference() + h = b_ref.GetChildMemberWithName('h'); + k = b_ref.GetChildMemberWithName('k'); + return 'a = ' + str(a.GetValueAsUnsigned(0)) + ', a_ptr = ' + \ + str(a_ptr.GetValueAsUnsigned(0)) + ' -> ' + str(a_ptr.Dereference().GetValueAsUnsigned(0)) + \ + ', i = ' + str(i.GetValueAsUnsigned(0)) + \ + ', i_ptr = ' + str(i_ptr.GetValueAsUnsigned(0)) + ' -> ' + str(i_ptr.Dereference().GetValueAsUnsigned(0)) + \ + ', b_ref = ' + str(b_ref.GetValueAsUnsigned(0)) + \ + ', h = ' + str(h.GetValueAsUnsigned(0)) + ' , k = ' + str(k.GetValueAsUnsigned(0)) \ No newline at end of file Added: lldb/trunk/test/expression_command/formatters/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/formatters/main.cpp?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/expression_command/formatters/main.cpp (added) +++ lldb/trunk/test/expression_command/formatters/main.cpp Tue Sep 6 14:20:51 2011 @@ -0,0 +1,48 @@ +#include +#include + +struct baz + { + int h; + int k; + baz(int a, int b) : h(a), k(b) {} + }; + +struct bar + { + int i; + int* i_ptr; + baz b; + baz& b_ref; + bar(int x) : i(x),i_ptr(new int(x+1)),b(i+3,i+5),b_ref(b) {} + }; + +struct foo + { + int a; + int* a_ptr; + bar b; + + foo(int x) : a(x), + a_ptr(new int(x+1)), + b(2*x) {} + + }; + +int main(int argc, char** argv) +{ + foo foo1(12); + foo foo2(121); + + foo2.a = 7777; // Stop here + *(foo2.b.i_ptr) = 8888; + foo2.b.b.h = 9999; + + *(foo1.a_ptr) = 9999; + foo1.b.i = 9999; + + int numbers[5] = {1,2,3,4,5}; + + return 0; + +} \ No newline at end of file Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py (original) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py Tue Sep 6 14:20:51 2011 @@ -110,10 +110,20 @@ self.expect("frame variable strarr", substrs = ['arr = "Hello world!']) - + + # check that rdar://problem/10011145 (Standard summary format for char[] doesn't work as the result of "expr".) is solved + self.expect("p strarr", + substrs = ['arr = "Hello world!']) + self.expect("frame variable strptr", substrs = ['ptr = "Hello world!"']) + self.expect("p strptr", + substrs = ['ptr = "Hello world!"']) + + self.expect("p (char*)\"1234567890123456789012345678901234567890123456789012345678901234ABC\"", + substrs = ['(char *) $', ' = ptr = ', ' "1234567890123456789012345678901234567890123456789012345678901234ABC"']) + self.runCmd("type summary add -c Point") self.expect("frame variable iAmSomewhere", Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (original) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Tue Sep 6 14:20:51 2011 @@ -250,6 +250,15 @@ '[2] = 123', '[3] = 1234', '}']) + + self.expect("p numbers", + substrs = ['$', '= {', + '[0] = 1', + '[1] = 12', + '[2] = 123', + '[3] = 1234', + '}']) + # check access to synthetic children self.runCmd("type summary add --summary-string \"item 0 is ${var[0]}\" std::int_vect int_vect") @@ -278,7 +287,18 @@ '[5] = 123456', '[6] = 1234567', '}']) - + + self.expect("p numbers", + substrs = ['$', ' = {', + '[0] = 1', + '[1] = 12', + '[2] = 123', + '[3] = 1234', + '[4] = 12345', + '[5] = 123456', + '[6] = 1234567', + '}']) + # check access-by-index self.expect("frame variable numbers[0]", substrs = ['1']); @@ -320,6 +340,11 @@ 'is', 'smart']) + self.expect("p strings", + substrs = ['goofy', + 'is', + 'smart']) + # test summaries based on synthetic children self.runCmd("type summary add std::string_vect string_vect --summary-string \"vector has ${svar%#} items\" -e") self.expect("frame variable strings", @@ -328,6 +353,12 @@ 'is', 'smart']) + self.expect("p strings", + substrs = ['vector has 3 items', + 'goofy', + 'is', + 'smart']) + self.runCmd("n"); self.expect("frame variable strings", @@ -360,12 +391,20 @@ self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e") self.runCmd("type format add -f hex int") + self.expect("frame variable numbers_list --raw", matching=False, + substrs = ['list has 0 items', + '{}']) + self.expect("frame variable numbers_list", substrs = ['list has 0 items', '{}']) + self.expect("p numbers_list", + substrs = ['list has 0 items', + '{}']) + self.runCmd("n") - + self.expect("frame variable numbers_list", substrs = ['list has 1 items', '[0] = ', @@ -397,7 +436,19 @@ '0x0abcdef0', '[5] =', '0x0cab0cab']) - + + self.expect("p numbers_list", + substrs = ['list has 6 items', + '[0] = ', + '0x12345678', + '0x11223344', + '0xbeeffeed', + '0x00abba00', + '[4] =', + '0x0abcdef0', + '[5] =', + '0x0cab0cab']) + # check access-by-index self.expect("frame variable numbers_list[0]", substrs = ['0x12345678']); @@ -414,7 +465,6 @@ substrs = ['list has 0 items', '{}']) - self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n"); self.expect("frame variable numbers_list", @@ -435,16 +485,13 @@ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n"); self.expect("frame variable text_list", - substrs = ['list has 4 items', - '[0]', 'goofy', - '[1]', 'is', - '[2]', 'smart', - '[3]', '!!!']) - - # let's prettify string display - self.runCmd("type summary add --summary-string \"${var._M_dataplus._M_p}\" std::string std::basic_string \"std::basic_string,std::allocator >\"") + substrs = ['list has 4 items', + '[0]', 'goofy', + '[1]', 'is', + '[2]', 'smart', + '[3]', '!!!']) - self.expect("frame variable text_list", + self.expect("p text_list", substrs = ['list has 4 items', '[0] = \"goofy\"', '[1] = \"is\"', @@ -505,7 +552,7 @@ self.runCmd("n");self.runCmd("n"); self.runCmd("n");self.runCmd("n");self.runCmd("n"); - self.expect('frame variable ii', + self.expect("frame variable ii", substrs = ['map has 9 items', '[5] = {', 'first = 5', @@ -514,6 +561,15 @@ 'first = 7', 'second = 1']) + self.expect("p ii", + substrs = ['map has 9 items', + '[5] = {', + 'first = 5', + 'second = 0', + '[7] = {', + 'first = 7', + 'second = 1']) + # check access-by-index self.expect("frame variable ii[0]", substrs = ['first = 0', @@ -552,7 +608,7 @@ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n"); - self.expect('frame variable si', + self.expect("frame variable si", substrs = ['map has 5 items', '[0] = ', 'first = \"zero\"', @@ -569,7 +625,25 @@ '[4] = ', 'first = \"four\"', 'second = 4']) - + + self.expect("p si", + substrs = ['map has 5 items', + '[0] = ', + 'first = \"zero\"', + 'second = 0', + '[1] = ', + 'first = \"one\"', + 'second = 1', + '[2] = ', + 'first = \"two\"', + 'second = 2', + '[3] = ', + 'first = \"three\"', + 'second = 3', + '[4] = ', + 'first = \"four\"', + 'second = 4']) + # check access-by-index self.expect("frame variable si[0]", substrs = ['first = ', 'four', @@ -597,7 +671,7 @@ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n"); - self.expect('frame variable is', + self.expect("frame variable is", substrs = ['map has 4 items', '[0] = ', 'second = \"goofy\"', @@ -612,6 +686,21 @@ 'second = \"!!!\"', 'first = 3']) + self.expect("p is", + substrs = ['map has 4 items', + '[0] = ', + 'second = \"goofy\"', + 'first = 0', + '[1] = ', + 'second = \"is\"', + 'first = 1', + '[2] = ', + 'second = \"smart\"', + 'first = 2', + '[3] = ', + 'second = \"!!!\"', + 'first = 3']) + # check access-by-index self.expect("frame variable is[0]", substrs = ['first = ', '0', @@ -639,7 +728,7 @@ self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n"); - self.expect('frame variable ss', + self.expect("frame variable ss", substrs = ['map has 4 items', '[0] = ', 'second = \"hello\"', @@ -654,6 +743,21 @@ 'second = \"..is always a Mac!\"', 'first = \"a Mac..\"']) + self.expect("p ss", + substrs = ['map has 4 items', + '[0] = ', + 'second = \"hello\"', + 'first = \"ciao\"', + '[1] = ', + 'second = \"house\"', + 'first = \"casa\"', + '[2] = ', + 'second = \"cat\"', + 'first = \"gatto\"', + '[3] = ', + 'second = \"..is always a Mac!\"', + 'first = \"a Mac..\"']) + # check access-by-index self.expect("frame variable ss[3]", substrs = ['gatto', 'cat']); Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py (original) +++ lldb/trunk/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py Tue Sep 6 14:20:51 2011 @@ -79,6 +79,14 @@ substrs = ['arr = \"', 'Nested Hello world!']) + self.expect("p strarr", + substrs = ['arr = \"', + 'Hello world!']) + + self.expect("p other.strarr", + substrs = ['arr = \"', + 'Nested Hello world!']) + # ${var%c} self.runCmd("type summary add --summary-string \"ptr = ${var%c}\" \"char *\"") @@ -90,6 +98,14 @@ substrs = ['ptr = \"', 'Nested Hello world!']) + self.expect("p strptr", + substrs = ['ptr = \"', + 'Hello world!']) + + self.expect("p other.strptr", + substrs = ['ptr = \"', + 'Nested Hello world!']) + self.runCmd("type summary add --summary-string \"arr = ${var%c}\" -x \"char \\[[0-9]+\\]\"") self.expect("frame variable strarr", @@ -100,6 +116,14 @@ substrs = ['arr = \"', 'Nested Hello world!']) + self.expect("p strarr", + substrs = ['arr = \"', + 'Hello world!']) + + self.expect("p other.strarr", + substrs = ['arr = \"', + 'Nested Hello world!']) + # ${var%char[]} self.runCmd("type summary add --summary-string \"arr = ${var%char[]}\" -x \"char \\[[0-9]+\\]\"") @@ -111,6 +135,14 @@ substrs = ['arr = ', 'Nested Hello world!']) + self.expect("p strarr", + substrs = ['arr = \"', + 'Hello world!']) + + self.expect("p other.strarr", + substrs = ['arr = ', + 'Nested Hello world!']) + self.runCmd("type summary add --summary-string \"ptr = ${var%char[]}\" \"char *\"") self.expect("frame variable strptr", @@ -121,6 +153,14 @@ substrs = ['ptr = \"', 'Nested Hello world!']) + self.expect("p strptr", + substrs = ['ptr = \"', + 'Hello world!']) + + self.expect("p other.strptr", + substrs = ['ptr = \"', + 'Nested Hello world!']) + # ${var%a} self.runCmd("type summary add --summary-string \"arr = ${var%a}\" -x \"char \\[[0-9]+\\]\"") @@ -132,6 +172,14 @@ substrs = ['arr = ', 'Nested Hello world!']) + self.expect("p strarr", + substrs = ['arr = \"', + 'Hello world!']) + + self.expect("p other.strarr", + substrs = ['arr = ', + 'Nested Hello world!']) + self.runCmd("type summary add --summary-string \"ptr = ${var%a}\" \"char *\"") self.expect("frame variable strptr", @@ -142,6 +190,14 @@ substrs = ['ptr = \"', 'Nested Hello world!']) + self.expect("p strptr", + substrs = ['ptr = \"', + 'Hello world!']) + + self.expect("p other.strptr", + substrs = ['ptr = \"', + 'Nested Hello world!']) + self.runCmd("type summary add --summary-string \"ptr = ${var[]%char[]}\" \"char *\"") # I do not know the size of the data, but you are asking for a full array slice.. @@ -154,6 +210,14 @@ substrs = ['ptr = \"', 'Nested Hello world!']) + self.expect("p strptr", matching=False, + substrs = ['ptr = \"', + 'Hello world!']) + + self.expect("p other.strptr", matching=False, + substrs = ['ptr = \"', + 'Nested Hello world!']) + # You asked an array-style printout... self.runCmd("type summary add --summary-string \"ptr = ${var[0-1]%char[]}\" \"char *\"") @@ -165,6 +229,14 @@ substrs = ['ptr = ', '[{N},{e}]']) + self.expect("p strptr", + substrs = ['ptr = ', + '[{H},{e}]']) + + self.expect("p other.strptr", + substrs = ['ptr = ', + '[{N},{e}]']) + # using [] is required here self.runCmd("type summary add --summary-string \"arr = ${var%x}\" \"int [5]\"") Modified: lldb/trunk/test/functionalities/target_command/TestTargetCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/TestTargetCommand.py?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/functionalities/target_command/TestTargetCommand.py (original) +++ lldb/trunk/test/functionalities/target_command/TestTargetCommand.py Tue Sep 6 14:20:51 2011 @@ -46,6 +46,15 @@ self.do_target_variable_command('globals') + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + def test_target_variable_command_with_dsym_no_fail(self): + """Test 'target variable' command before and after starting the inferior.""" + d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'} + self.buildDsym(dictionary=d) + self.addTearDownCleanup(dictionary=d) + + self.do_target_variable_command_no_fail('globals') + def do_target_command(self): """Exercise 'target create', 'target list', 'target select' commands.""" exe_a = os.path.join(os.getcwd(), "a.out") @@ -109,18 +118,78 @@ substrs = ['my_global_str', '"abc"']) self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['my_static_int', '228']) + self.expect("target variable my_global_str_ptr", matching=False, + substrs = ['"abc"']) + self.expect("target variable *my_global_str_ptr", matching=True, + substrs = ['"abc"']) + self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['a']) + self.runCmd("b main") self.runCmd("run") + + self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_global_str', '"abc"']) + self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_static_int', '228']) + self.expect("target variable my_global_str_ptr", matching=False, + substrs = ['"abc"']) + self.expect("target variable *my_global_str_ptr", matching=True, + substrs = ['"abc"']) + self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['a']) + self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["my_global_char", "'X'"]) + + self.runCmd("c") # rdar://problem/9763907 # 'target variable' command fails if the target program has been run + self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_global_str', '"abc"']) + self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_static_int', '228']) + self.expect("target variable my_global_str_ptr", matching=False, + substrs = ['"abc"']) + self.expect("target variable *my_global_str_ptr", matching=True, + substrs = ['"abc"']) + self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['a']) + self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["my_global_char", "'X'"]) + + def do_target_variable_command_no_fail(self, exe_name): + """Exercise 'target variable' command before and after starting the inferior.""" + self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET) + self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY, substrs = ["my_global_char", "'X'"]) self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['my_global_str', '"abc"']) self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY, substrs = ['my_static_int', '228']) + self.expect("target variable my_global_str_ptr", matching=False, + substrs = ['"abc"']) + self.expect("target variable *my_global_str_ptr", matching=True, + substrs = ['"abc"']) + self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['a']) + self.runCmd("b main") + self.runCmd("run") + + self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_global_str', '"abc"']) + self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['my_static_int', '228']) + self.expect("target variable my_global_str_ptr", matching=False, + substrs = ['"abc"']) + self.expect("target variable *my_global_str_ptr", matching=True, + substrs = ['"abc"']) + self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ['a']) + self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY, + substrs = ["my_global_char", "'X'"]) if __name__ == '__main__': import atexit Modified: lldb/trunk/test/functionalities/target_command/globals.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/target_command/globals.c?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/functionalities/target_command/globals.c (original) +++ lldb/trunk/test/functionalities/target_command/globals.c Tue Sep 6 14:20:51 2011 @@ -10,6 +10,7 @@ char my_global_char = 'X'; const char* my_global_str = "abc"; +const char **my_global_str_ptr = &my_global_str; static int my_static_int = 228; int main (int argc, char const *argv[]) Modified: lldb/trunk/test/lang/c/strings/TestCStrings.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/strings/TestCStrings.py?rev=139160&r1=139159&r2=139160&view=diff ============================================================================== --- lldb/trunk/test/lang/c/strings/TestCStrings.py (original) +++ lldb/trunk/test/lang/c/strings/TestCStrings.py Tue Sep 6 14:20:51 2011 @@ -50,6 +50,15 @@ self.expect("expression -- \"\"[0]", startstr = "(const char) $4 = '\\0'") + self.expect("p \"hello\"", + substrs = ['(const char [6]) $', 'hello', + '(const char) [0] = \'h\'', + '(const char) [5] = \'\\0\'']) + + self.expect("p (char*)\"hello\"", + substrs = ['(char *) $', ' = 0x', + 'hello']) + if __name__ == '__main__': import atexit lldb.SBDebugger.Initialize() Added: lldb/trunk/test/python_api/sbdata/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/sbdata/Makefile?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/python_api/sbdata/Makefile (added) +++ lldb/trunk/test/python_api/sbdata/Makefile Tue Sep 6 14:20:51 2011 @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/test/python_api/sbdata/TestSBData.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/sbdata/TestSBData.py?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/python_api/sbdata/TestSBData.py (added) +++ lldb/trunk/test/python_api/sbdata/TestSBData.py Tue Sep 6 14:20:51 2011 @@ -0,0 +1,204 @@ +"""Test the SBData APIs.""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * +from math import fabs + +class SBDataAPICase(TestBase): + + mydir = os.path.join("python_api", "sbdata") + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + def test_with_dsym_and_run_command(self): + """Test the SBData APIs.""" + self.buildDsym() + self.data_api() + + @python_api_test + def test_with_dwarf_and_process_launch_api(self): + """Test the SBData APIs.""" + self.buildDwarf() + self.data_api() + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break on inside main.cpp. + self.line = line_number('main.cpp', '// set breakpoint here') + + def data_api(self): + """Test the SBData APIs.""" + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.expect("breakpoint set -f main.cpp -l %d" % self.line, + BREAKPOINT_CREATED, + startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" % + self.line) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs = ['stopped', + 'stop reason = breakpoint']) + + target = self.dbg.GetSelectedTarget() + + process = target.GetProcess() + + thread = process.GetThreadAtIndex(0) + + frame = thread.GetSelectedFrame() + + foobar = frame.FindVariable('foobar') + + print foobar + + data = foobar.GetPointeeData(0, 2) + + print data + + offset = 0 + error = lldb.SBError() + + self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'foo[0].a == 1') + offset += 4 + low = data.GetSignedInt16(error, offset) + offset += 2 + high = data.GetSignedInt16(error, offset) + offset += 2 + self.assertTrue ((low == 9 and high == 0) or (low == 0 and high == 9), 'foo[0].b == 9') + self.assertTrue( fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[0].c == 3.14') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'foo[1].a == 8') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'foo[1].b == 5') + offset += 4 + + self.runCmd("n") + + offset = 16 + + self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'saved foo[1].b == 5') + + data = foobar.GetPointeeData(1, 1) + + offset = 0 + + self.assertTrue(data.GetSignedInt32(error, offset) == 8, 'new foo[1].a == 8') + offset += 4 + self.assertTrue(data.GetSignedInt32(error, offset) == 7, 'new foo[1].a == 7') + offset += 8 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 0, 'do not read beyond end') + + star_foobar = foobar.Dereference() + + data = star_foobar.GetData() + + print data + + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'foo[0].a == 1') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 9, 'foo[0].b == 9') + + foobar_addr = star_foobar.GetLoadAddress() + foobar_addr += 12 + + new_foobar = foobar.CreateValueFromAddress("f00", foobar_addr, star_foobar.GetType()) + + print new_foobar + + data = new_foobar.GetData() + + print data + + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'then foo[1].a == 8') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 7, 'then foo[1].b == 7') + offset += 4 + self.assertTrue(fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[1].c == 3.14') + + self.runCmd("n") + + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'then foo[1].a == 8') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 7, 'then foo[1].b == 7') + offset += 4 + self.assertTrue(fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[1].c == 3.14') + + data = new_foobar.GetData() + + print data + + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'finally foo[1].a == 8') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 7, 'finally foo[1].b == 7') + offset += 4 + self.assertTrue(fabs(data.GetFloat(error, offset) - 6.28) < 1, 'foo[1].c == 6.28') + + self.runCmd("n") + + barfoo = frame.FindVariable('barfoo') + + data = barfoo.GetData() + + print barfoo + + print data + + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'barfoo[0].a = 1') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 2, 'barfoo[0].b == 2') + offset += 4 + self.assertTrue(fabs(data.GetFloat(error, offset) - 3) < 1, 'barfoo[0].c == 3') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 4, 'barfoo[1].a = 4') + offset += 4 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'barfoo[1].b == 5') + offset += 4 + self.assertTrue(fabs(data.GetFloat(error, offset) - 6) < 1, 'barfoo[1].c == 6') + + new_object = barfoo.CreateValueFromData("new_object",data,barfoo.GetType().GetBasicType(lldb.eBasicTypeInt)) + + print new_object + + self.assertTrue(new_object.GetLoadAddress() == 0xFFFFFFFFFFFFFFFF, 'GetLoadAddress() == invalid') + self.assertTrue(new_object.AddressOf().IsValid() == False, 'AddressOf() == invalid') + self.assertTrue(new_object.GetAddress().IsValid() == False, 'GetAddress() == invalid') + + self.assertTrue(new_object.GetValue() == "1", 'new_object == 1') + + data.SetData(error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize()) + + data2 = lldb.SBData() + data2.SetData(error, 'BCD', data.GetByteOrder(), data.GetAddressByteSize()) + + data.Append(data2) + + print data + + # this breaks on EBCDIC + offset = 0 + self.assertTrue(data.GetUnsignedInt32(error, offset) == 65, 'made-up data == 65') + offset += 4 + self.assertTrue(data.GetUnsignedInt8(error, offset) == 66, 'made-up data == 66') + offset += 1 + self.assertTrue(data.GetUnsignedInt8(error, offset) == 67, 'made-up data == 67') + offset += 1 + self.assertTrue(data.GetUnsignedInt8(error, offset) == 68, 'made-up data == 68') + offset += 1 + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() Added: lldb/trunk/test/python_api/sbdata/main.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/sbdata/main.cpp?rev=139160&view=auto ============================================================================== --- lldb/trunk/test/python_api/sbdata/main.cpp (added) +++ lldb/trunk/test/python_api/sbdata/main.cpp Tue Sep 6 14:20:51 2011 @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include + +struct foo +{ + uint32_t a; + uint32_t b; + float c; + foo() : a(0), b(1), c(3.14) {} + foo(uint32_t A, uint32_t B, float C) : + a(A), + b(B), + c(C) + {} +}; + +int main (int argc, char const *argv[]) +{ + foo* foobar = new foo[2]; + + foobar[0].a = 1; + foobar[0].b = 9; + + foobar[1].a = 8; + foobar[1].b = 5; + + foobar[1].b = 7; // set breakpoint here + + foobar[1].c = 6.28; + + foo barfoo[] = {foo(1,2,3), foo(4,5,6)}; + + delete[] foobar; + + return 0; +} From johnny.chen at apple.com Tue Sep 6 14:52:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 06 Sep 2011 19:52:50 -0000 Subject: [Lldb-commits] [lldb] r139163 - in /lldb/trunk/tools/debugserver/source: DNB.cpp DNBBreakpoint.h DNBDefs.h Message-ID: <20110906195250.2060E2A6C12C@llvm.org> Author: johnny Date: Tue Sep 6 14:52:49 2011 New Revision: 139163 URL: http://llvm.org/viewvc/llvm-project?rev=139163&view=rev Log: DNBBreakpoint::SetEnabled() should take a bool, not a uint32_t, as its input argument. Plus for watchpoint related functions, add new macros INVALID_NUB_WATCH_ID and NUB_WATCH_ID_IS_VALID and use them, instead. Modified: lldb/trunk/tools/debugserver/source/DNB.cpp lldb/trunk/tools/debugserver/source/DNBBreakpoint.h lldb/trunk/tools/debugserver/source/DNBDefs.h Modified: lldb/trunk/tools/debugserver/source/DNB.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=139163&r1=139162&r2=139163&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNB.cpp (original) +++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue Sep 6 14:52:49 2011 @@ -972,13 +972,13 @@ { return procSP->CreateWatchpoint(addr, size, watch_flags, hardware, THREAD_NULL); } - return INVALID_NUB_BREAK_ID; + return INVALID_NUB_WATCH_ID; } nub_bool_t DNBWatchpointClear (nub_process_t pid, nub_watch_t watchID) { - if (NUB_BREAK_ID_IS_VALID(watchID)) + if (NUB_WATCH_ID_IS_VALID(watchID)) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) @@ -992,7 +992,7 @@ nub_ssize_t DNBWatchpointGetHitCount (nub_process_t pid, nub_watch_t watchID) { - if (NUB_BREAK_ID_IS_VALID(watchID)) + if (NUB_WATCH_ID_IS_VALID(watchID)) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) @@ -1008,7 +1008,7 @@ nub_ssize_t DNBWatchpointGetIgnoreCount (nub_process_t pid, nub_watch_t watchID) { - if (NUB_BREAK_ID_IS_VALID(watchID)) + if (NUB_WATCH_ID_IS_VALID(watchID)) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) @@ -1024,7 +1024,7 @@ nub_bool_t DNBWatchpointSetIgnoreCount (nub_process_t pid, nub_watch_t watchID, nub_size_t ignore_count) { - if (NUB_BREAK_ID_IS_VALID(watchID)) + if (NUB_WATCH_ID_IS_VALID(watchID)) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) @@ -1047,7 +1047,7 @@ nub_bool_t DNBWatchpointSetCallback (nub_process_t pid, nub_watch_t watchID, DNBCallbackBreakpointHit callback, void *baton) { - if (NUB_BREAK_ID_IS_VALID(watchID)) + if (NUB_WATCH_ID_IS_VALID(watchID)) { MachProcessSP procSP; if (GetProcessSP (pid, procSP)) Modified: lldb/trunk/tools/debugserver/source/DNBBreakpoint.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBBreakpoint.h?rev=139163&r1=139162&r2=139163&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNBBreakpoint.h (original) +++ lldb/trunk/tools/debugserver/source/DNBBreakpoint.h Tue Sep 6 14:52:49 2011 @@ -73,7 +73,7 @@ } return false; } - void SetEnabled(uint32_t enabled) + void SetEnabled(bool enabled) { if (!enabled) SetHardwareIndex(INVALID_NUB_HW_INDEX); Modified: lldb/trunk/tools/debugserver/source/DNBDefs.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBDefs.h?rev=139163&r1=139162&r2=139163&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/DNBDefs.h (original) +++ lldb/trunk/tools/debugserver/source/DNBDefs.h Tue Sep 6 14:52:49 2011 @@ -66,11 +66,13 @@ #define INVALID_NUB_BREAK_ID ((nub_break_t)0) #define INVALID_NUB_PROCESS ((nub_process_t)0) #define INVALID_NUB_THREAD ((nub_thread_t)0) +#define INVALID_NUB_WATCH_ID ((nub_watch_t)0) #define INVALID_NUB_HW_INDEX UINT32_MAX #define INVALID_NUB_REGNUM UINT32_MAX #define NUB_GENERIC_ERROR UINT32_MAX #define NUB_BREAK_ID_IS_VALID(breakID) ((breakID) != (INVALID_NUB_BREAK_ID)) +#define NUB_WATCH_ID_IS_VALID(watchID) ((watchID) != (INVALID_NUB_WATCH_ID)) // Watchpoint types #define WATCH_TYPE_READ (1u << 0) From johnny.chen at apple.com Tue Sep 6 15:05:25 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 06 Sep 2011 20:05:25 -0000 Subject: [Lldb-commits] [lldb] r139166 - in /lldb/trunk: include/lldb/Breakpoint/WatchpointLocationList.h include/lldb/Target/Target.h include/lldb/lldb-forward-rtti.h include/lldb/lldb-types.h lldb.xcodeproj/project.pbxproj source/Breakpoint/WatchpointLocationList.cpp source/Target/Target.cpp Message-ID: <20110906200525.E49EC2A6C12C@llvm.org> Author: johnny Date: Tue Sep 6 15:05:25 2011 New Revision: 139166 URL: http://llvm.org/viewvc/llvm-project?rev=139166&view=rev Log: Add a data type WatchpointLocationList to the repository. A Target contains an instance of watchpoint location list. Also add a typefed for WatchpointLocationSP to lldb-forward-rtti.h. Added: lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h lldb/trunk/source/Breakpoint/WatchpointLocationList.cpp Modified: lldb/trunk/include/lldb/Target/Target.h lldb/trunk/include/lldb/lldb-forward-rtti.h lldb/trunk/include/lldb/lldb-types.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Target/Target.cpp Added: lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h?rev=139166&view=auto ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h (added) +++ lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h Tue Sep 6 15:05:25 2011 @@ -0,0 +1,191 @@ +//===-- WatchpointLocationList.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_WatchpointLocationList_h_ +#define liblldb_WatchpointLocationList_h_ + +// C Includes +// C++ Includes +#include +#include +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/Address.h" +#include "lldb/Host/Mutex.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class WatchpointLocationList WatchpointLocationList.h "lldb/Breakpoint/WatchpointLocationList.h" +/// @brief This class is used by Watchpoint to manage a list of watchpoint locations, +// each watchpoint location in the list +/// has a unique ID, and is unique by Address as well. +//---------------------------------------------------------------------- + +class WatchpointLocationList +{ +// Only Target can make the location list, or add elements to it. +// This is not just some random collection of locations. Rather, the act of adding the location +// to this list sets its ID. +friend class WatchpointLocation; + +public: + //------------------------------------------------------------------ + /// Default constructor makes an empty list. + //------------------------------------------------------------------ + WatchpointLocationList(); + + //------------------------------------------------------------------ + /// Destructor, currently does nothing. + //------------------------------------------------------------------ + ~WatchpointLocationList(); + + //------------------------------------------------------------------ + /// Add a WatchpointLocation to the list. + /// + /// @param[in] wp_loc_sp + /// A shared pointer to a watchpoint location being added to the list. + /// + /// @return + /// The ID of the WatchpointLocation in the list. + //------------------------------------------------------------------ + lldb::watch_id_t + Add (const lldb::WatchpointLocationSP& wp_loc_sp); + + //------------------------------------------------------------------ + /// Standard "Dump" method. + //------------------------------------------------------------------ + void + Dump (Stream *s) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the watchpoint location at address + /// \a addr - const version. + /// + /// @param[in] addr + /// The address to look for. + /// + /// @result + /// A shared pointer to the watchpoint. May contain a NULL + /// pointer if the watchpoint doesn't exist. + //------------------------------------------------------------------ + const lldb::WatchpointLocationSP + FindByAddress (lldb::addr_t addr) const; + + //------------------------------------------------------------------ + /// Returns a shared pointer to the watchpoint location with id + /// \a breakID, const version. + /// + /// @param[in] breakID + /// The watchpoint location ID to seek for. + /// + /// @result + /// A shared pointer to the watchpoint. May contain a NULL + /// pointer if the watchpoint doesn't exist. + //------------------------------------------------------------------ + lldb::WatchpointLocationSP + FindByID (lldb::watch_id_t watchID) const; + + //------------------------------------------------------------------ + /// Returns the watchpoint location id to the watchpoint location + /// at address \a addr. + /// + /// @param[in] addr + /// The address to match. + /// + /// @result + /// The ID of the watchpoint location, or LLDB_INVALID_WATCH_ID. + //------------------------------------------------------------------ + lldb::watch_id_t + FindIDByAddress (lldb::addr_t addr); + + //------------------------------------------------------------------ + /// Removes the watchpoint location given by \b watchID from this list. + /// + /// @param[in] watchID + /// The watchpoint location ID to remove. + /// + /// @result + /// \b true if the watchpoint location \a watchID was in the list. + //------------------------------------------------------------------ + bool + Remove (lldb::watch_id_t watchID); + + //------------------------------------------------------------------ + /// Returns the number hit count of all locations in this list. + /// + /// @result + /// Hit count of all locations in this list. + //------------------------------------------------------------------ + uint32_t + GetHitCount () const; + + //------------------------------------------------------------------ + /// Enquires of the watchpoint location in this list with ID \a + /// watchID whether we should stop. + /// + /// @param[in] context + /// This contains the information about this stop. + /// + /// @param[in] watchID + /// This watch ID that we hit. + /// + /// @return + /// \b true if we should stop, \b false otherwise. + //------------------------------------------------------------------ + bool + ShouldStop (StoppointCallbackContext *context, + lldb::watch_id_t watchID); + + //------------------------------------------------------------------ + /// Returns the number of elements in this watchpoint location list. + /// + /// @result + /// The number of elements. + //------------------------------------------------------------------ + size_t + GetSize() const + { + return m_address_to_location.size(); + } + + //------------------------------------------------------------------ + /// Print a description of the watchpoint locations in this list to + /// the stream \a s. + /// + /// @param[in] s + /// The stream to which to print the description. + /// + /// @param[in] level + /// The description level that indicates the detail level to + /// provide. + /// + /// @see lldb::DescriptionLevel + //------------------------------------------------------------------ + void + GetDescription (Stream *s, + lldb::DescriptionLevel level); + +protected: + typedef std::map addr_map; + + addr_map::iterator + GetIDIterator(lldb::watch_id_t watchID); + + addr_map::const_iterator + GetIDConstIterator(lldb::watch_id_t watchID) const; + + addr_map m_address_to_location; + mutable Mutex m_mutex; +}; + +} // namespace lldb_private + +#endif // liblldb_WatchpointLocationList_h_ Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=139166&r1=139165&r2=139166&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Tue Sep 6 15:05:25 2011 @@ -18,6 +18,7 @@ #include "lldb/lldb-public.h" #include "lldb/Breakpoint/BreakpointList.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" +#include "lldb/Breakpoint/WatchpointLocationList.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" #include "lldb/Core/ModuleList.h" @@ -813,6 +814,7 @@ BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; lldb::BreakpointSP m_last_created_breakpoint; + WatchpointLocationList m_watchpoint_location_list; // We want to tightly control the process destruction process so // we can correctly tear down everything that we need to, so the only // class that knows about the process lifespan is this target class. Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=139166&r1=139165&r2=139166&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward-rtti.h (original) +++ lldb/trunk/include/lldb/lldb-forward-rtti.h Tue Sep 6 15:05:25 2011 @@ -86,6 +86,7 @@ typedef SharedPtr::Type VariableSP; typedef SharedPtr::Type VariableListSP; typedef SharedPtr::Type ValueObjectListSP; + typedef SharedPtr::Type WatchpointLocationSP; } // namespace lldb Modified: lldb/trunk/include/lldb/lldb-types.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-types.h?rev=139166&r1=139165&r2=139166&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-types.h (original) +++ lldb/trunk/include/lldb/lldb-types.h Tue Sep 6 15:05:25 2011 @@ -94,6 +94,7 @@ typedef int32_t pid_t; typedef uint32_t tid_t; typedef int32_t break_id_t; + typedef int32_t watch_id_t; typedef void * clang_type_t; } Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=139166&r1=139165&r2=139166&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Sep 6 15:05:25 2011 @@ -437,6 +437,7 @@ 9AC703AF117675410086C050 /* SBInstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC703AE117675410086C050 /* SBInstruction.cpp */; }; 9AC703B1117675490086C050 /* SBInstructionList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC703B0117675490086C050 /* SBInstructionList.cpp */; }; B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */; }; + B27318421416AC12006039C8 /* WatchpointLocationList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B27318411416AC12006039C8 /* WatchpointLocationList.cpp */; }; B28058A1139988B0002D96D0 /* InferiorCallPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */; }; /* End PBXBuildFile section */ @@ -1291,6 +1292,8 @@ AF68D3301255A110002FF25B /* UnwindLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindLLDB.h; path = Utility/UnwindLLDB.h; sourceTree = ""; }; AF94005711C03F6500085DB9 /* SymbolVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolVendor.cpp; path = source/Symbol/SymbolVendor.cpp; sourceTree = ""; }; B23DD24F12EDFAC1000C3894 /* ARMUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARMUtils.h; path = Utility/ARMUtils.h; sourceTree = ""; }; + B27318411416AC12006039C8 /* WatchpointLocationList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocationList.cpp; path = source/Breakpoint/WatchpointLocationList.cpp; sourceTree = ""; }; + B27318431416AC43006039C8 /* WatchpointLocationList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WatchpointLocationList.h; path = include/lldb/Breakpoint/WatchpointLocationList.h; sourceTree = ""; }; B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InferiorCallPOSIX.cpp; path = Utility/InferiorCallPOSIX.cpp; sourceTree = ""; }; B28058A2139988C6002D96D0 /* InferiorCallPOSIX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = InferiorCallPOSIX.h; path = Utility/InferiorCallPOSIX.h; sourceTree = ""; }; B287E63E12EFAE2C00C9BEFE /* ARMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARMDefines.h; path = Utility/ARMDefines.h; sourceTree = ""; }; @@ -2176,7 +2179,9 @@ 26BC7CFB10F1B71400F91463 /* StoppointLocation.h */, 26BC7E1710F1B83100F91463 /* StoppointLocation.cpp */, 26BC7CFC10F1B71400F91463 /* WatchpointLocation.h */, + B27318431416AC43006039C8 /* WatchpointLocationList.h */, 26BC7E1810F1B83100F91463 /* WatchpointLocation.cpp */, + B27318411416AC12006039C8 /* WatchpointLocationList.cpp */, ); name = Breakpoint; sourceTree = ""; @@ -3338,6 +3343,7 @@ 949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */, 268ED0A5140FF54200DE830F /* DataEncoder.cpp in Sources */, 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */, + B27318421416AC12006039C8 /* WatchpointLocationList.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Added: lldb/trunk/source/Breakpoint/WatchpointLocationList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointLocationList.cpp?rev=139166&view=auto ============================================================================== --- lldb/trunk/source/Breakpoint/WatchpointLocationList.cpp (added) +++ lldb/trunk/source/Breakpoint/WatchpointLocationList.cpp Tue Sep 6 15:05:25 2011 @@ -0,0 +1,190 @@ +//===-- WatchpointLocationList.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Breakpoint/WatchpointLocationList.h" +#include "lldb/Breakpoint/WatchpointLocation.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +WatchpointLocationList::WatchpointLocationList() : + m_address_to_location (), + m_mutex (Mutex::eMutexTypeRecursive) +{ +} + +WatchpointLocationList::~WatchpointLocationList() +{ +} + +// Add watchpoint loc to the list. However, if the element already exists in the +// list, then replace it with the input one. + +lldb::watch_id_t +WatchpointLocationList::Add (const WatchpointLocationSP &wp_loc_sp) +{ + Mutex::Locker locker (m_mutex); + lldb::addr_t wp_addr = wp_loc_sp->GetLoadAddress(); + addr_map::iterator iter = m_address_to_location.find(wp_addr); + + if (iter == m_address_to_location.end()) + { + m_address_to_location.insert(iter, addr_map::value_type(wp_addr, wp_loc_sp)); + } + else + { + m_address_to_location[wp_addr] = wp_loc_sp; + } + return wp_loc_sp->GetID(); +} + +void +WatchpointLocationList::Dump (Stream *s) const +{ + Mutex::Locker locker (m_mutex); + s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); + //s->Indent(); + s->Printf("WatchpointLocationList with %zu WatchpointLocations:\n", + m_address_to_location.size()); + s->IndentMore(); + addr_map::const_iterator pos, end = m_address_to_location.end(); + for (pos = m_address_to_location.begin(); pos != end; ++pos) + pos->second->Dump(s); + s->IndentLess(); +} + +const WatchpointLocationSP +WatchpointLocationList::FindByAddress (lldb::addr_t addr) const +{ + WatchpointLocationSP wp_loc_sp; + Mutex::Locker locker (m_mutex); + if (!m_address_to_location.empty()) + { + addr_map::const_iterator pos = m_address_to_location.find (addr); + if (pos != m_address_to_location.end()) + wp_loc_sp = pos->second; + } + + return wp_loc_sp; +} + +class WatchpointLocationIDMatches +{ +public: + WatchpointLocationIDMatches (lldb::watch_id_t watch_id) : + m_watch_id(watch_id) + { + } + + bool operator() (std::pair val_pair) const + { + return m_watch_id == val_pair.second.get()->GetID(); + } + +private: + const lldb::watch_id_t m_watch_id; +}; + +WatchpointLocationList::addr_map::iterator +WatchpointLocationList::GetIDIterator (lldb::watch_id_t watch_id) +{ + return std::find_if(m_address_to_location.begin(), m_address_to_location.end(), // Search full range + WatchpointLocationIDMatches(watch_id)); // Predicate +} + +WatchpointLocationList::addr_map::const_iterator +WatchpointLocationList::GetIDConstIterator (lldb::watch_id_t watch_id) const +{ + return std::find_if(m_address_to_location.begin(), m_address_to_location.end(), // Search full range + WatchpointLocationIDMatches(watch_id)); // Predicate +} + +WatchpointLocationSP +WatchpointLocationList::FindByID (lldb::watch_id_t watch_id) const +{ + WatchpointLocationSP wp_loc_sp; + Mutex::Locker locker (m_mutex); + addr_map::const_iterator pos = GetIDConstIterator(watch_id); + if (pos != m_address_to_location.end()) + wp_loc_sp = pos->second; + + return wp_loc_sp; +} + +lldb::watch_id_t +WatchpointLocationList::FindIDByAddress (lldb::addr_t addr) +{ + WatchpointLocationSP wp_loc_sp = FindByAddress (addr); + if (wp_loc_sp) + { + return wp_loc_sp->GetID(); + } + return LLDB_INVALID_WATCH_ID; +} + +bool +WatchpointLocationList::Remove (lldb::watch_id_t watch_id) +{ + Mutex::Locker locker (m_mutex); + addr_map::iterator pos = GetIDIterator(watch_id); // Predicate + if (pos != m_address_to_location.end()) + { + m_address_to_location.erase(pos); + return true; + } + return false; +} + +uint32_t +WatchpointLocationList::GetHitCount () const +{ + uint32_t hit_count = 0; + Mutex::Locker locker (m_mutex); + addr_map::const_iterator pos, end = m_address_to_location.end(); + for (pos = m_address_to_location.begin(); pos != end; ++pos) + hit_count += pos->second->GetHitCount(); + return hit_count; +} + +bool +WatchpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::watch_id_t watch_id) +{ + WatchpointLocationSP wp_loc_sp = FindByID (watch_id); + if (wp_loc_sp) + { + // Let the WatchpointLocation decide if it should stop here (could not have + // reached it's target hit count yet, or it could have a callback + // that decided it shouldn't stop. + return wp_loc_sp->ShouldStop (context); + } + // We should stop here since this WatchpointLocation isn't valid anymore or it + // doesn't exist. + return true; +} + +void +WatchpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level) +{ + Mutex::Locker locker (m_mutex); + addr_map::iterator pos, end = m_address_to_location.end(); + + for (pos = m_address_to_location.begin(); pos != end; ++pos) + { + s->Printf(" "); + pos->second->Dump(s); + } +} + Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=139166&r1=139165&r2=139166&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Tue Sep 6 15:05:25 2011 @@ -53,6 +53,7 @@ m_section_load_list (), m_breakpoint_list (false), m_internal_breakpoint_list (true), + m_watchpoint_location_list (), m_process_sp (), m_search_filter_sp (), m_image_search_paths (ImageSearchPathsChanged, this), From johnny.chen at apple.com Tue Sep 6 15:32:42 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 06 Sep 2011 20:32:42 -0000 Subject: [Lldb-commits] [lldb] r139174 - /lldb/trunk/test/python_api/sbdata/TestSBData.py Message-ID: <20110906203242.5D9A92A6C12C@llvm.org> Author: johnny Date: Tue Sep 6 15:32:42 2011 New Revision: 139174 URL: http://llvm.org/viewvc/llvm-project?rev=139174&view=rev Log: Test should print to stdout only if self.TraceOn() is True. Modified: lldb/trunk/test/python_api/sbdata/TestSBData.py Modified: lldb/trunk/test/python_api/sbdata/TestSBData.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/sbdata/TestSBData.py?rev=139174&r1=139173&r2=139174&view=diff ============================================================================== --- lldb/trunk/test/python_api/sbdata/TestSBData.py (original) +++ lldb/trunk/test/python_api/sbdata/TestSBData.py Tue Sep 6 15:32:42 2011 @@ -56,11 +56,13 @@ foobar = frame.FindVariable('foobar') - print foobar + if self.TraceOn(): + print foobar data = foobar.GetPointeeData(0, 2) - print data + if self.TraceOn(): + print data offset = 0 error = lldb.SBError() @@ -99,7 +101,8 @@ data = star_foobar.GetData() - print data + if self.TraceOn(): + print data offset = 0 self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'foo[0].a == 1') @@ -111,11 +114,13 @@ new_foobar = foobar.CreateValueFromAddress("f00", foobar_addr, star_foobar.GetType()) - print new_foobar + if self.TraceOn(): + print new_foobar data = new_foobar.GetData() - print data + if self.TraceOn(): + print data offset = 0 self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'then foo[1].a == 8') @@ -135,7 +140,8 @@ data = new_foobar.GetData() - print data + if self.TraceOn(): + print data offset = 0 self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'finally foo[1].a == 8') @@ -150,9 +156,11 @@ data = barfoo.GetData() - print barfoo + if self.TraceOn(): + print barfoo - print data + if self.TraceOn(): + print data offset = 0 self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'barfoo[0].a = 1') @@ -169,7 +177,8 @@ new_object = barfoo.CreateValueFromData("new_object",data,barfoo.GetType().GetBasicType(lldb.eBasicTypeInt)) - print new_object + if self.TraceOn(): + print new_object self.assertTrue(new_object.GetLoadAddress() == 0xFFFFFFFFFFFFFFFF, 'GetLoadAddress() == invalid') self.assertTrue(new_object.AddressOf().IsValid() == False, 'AddressOf() == invalid') @@ -184,7 +193,8 @@ data.Append(data2) - print data + if self.TraceOn(): + print data # this breaks on EBCDIC offset = 0 From johnny.chen at apple.com Tue Sep 6 17:38:36 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 06 Sep 2011 22:38:36 -0000 Subject: [Lldb-commits] [lldb] r139198 - in /lldb/trunk: include/lldb/Breakpoint/WatchpointLocation.h source/Breakpoint/WatchpointLocation.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Message-ID: <20110906223837.08CA42A6C12C@llvm.org> Author: johnny Date: Tue Sep 6 17:38:36 2011 New Revision: 139198 URL: http://llvm.org/viewvc/llvm-project?rev=139198&view=rev Log: Fill out implementation of Enable/DisableWatchpoint() for ProcessGDBRemote class (Not Tested Yet). Also update the signature of WatchpointLocation::SetEnable() to take a bool as input arg. Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h lldb/trunk/source/Breakpoint/WatchpointLocation.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h?rev=139198&r1=139197&r2=139198&view=diff ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h (original) +++ lldb/trunk/include/lldb/Breakpoint/WatchpointLocation.h Tue Sep 6 17:38:36 2011 @@ -37,7 +37,7 @@ IsEnabled () const; void - SetEnabled (uint32_t enabled); + SetEnabled (bool enabled); bool WatchpointRead () const; bool WatchpointWrite () const; Modified: lldb/trunk/source/Breakpoint/WatchpointLocation.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointLocation.cpp?rev=139198&r1=139197&r2=139198&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/WatchpointLocation.cpp (original) +++ lldb/trunk/source/Breakpoint/WatchpointLocation.cpp Tue Sep 6 17:38:36 2011 @@ -99,7 +99,7 @@ } void -WatchpointLocation::SetEnabled(uint32_t enabled) +WatchpointLocation::SetEnabled(bool enabled) { if (!enabled) SetHardwareIndex(LLDB_INVALID_INDEX32); Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=139198&r1=139197&r2=139198&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Sep 6 17:38:36 2011 @@ -1882,6 +1882,24 @@ return error; } +// Pre-requisite: wp != NULL. +static GDBStoppointType +GetGDBStoppointType (WatchpointLocation *wp) +{ + assert(wp); + bool watch_read = wp->WatchpointRead(); + bool watch_write = wp->WatchpointWrite(); + + // watch_read and watch_write cannot both be false. + assert(watch_read || watch_write); + if (watch_read && watch_write) + return eWatchpointReadWrite; + if (watch_read) + return eWatchpointRead; + if (watch_write) + return eWatchpointWrite; +} + Error ProcessGDBRemote::EnableWatchpoint (WatchpointLocation *wp) { @@ -1899,11 +1917,21 @@ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %d) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr); return error; } - else + + GDBStoppointType type = GetGDBStoppointType(wp); + // Pass down an appropriate z/Z packet... + if (m_gdb_comm.SupportsGDBStoppointPacket (type)) { - // Pass down an appropriate z/Z packet... - error.SetErrorString("watchpoints not supported"); + if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0) + { + wp->SetEnabled(true); + return error; + } + else + error.SetErrorString("sending gdb watchpoint packet failed"); } + else + error.SetErrorString("watchpoints not supported"); } else { @@ -1928,10 +1956,24 @@ if (log) log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx", watchID, (uint64_t)addr); + if (!wp->IsEnabled()) + { + if (log) + log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %d) addr = 0x%8.8llx -- SUCCESS (already disabled)", watchID, (uint64_t)addr); + return error; + } + if (wp->IsHardware()) { + GDBStoppointType type = GetGDBStoppointType(wp); // Pass down an appropriate z/Z packet... - error.SetErrorString("watchpoints not supported"); + if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0) + { + wp->SetEnabled(false); + return error; + } + else + error.SetErrorString("sending gdb watchpoint packet failed"); } // TODO: clear software watchpoints if we implement them } From granata.enrico at gmail.com Tue Sep 6 17:59:55 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Tue, 06 Sep 2011 22:59:55 -0000 Subject: [Lldb-commits] [lldb] r139201 - in /lldb/trunk: include/lldb/Core/DataVisualization.h include/lldb/Core/FormatManager.h include/lldb/Core/ValueObject.h source/Commands/CommandObjectType.cpp source/Core/DataVisualization.cpp source/Core/FormatManager.cpp source/Core/ValueObject.cpp Message-ID: <20110906225955.524FE2A6C12C@llvm.org> Author: enrico Date: Tue Sep 6 17:59:55 2011 New Revision: 139201 URL: http://llvm.org/viewvc/llvm-project?rev=139201&view=rev Log: Refactoring of Get() methods in FormatManager/FormatCategory to have explicative names and return shared-pointers instead of bools Reduced the amount of memory required to avoid loops in DumpPrintableRepresentation() from 32 bits down to 1 bit - Additionally, disallowed creating summary strings of the form ${var%S} which did nothing but cause endless loops by definition Modified: lldb/trunk/include/lldb/Core/DataVisualization.h lldb/trunk/include/lldb/Core/FormatManager.h lldb/trunk/include/lldb/Core/ValueObject.h lldb/trunk/source/Commands/CommandObjectType.cpp lldb/trunk/source/Core/DataVisualization.cpp lldb/trunk/source/Core/FormatManager.cpp lldb/trunk/source/Core/ValueObject.cpp Modified: lldb/trunk/include/lldb/Core/DataVisualization.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataVisualization.h?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/DataVisualization.h (original) +++ lldb/trunk/include/lldb/Core/DataVisualization.h Tue Sep 6 17:59:55 2011 @@ -48,8 +48,8 @@ class ValueFormats { public: - static bool - Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic, lldb::ValueFormatSP &entry); + static lldb::ValueFormatSP + Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic); static void Add (const ConstString &type, const lldb::ValueFormatSP &entry); @@ -67,14 +67,13 @@ GetCount (); }; - static bool + static lldb::SummaryFormatSP GetSummaryFormat(ValueObject& valobj, - lldb::DynamicValueType use_dynamic, - lldb::SummaryFormatSP& entry); - static bool + lldb::DynamicValueType use_dynamic); + + static lldb::SyntheticChildrenSP GetSyntheticChildren(ValueObject& valobj, - lldb::DynamicValueType use_dynamic, - lldb::SyntheticChildrenSP& entry); + lldb::DynamicValueType use_dynamic); static bool AnyMatches(ConstString type_name, Modified: lldb/trunk/include/lldb/Core/FormatManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/FormatManager.h (original) +++ lldb/trunk/include/lldb/Core/FormatManager.h Tue Sep 6 17:59:55 2011 @@ -299,15 +299,13 @@ return m_map.size(); } - bool - Get (ValueObject& valobj, - lldb::SummaryFormatSP& entry, + lldb::SummaryFormatSP + GetSummaryFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic); - bool - Get (ValueObject& valobj, - lldb::SyntheticChildrenSP& entry, - lldb::DynamicValueType use_dynamic); + lldb::SyntheticChildrenSP + GetSyntheticChildren (ValueObject& valobj, + lldb::DynamicValueType use_dynamic); private: @@ -422,20 +420,18 @@ GetCategory (const ConstString& category_name, bool can_create = true); - bool - Get (ValueObject& valobj, - lldb::SummaryFormatSP& entry, - lldb::DynamicValueType use_dynamic) + lldb::SummaryFormatSP + GetSummaryFormat (ValueObject& valobj, + lldb::DynamicValueType use_dynamic) { - return m_categories_map.Get(valobj, entry, use_dynamic); + return m_categories_map.GetSummaryFormat(valobj, use_dynamic); } - bool - Get (ValueObject& valobj, - lldb::SyntheticChildrenSP& entry, - lldb::DynamicValueType use_dynamic) + lldb::SyntheticChildrenSP + GetSyntheticChildren (ValueObject& valobj, + lldb::DynamicValueType use_dynamic) { - return m_categories_map.Get(valobj, entry, use_dynamic); + return m_categories_map.GetSyntheticChildren(valobj, use_dynamic); } bool Modified: lldb/trunk/include/lldb/Core/ValueObject.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ValueObject.h (original) +++ lldb/trunk/include/lldb/Core/ValueObject.h Tue Sep 6 17:59:55 2011 @@ -920,6 +920,7 @@ m_forced_summary_format = format; m_user_id_of_forced_summary = m_update_point.GetModID(); m_summary_str.clear(); + m_trying_summary_already = false; } lldb::SummaryFormatSP @@ -949,6 +950,42 @@ return m_forced_summary_format; return m_last_summary_format; } + + void + SetSummaryFormat(lldb::SummaryFormatSP format) + { + m_last_summary_format = format; + m_summary_str.clear(); + m_trying_summary_already = false; + } + + void + SetValueFormat(lldb::ValueFormatSP format) + { + m_last_value_format = format; + m_value_str.clear(); + } + + lldb::ValueFormatSP + GetValueFormat() + { + UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); + return m_last_value_format; + } + + void + SetSyntheticChildren(lldb::SyntheticChildrenSP synth) + { + m_last_synthetic_filter = synth; + m_synthetic_value = NULL; + } + + lldb::SyntheticChildrenSP + GetSyntheticChildren() + { + UpdateFormatsIfNeeded(m_last_format_mgr_dynamic); + return m_last_synthetic_filter; + } // Use GetParent for display purposes, but if you want to tell the parent to update itself // then use m_parent. The ValueObjectDynamicValue's parent is not the correct parent for @@ -1012,13 +1049,15 @@ // as a shared pointer to any of them has been handed out. Shared pointers to // value objects must always be made with the GetSP method. - std::vector m_children; + std::vector m_children; std::map m_synthetic_children; - ValueObject *m_dynamic_value; - ValueObject *m_synthetic_value; + + ValueObject* m_dynamic_value; + ValueObject* m_synthetic_value; + ValueObject* m_deref_valobj; + lldb::ValueObjectSP m_addr_of_valobj_sp; // We have to hold onto a shared pointer to this one because it is created // as an independent ValueObjectConstResult, which isn't managed by us. - ValueObject *m_deref_valobj; lldb::Format m_format; uint32_t m_last_format_mgr_revision; @@ -1028,6 +1067,7 @@ lldb::ValueFormatSP m_last_value_format; lldb::SyntheticChildrenSP m_last_synthetic_filter; ProcessModID m_user_id_of_forced_summary; + AddressType m_address_type_of_ptr_or_ref_children; bool m_value_is_valid:1, m_value_did_change:1, @@ -1037,12 +1077,8 @@ m_is_array_item_for_pointer:1, m_is_bitfield_for_scalar:1, m_is_expression_path_child:1, - m_is_child_at_offset:1; - - // used to prevent endless looping into GetPrintableRepresentation() - uint32_t m_dump_printable_counter; - - AddressType m_address_type_of_ptr_or_ref_children; + m_is_child_at_offset:1, + m_trying_summary_already:1; // used to prevent endless recursion in printing summaries friend class ClangExpressionDeclMap; // For GetValue friend class ClangExpressionVariable; // For SetName Modified: lldb/trunk/source/Commands/CommandObjectType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectType.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectType.cpp Tue Sep 6 17:59:55 2011 @@ -873,6 +873,14 @@ const char* format_cstr = (m_options.m_one_liner ? "" : m_options.m_format_string.c_str()); + // ${var%S} is an endless recursion, prevent it + if (strcmp(format_cstr, "${var%S}") == 0) + { + result.AppendError("recursive summary not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + Error error; lldb::SummaryFormatSP entry(new StringSummaryFormat(m_options.m_cascade, Modified: lldb/trunk/source/Core/DataVisualization.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataVisualization.cpp?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/source/Core/DataVisualization.cpp (original) +++ lldb/trunk/source/Core/DataVisualization.cpp Tue Sep 6 17:59:55 2011 @@ -38,10 +38,12 @@ return GetFormatManager().GetCurrentRevision(); } -bool -DataVisualization::ValueFormats::Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic, lldb::ValueFormatSP &entry) +lldb::ValueFormatSP +DataVisualization::ValueFormats::Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic) { - return GetFormatManager().GetValueNavigator().Get(valobj,entry, use_dynamic); + lldb::ValueFormatSP entry; + GetFormatManager().GetValueNavigator().Get(valobj, entry, use_dynamic); + return entry; } void @@ -74,19 +76,18 @@ return GetFormatManager().GetValueNavigator().GetCount(); } -bool +lldb::SummaryFormatSP DataVisualization::GetSummaryFormat (ValueObject& valobj, - lldb::DynamicValueType use_dynamic, - lldb::SummaryFormatSP& entry) + lldb::DynamicValueType use_dynamic) { - return GetFormatManager().Get(valobj, entry, use_dynamic); + return GetFormatManager().GetSummaryFormat(valobj, use_dynamic); } -bool + +lldb::SyntheticChildrenSP DataVisualization::GetSyntheticChildren (ValueObject& valobj, - lldb::DynamicValueType use_dynamic, - lldb::SyntheticChildrenSP& entry) + lldb::DynamicValueType use_dynamic) { - return GetFormatManager().Get(valobj, entry, use_dynamic); + return GetFormatManager().GetSyntheticChildren(valobj, use_dynamic); } bool Modified: lldb/trunk/source/Core/FormatManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/source/Core/FormatManager.cpp (original) +++ lldb/trunk/source/Core/FormatManager.cpp Tue Sep 6 17:59:55 2011 @@ -402,10 +402,9 @@ return false; } -bool -CategoryMap::Get (ValueObject& valobj, - lldb::SummaryFormatSP& entry, - lldb::DynamicValueType use_dynamic) +lldb::SummaryFormatSP +CategoryMap::GetSummaryFormat (ValueObject& valobj, + lldb::DynamicValueType use_dynamic) { Mutex::Locker(m_map_mutex); @@ -418,16 +417,14 @@ lldb::SummaryFormatSP current_format; if (!category->Get(valobj, current_format, use_dynamic, &reason_why)) continue; - entry = current_format; - return true; + return current_format; } - return false; + return lldb::SummaryFormatSP(); } -bool -CategoryMap::Get (ValueObject& valobj, - lldb::SyntheticChildrenSP& entry, - lldb::DynamicValueType use_dynamic) +lldb::SyntheticChildrenSP +CategoryMap::GetSyntheticChildren (ValueObject& valobj, + lldb::DynamicValueType use_dynamic) { Mutex::Locker(m_map_mutex); @@ -441,10 +438,9 @@ lldb::SyntheticChildrenSP current_format; if (!category->Get(valobj, current_format, use_dynamic, &reason_why)) continue; - entry = current_format; - return true; + return current_format; } - return false; + return lldb::SyntheticChildrenSP(); } void Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=139201&r1=139200&r2=139201&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Tue Sep 6 17:59:55 2011 @@ -94,8 +94,8 @@ m_is_bitfield_for_scalar(false), m_is_expression_path_child(false), m_is_child_at_offset(false), - m_dump_printable_counter(0), - m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid) + m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), + m_trying_summary_already(false) { m_manager->ManageObject(this); } @@ -140,8 +140,8 @@ m_is_bitfield_for_scalar(false), m_is_expression_path_child(false), m_is_child_at_offset(false), - m_dump_printable_counter(0), - m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type) + m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), + m_trying_summary_already(false) { m_manager = new ValueObjectManager(); m_manager->ManageObject (this); @@ -241,30 +241,21 @@ if (HasCustomSummaryFormat() && m_update_point.GetModID() != m_user_id_of_forced_summary) { ClearCustomSummaryFormat(); - m_summary_str.clear(); + any_change = true; } + if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) || m_last_format_mgr_dynamic != use_dynamic) { - if (m_last_summary_format.get()) - m_last_summary_format.reset((StringSummaryFormat*)NULL); - if (m_last_value_format.get()) - m_last_value_format.reset(/*(ValueFormat*)NULL*/); - if (m_last_synthetic_filter.get()) - m_last_synthetic_filter.reset(/*(SyntheticFilter*)NULL*/); - - m_synthetic_value = NULL; - - any_change = true; - DataVisualization::ValueFormats::Get(*this, eNoDynamicValues, m_last_value_format); - DataVisualization::GetSummaryFormat(*this, use_dynamic, m_last_summary_format); - DataVisualization::GetSyntheticChildren(*this, use_dynamic, m_last_synthetic_filter); + SetValueFormat(DataVisualization::ValueFormats::Get(*this, eNoDynamicValues)); + SetSummaryFormat(DataVisualization::GetSummaryFormat(*this, use_dynamic)); + SetSyntheticChildren(DataVisualization::GetSyntheticChildren(*this, use_dynamic)); m_last_format_mgr_revision = DataVisualization::GetCurrentRevision(); m_last_format_mgr_dynamic = use_dynamic; - - ClearUserVisibleData(); + + any_change = true; } return any_change; @@ -1122,8 +1113,6 @@ Format custom_format) { - RefCounter ref(&m_dump_printable_counter); - if (custom_format != eFormatInvalid) SetFormat(custom_format); @@ -1136,8 +1125,15 @@ return_value = GetValueAsCString(); break; case eDisplaySummary: - return_value = GetSummaryAsCString(); - break; + if (m_trying_summary_already) + return_value = NULL; + else + { + m_trying_summary_already = true; + return_value = GetSummaryAsCString(); + m_trying_summary_already = false; + break; + } case eDisplayLanguageSpecific: return_value = GetObjectDescription(); break; @@ -1159,20 +1155,17 @@ break; } - // this code snippet might lead to endless recursion, thus we use a RefCounter here to - // check that we are not looping endlessly - if (!return_value && (m_dump_printable_counter < 3)) + if (!return_value) { - // try to pick the other choice if (val_obj_display == eDisplayValue) - return_value = GetSummaryAsCString(); + return_value = GetSummaryAsCString(); else if (val_obj_display == eDisplaySummary) { if (ClangASTContext::IsAggregateType (GetClangType()) == true) { // this thing has no value, and it seems to have no summary // some combination of unitialized data and other factors can also - // raise this condition, so let's print a nice generic error message + // raise this condition, so let's print a nice generic description { alloc_mem.resize(684); return_value = &alloc_mem[0]; @@ -3704,6 +3697,7 @@ m_value_str.clear(); m_summary_str.clear(); m_object_desc_str.clear(); + m_trying_summary_already = false; } SymbolContextScope * From johnny.chen at apple.com Tue Sep 6 19:09:23 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 07 Sep 2011 00:09:23 -0000 Subject: [Lldb-commits] [lldb] r139209 - /lldb/trunk/tools/debugserver/source/RNBRemote.cpp Message-ID: <20110907000923.D4C412A6C12C@llvm.org> Author: johnny Date: Tue Sep 6 19:09:23 2011 New Revision: 139209 URL: http://llvm.org/viewvc/llvm-project?rev=139209&view=rev Log: Minor change: compare the return val of DNBWatchpointSet() against INVALID_NUB_WATCH_ID to determine its validity. Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=139209&r1=139208&r2=139209&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue Sep 6 19:09:23 2011 @@ -2927,10 +2927,10 @@ } else { - // We do NOT already have a breakpoint at this address, So lets + // We do NOT already have a watchpoint at this address, So lets // create one. nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware); - if (watch_id != INVALID_NUB_BREAK_ID) + if (watch_id != INVALID_NUB_WATCH_ID) { // We successfully created a watchpoint, now lets full out // a ref count structure with the watch_id and add it to our From johnny.chen at apple.com Wed Sep 7 14:03:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Wed, 07 Sep 2011 19:03:50 -0000 Subject: [Lldb-commits] [lldb] r139246 - in /lldb/trunk/tools/debugserver/source: MacOSX/MachThreadList.cpp RNBRemote.cpp Message-ID: <20110907190350.45F722A6C12C@llvm.org> Author: johnny Date: Wed Sep 7 14:03:50 2011 New Revision: 139246 URL: http://llvm.org/viewvc/llvm-project?rev=139246&view=rev Log: Add logic to MachThreadList::GetThreadID() for the use case of setting a watchpoint (MachThreadList::EnableHardwareWatchpoint()) where the watchpoint is not associated with a thread and the current thread, if set, is returned, otherwise we return the first thread. Plus minor change to RNBRemote::HandlePacket_z() to use the existing macros to check the validity of break_id/watch_id. Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp lldb/trunk/tools/debugserver/source/RNBRemote.cpp Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=139246&r1=139245&r2=139246&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Wed Sep 7 14:03:50 2011 @@ -99,14 +99,26 @@ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex); MachThreadSP thread_sp; const size_t num_threads = m_threads.size(); - for (size_t idx = 0; idx < num_threads; ++idx) + if (MachThread::ThreadIDIsValid(tid)) { - if (m_threads[idx]->ThreadID() == tid) + for (size_t idx = 0; idx < num_threads; ++idx) { - thread_sp = m_threads[idx]; - break; + if (m_threads[idx]->ThreadID() == tid) + { + thread_sp = m_threads[idx]; + break; + } } } + else if (num_threads > 0) + { + // See DNBWatchpointSet() -> MachProcess::CreateWatchpoint() -> MachProcess::EnableWatchpoint() + // -> MachThreadList::EnableHardwareWatchpoint() for a use case of this branch. + if (m_current_thread) + thread_sp = m_current_thread; + else + thread_sp = m_threads[0]; + } return thread_sp; } Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=139246&r1=139245&r2=139246&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original) +++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Wed Sep 7 14:03:50 2011 @@ -2885,7 +2885,7 @@ // We do NOT already have a breakpoint at this address, So lets // create one. nub_break_t break_id = DNBBreakpointSet (pid, addr, byte_size, hardware); - if (break_id != INVALID_NUB_BREAK_ID) + if (NUB_BREAK_ID_IS_VALID(break_id)) { // We successfully created a breakpoint, now lets full out // a ref count structure with the breakID and add it to our @@ -2930,7 +2930,7 @@ // We do NOT already have a watchpoint at this address, So lets // create one. nub_watch_t watch_id = DNBWatchpointSet (pid, addr, byte_size, watch_flags, hardware); - if (watch_id != INVALID_NUB_WATCH_ID) + if (NUB_WATCH_ID_IS_VALID(watch_id)) { // We successfully created a watchpoint, now lets full out // a ref count structure with the watch_id and add it to our From granata.enrico at gmail.com Wed Sep 7 14:20:42 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Wed, 07 Sep 2011 19:20:42 -0000 Subject: [Lldb-commits] [lldb] r139249 - /lldb/trunk/www/varformats.html Message-ID: <20110907192042.9FCAA2A6C12C@llvm.org> Author: enrico Date: Wed Sep 7 14:20:42 2011 New Revision: 139249 URL: http://llvm.org/viewvc/llvm-project?rev=139249&view=rev Log: documentation changes (WIP) Modified: lldb/trunk/www/varformats.html Modified: lldb/trunk/www/varformats.html URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=139249&r1=139248&r2=139249&view=diff ============================================================================== --- lldb/trunk/www/varformats.html (original) +++ lldb/trunk/www/varformats.html Wed Sep 7 14:20:42 2011 @@ -21,34 +21,27 @@

Usually, when you type frame variable or run some expression LLDB will - automatically choose a format to display your results on + automatically choose the way to display your results on a per-type basis, as in the following example:

-

(lldb) frame variable -T sp
- (SimpleWithPointers) sp = {
-     (int *) x = 0x0000000100100120
-     (float *) y = - 0x0000000100100130
-     (char *) z = - 0x0000000100100140 "3"
- }
+

(lldb) frame variable
+ (uint8_t) x = 'a'
+ (intptr_t) y = 124752287

However, in certain cases, you may want to associate a - different format to the display for certain datatypes. + different style to the display for certain datatypes. To do so, you need to give hints to the debugger as to - how datatypes should be displayed.
+ how variables should be displayed.
A new type command has been introduced in LLDB which allows to do just that.

-

Using it you can obtain a format like this one for sp, - instead of the default shown above:

+

Using it you can change your visualization to look like this:

-

(lldb) frame variable sp
- (SimpleWithPointers) sp = - (x=0x0000000100100120 -> -1, y=0x0000000100100130 - -> -2, z="3")
+

(lldb) frame variable
+ (uint8_t) x = chr='a' dec=65 hex=0x41
+ (intptr_t) y = 0x76f919f

There are several features related to data visualization: This is done by typing
- (lldb) type format add -f hex int + (lldb) type format add --format hex int
at the LLDB command line.

-

The -f option accepts a format name, and a list of +

The --format (which you can shorten to -f) option accepts a format name. Then, you provide one or more types to which you want the new format applied.

A frequent scenario is that your program has a typedef @@ -125,20 +118,28 @@

and you want to show all A's as hex, all - C's as pointers and leave the defaults + C's as byte arrays and leave the defaults untouched for other types.

If you simply type

(lldb) type format add -f hex A
- (lldb) type format add -f pointer C + (lldb) type format add -f uint8_t[] C

values of type B will be shown as hex - and values of type D as pointers.

+ and values of type D as byte arrays, as in:

+

+ (lldb) frame variable -T
+ (A) a = 0x00000001
+ (B) b = 0x00000002
+ (C) c = {0x03 0x00 0x00 0x00}
+ (D) d = {0x04 0x00 0x00 0x00}
+

+

This is because by default LLDB cascades formats through typedef chains. In order to avoid that you can use the option -C no to prevent @@ -147,12 +148,21 @@

(lldb) type format add -C no -f hex A
- (lldb) type format add -C no -f pointer C + (lldb) type format add -C no -f uint8_t[] C
- + +

which provides the desired output:

+

+ (lldb) frame variable -T
+ (A) a = 0x00000001
+ (B) b = 2
+ (C) c = {0x03 0x00 0x00 0x00}
+ (D) d = 4
+

+

Two additional options that you will want to look at - are -p and -r. These two + are --skip-pointers (-p) and --skip-references (-r). These two options prevent LLDB from applying a format for type T to values of type T* and T& respectively.

@@ -168,15 +178,22 @@ (int) *pointer = {1.53302e-42}

-

As the previous example highlights, you will most - probably want to use -p for your formats.

+

While they can be applied to pointers and references, formats will make no attempt + to dereference the pointer and extract the value before applying the format, which means you + are effectively formatting the address stored in the pointer rather than the pointee value. + For this reason, you may want to use the -p option when defining formats.

If you need to delete a custom format simply type type format delete followed by the name of the type - to which the format applies. To delete ALL formats, use - type format clear. To see all the formats - defined, type type format list.
+ to which the format applies.Even if you + defined the same format for multiple types on the same command, + type format delete will only remove the format for + the type name passed as argument.

+

+ To delete ALL formats, use + type format clear. To see all the formats + defined, use type format list.

If all you need to do, however, is display one variable in a custom format, while leaving the others of the same @@ -392,9 +409,9 @@

before adding a summary...
(lldb) frame variable -T one
(i_am_cool) one = {
-     (int) integer = 3
-     (float) floating = 3.14159
-     (char) character = 'E'
+     (int) x = 3
+     (float) y = 3.14159
+     (char) z = 'E'
}

after adding a summary...
@@ -403,13 +420,13 @@

There are two ways to use type summaries: the first one is to bind a - summary string to the datatype; the second is to bind a Python script to the - datatype. Both options are enabled by the type summary add + summary string to the type; the second is to write a Python script that returns + the string to be used as summary. Both options are enabled by the type summary add command.

The command to obtain the output shown in the example is:

- (lldb) type summary add --summary-string "int = ${var.integer}, float = ${var.floating}, char = ${var.character%u}" i_am_cool + (lldb) type summary add --summary-string "int = ${var.x}, float = ${var.y}, char = ${var.z%u}" i_am_cool
@@ -421,36 +438,34 @@

Summary Strings

-

While you may already have guessed a lot about the format of - summary strings from the above example, a detailed description - of their format follows.

+

Summary strings are written using a simple control language, exemplified by the snippet above. + A summary string contains a sequence of tokens that are processed by LLDB to generate the summary.

Summary strings can contain plain text, control characters and - special symbols that have access to information about + special variables that have access to information about the current object and the overall program state.

-

Normal characters are any text that doesn't contain a '{', +

Plain text is any sequence of characters that doesn't contain a '{', '}', '$', or '\' - character.

-

Variable names are found in between a "${" + character, which are the syntax control characters.

+

The special variables are found in between a "${" prefix, and end with a "}" suffix. Variables can be a simple name or they can refer to complex objects that have subitems themselves. In other words, a variable looks like "${object}" or "${object.child.otherchild}". A variable can also be prefixed or suffixed with other symbols meant to change the way its value is handled. An example is "${*var.int_pointer[0-3]}".

-

Basically, all the variables described in Basically, the syntax is the same one described Frame and Thread Formatting - are accepted. Also acceptable are the control characters - and scoping features described in that page. - Additionally, ${var and ${*var - become acceptable symbols in this scenario. These special symbols - are used to refer to the variable that a summary is being created for.

+ are accepted. + Beyond what's described there, additional symbols have become available + in the syntax for summary strings. The main of them is ${var, + which is used refer to the variable that a summary is being created for.

The simplest thing you can do is grab a member variable of a class or structure by typing its expression path. In the previous example, the expression path - for the floating member is simply .floating. - Thus, to ask the summary string to display floating - you would type ${var.floating}.

+ for the field float y is simply .y. + Thus, to ask the summary string to display y + you would type ${var.y}.

If you have code like the following:
struct A {
    int x;
@@ -466,8 +481,8 @@ type B would be .x.y and you would type ${var.x.y} to display it in a summary string for type B.

-

By default, summary strings work for both type T and - type T* (there is an option to prevent this if you need to). +

By default, a summary defined for type T, also works for types + T* and T& (you can disable this behavior if desired). For this reason, expression paths do not differentiate between . and ->, and the above expression path .x.y would be just as good if you were displaying a B*, @@ -553,67 +568,49 @@ tells LLDB not to look for a summary string, but instead to just print a listing of all the object's children on one line.

-

As an example, given a type Couple: +

As an example, given a type pair:
- (lldb) frame variable --show-types a_couple
- (Couple) a_couple = {
-     (SimpleWithPointers) sp = {
-         (int *) x = 0x00000001001000b0
-         (float *) y = 0x00000001001000c0
-         (char *) z = 0x00000001001000d0 "X"
-     }
-     (Simple *) s = 0x00000001001000e0
+ (lldb) frame variable --show-types a_pair
+ (pair) a_pair = {
+     (int) first = 1;
+     (int) second = 2;
}

If one types the following commands:

- (lldb) type summary add --summary-string "int = ${*var.sp.x}, - float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple = - ${var.s}" Couple
- (lldb) type summary add -c Simple
+ (lldb) type summary add --inline-children pair
the output becomes:
- (lldb) frame variable a_couple
- (Couple) a_couple = int = 9, float = 9.99, char = 88, Simple - = (x=9, y=9.99, z='X')
+ (lldb) frame variable a_pair
+ (pair) a_pair = (first=1, second=2)

-

Using the above summary for type Couple, without providing a summary for type Simple - would lead LLDB to display the address of the Simple object, as in: -
- - (lldb) frame variable a_couple
- (Couple) a_couple = int = 9, float = 9.99, char = 88, Simple - = Simple @ 0x00007fff5fbff940
-

- This happens because Simple is an aggregate type, so it has no value of its own to display, - but it has no summary defined. Thus, LLDB picks a reasonable default summary and displays it. If you want to reproduce - that summary, the summary string to use is ${var%T} @ ${var%L}. -

Bitfields and array syntax

Sometimes, a basic type's value actually represents - several different values packed together in a bitfield. + several different values packed together in a bitfield.
With the classical view, there is no way to look at them. Hexadecimal display can help, but if the bits - actually span byte boundaries, the help is limited. + actually span nibble boundaries, the help is limited.
Binary view would show it all without ambiguity, but is often too detailed and hard to read for real-life - scenarios. To cope with the issue, LLDB supports native + scenarios. +

+ To cope with the issue, LLDB supports native bitfield formatting in summary strings. If your expression paths leads to a so-called scalar type (the usual int, float, char, double, short, long, long long, double, long double and unsigned variants), you can ask LLDB to only grab some bits out of the value and - display them in any format you like. The syntax is - similar to that used for arrays, just you can also give - a pair of indices separated by a -.
- e.g.
+ display them in any format you like. If you only need one bit + you can use the [n], just like + indexing an array. To extract multiple bits, you can use + a slice-like syntax: [n-m], e.g.

(lldb) frame variable float_point
(float) float_point = -3.14159

@@ -622,7 +619,7 @@ Exponent: ${var[30-23]%x} Mantissa: ${var[0-22]%u}" float -

+

(lldb) frame variable float_point
@@ -632,11 +629,8 @@ representation of a float variable by extracting bitfields out of a float object.

-

As far as the syntax is concerned, it looks - much like the normal C array syntax, but also allows you - to specify 2 indices, separated by a - symbol (a range). - Ranges can be given either with the lower or the higher index - first, and range extremes are always included in the bits extracted.

+

When typing a range, the extremes n and m are always + included, and the order of the indices is irrelevant.

LLDB also allows to use a similar syntax to display array members inside a summary string. For instance, you @@ -705,10 +699,11 @@ (lldb) frame variable sarray
(Simple [3]) sarray = [4,7]

-

The same logic works if you are printing a pointer - instead of an array, however in this latter case, the empty - square brackets operator [] - cannot be used and you need to give exact range limits.

+

If you are dealing with a pointer that you know is an array, you can use this + syntax to display the elements contained in the pointed array instead of just + the pointer value. However, because pointers have no notion of their size, the + empty brackets [] operator does not work, and you must explicitly provide + higher and lower bounds.

In general, LLDB needs the square brackets operator [] in order to handle arrays and pointers correctly, and for pointers it also @@ -791,7 +786,7 @@

Summary strings are effective to reduce the screen real estate used by the default viewing mode, but are not effective if we want to display the - area, perimeter and length of diagonal of Rectangle objects

+ area and perimeter of Rectangle objects

To obtain this, we can simply attach a small Python script to the Rectangle class, as shown in this example:

@@ -803,32 +798,19 @@ def function (valobj,dict):
    height_val = valobj.GetChildMemberWithName('height')
    width_val = valobj.GetChildMemberWithName('width')
-     height_str = height_val.GetValue()
-     width_str = width_val.GetValue()
-     height = int(height_str)
-     width = int(width_str)
+     height = height_val.GetValueAsUnsigned(0)
+     width = width_val.GetValueAsUnsigned(0)
    area = height*width
-     perimeter = 2*height + 2*width
-     diag = sqrt(height*height+width*width)
-     return 'Area: ' + str(area) + ', Perimeter: ' + str(perimeter) + ', Diagonal: ' + str(diag)
+     perimeter = 2*(height + width)
+     return 'Area: ' + str(area) + ', Perimeter: ' + str(perimeter)
    DONE
-(lldb) script
-Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
->>> from math import sqrt
->>> quit()
(lldb) frame variable
-(Rectangle) r1 = Area: 20, Perimeter: 18, Diagonal: 6.40312423743
-(Rectangle) r2 = Area: 72, Perimeter: 36, Diagonal: 13.416407865
-(Rectangle) r3 = Area: 16, Perimeter: 16, Diagonal: 5.65685424949
+(Rectangle) r1 = Area: 20, Perimeter: 18
+(Rectangle) r2 = Area: 72, Perimeter: 36
+(Rectangle) r3 = Area: 16, Perimeter: 16
-

In this scenario, you need to enter the interactive interpreter to import the - function sqrt() from the math library. As the example shows, everything you enter - into the interactive interpreter is saved for you to use it in scripts. This way - you can define your own utility functions and use them in your summary scripts if - necessary.

-

In order to write effective summary scripts, you need to know the LLDB public API, which is the way Python code can access the LLDB object model. For further details on the API you should look at this page, or at @@ -839,11 +821,12 @@

dict is an internal support parameter used by LLDB and you should not use it.
valobj is the object encapsulating the actual - variable being displayed, and its type is SBValue. The most important thing you can - do with an SBValue is retrieve its children objects, by calling - GetChildMemberWithName(), passing it the child's name as a string, or ask - it for its value, by calling GetValue(), which returns a Python string. -

+ variable being displayed, and its type is SBValue. + Out of the many possible operations on an SBValue, the basic one is retrieve the children objects + it contains (essentially, the fields of the object wrapped by it), by calling + GetChildMemberWithName(), passing it the child's name as a string.
+ If the variable has a value, you can ask for it, and return it as a string using GetValue(), + or as a signed/unsigned number using GetValueAsSigned(), GetValueAsUnsigned().

If you need to delve into several levels of hierarchy, as you can do with summary strings, you can use the method GetValueForExpressionPath(), passing it @@ -851,7 +834,7 @@ is that dereferencing a pointer does not occur by prefixing the path with a *, but by calling the Dereference() method on the returned SBValue). If you need to access array slices, you cannot do that (yet) via this method call, and you must - use GetChildMemberWithName() querying it for the array items one by one. + use GetChildAtIndex() querying it for the array items one by one. Also, handling custom formats is something you have to deal with on your own.

Other than interactively typing a Python script there are two other ways for you @@ -873,7 +856,7 @@

  • using the --python-function (-F) option to type summary add and giving the name of a Python function with the correct prototype. Most probably, you will define (or have already defined) the function in the interactive interpreter, or somehow - loaded it from a file. + loaded it from a file, using the script import command.

    @@ -932,14 +915,14 @@

    Named summaries

    -

    For a given datatype, there may be different meaningful summary +

    For a given type, there may be different meaningful summary representations. However, currently, only one summary can be associated - to a given datatype. If you need to temporarily override the association - for a variable, without changing the summary string bound to the datatype, + to a type at each moment. If you need to temporarily override the association + for a variable, without changing the summary string for to its type, you can use named summaries.

    -

    Named summaries work by attaching a name to a summary string when creating - it. Then, when there is a need to attach the summary string to a variable, the +

    Named summaries work by attaching a name to a summary when creating + it. Then, when there is a need to attach the summary to a variable, the frame variable command, supports a --summary option that tells LLDB to use the named summary given instead of the default one.

    @@ -977,7 +960,7 @@ When that's the case, expression paths do not work correctly.

    In other cases, the internals are available to use in expression paths, but they do not provide a user-friendly representation of the object's value.

    -

    For instance, consider an STL vector:

    +

    For instance, consider an STL vector, as implemented by the GNU C++ Library:

    (lldb) frame variable numbers -T
    (std::vector<int>) numbers = {
    @@ -1007,31 +990,33 @@ available by default through the debug information. In the example, we can use synthetic children to provide the vector items as children for the std::vector object.

    In order to create synthetic children, you need to provide a Python class that adheres to a given interface - (the word is italicized because Python has no explicit notion of interface. By that word we mean a given set of methods + (the word is italicized because Python has no explicit notion of interface, by that word we mean a given set of methods must be implemented by the Python class):

    class SyntheticChildrenProvider:
        def __init__(self, valobj, dict):
    -         this call should initialize the Python object using valobj as the variable to provide synthetic children for
    +         this call should initialize the Python object using valobj as the variable to provide synthetic children for
        def num_children(self):
    -         this call should return the number of children that you want your object to have
    +         this call should return the number of children that you want your object to have
        def get_child_index(self,name):
    -         this call should return the index of the synthetic child whose name is given as argument
    +         this call should return the index of the synthetic child whose name is given as argument
        def get_child_at_index(self,index):
    -         this call should return a new LLDB SBValue object representing the child at the index given as argument
    +         this call should return a new LLDB SBValue object representing the child at the index given as argument
        def update(self):
    -         this call should be used to update the internal state of this Python object whenever the state of the variables in LLDB changes. - Currently this method is optional, because the internal state of synthetic children providers will not be preserved. However, this is meant to change in future versions - of LLDB.
    +         this call should be used to update the internal state of this Python object whenever the state of the variables in LLDB changes.[1]
    +[1] Currently this method is optional, because the internal state of synthetic children providers will not be preserved. However, this is meant to change in future versions of LLDB.

    For examples of how synthetic children are created, you are encouraged to look at examples/synthetic in the LLDB trunk. You may especially want to begin looking at StdVector to get - a feel for this feature.

    + a feel for this feature, as it is a relatively easy and well commented example.

    While the update method is optional, the design pattern consistently used in synthetic providers shipping with LLDB is to use the __init__ to store the SBValue instance as a part of self, and then call update - to perform the actual initialization. This pattern should make transition to a future version of LLDB that persists synthetic children - providers transparent.

    - + to perform the actual initialization. This pattern should make for a transparent transition to a future version of LLDB that persists synthetic children. For example:

    + + def __init__(self, valobj, dict):
    +     self.valobj = valobj;
    +     self.update() +

    Once a synthetic children provider is written, one must load it into LLDB before it can be used. Currently, one can use the LLDB script command to type Python code interactively, or use the script import module command to load Python code from a Python module @@ -1058,15 +1043,15 @@

    Currently, in LLDB top of tree, synthetic children providers are enabled for std::vector<T>, std::list<T> and std::map<K,V>.

    -

    Synthetic children enable a new symbol for summary strings, ${svar. This symbol tells LLDB to refer expression paths to the - synthetic children instead of the real ones. While in certain cases, you can use ${var.synthetic-child-path} and LLDB will - access the synthetic child correctly, it is best to always use ${svar to refer to synthetic children. For instance,

    +

    Synthetic children extend summary strings by enabling a new special variable: ${svar.
    + This symbol tells LLDB to refer expression paths to the + synthetic children instead of the real ones. For instance,

    -
    (lldb) type summary add --expand -x "std::vector<" --summary-string "${svar%#} items"
    +
    (lldb) frame variable numbers
    (std::vector<int>) numbers = 4 items {
        (int) [0] = 1
    @@ -1075,7 +1060,21 @@     (int) [3] = 1234
    }

    - +

    In some cases, if LLDB is unable to use the real object to get a child specified in an expression path, it will automatically refer to the + synthetic children. While in summaries it is best to always use ${svar to make your intentions clearer, interactive debugging + can benefit from this behavior, as in: + (lldb) frame variable numbers[0] numbers[1]
    + (int) numbers[0] = 1
    + (int) numbers[1] = 12
    +

    + Unlike many other visualization features, however, the access to synthetic children only works when using frame variable, and is + not supported in expression:
    + (lldb) expression numbers[0]
    + Error [IRForTarget]: Call to a function '_ZNSt33vector<int, std::allocator<int> >ixEm' that is not present in the target
    + error: Couldn't convert the expression to DWARF
    +

    + The reason for this is that classes might have an overloaded operator [], or other special provisions + and the expression command ignores synthetic children when evaluating its arguments.
    @@ -1110,9 +1109,9 @@

    Objective-C dynamic type discovery

    When doing Objective-C development, you may notice that some of your variables - come out as of type id. While this does not influence the ability - of the runtime to send messages to them, it can make it impossible for LLDB - to determine the actual formatters for that object.

    + come out as of type id (for instance, items extracted from NSArray). + While this does not influence the ability of the runtime to send messages to them, it could make it impossible for LLDB + to determine the actual formatters for that object, given its type-based algorithm.

    The debugger, however, can dynamically discover the type of an Objective-C variable, much like the runtime itself does when invoking a selector. In order to let LLDB do that, however, a special option to frame variable is From granata.enrico at gmail.com Wed Sep 7 19:50:01 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Thu, 08 Sep 2011 00:50:01 -0000 Subject: [Lldb-commits] [lldb] r139271 - /lldb/trunk/www/varformats.html Message-ID: <20110908005001.8DFBD2A6C12C@llvm.org> Author: enrico Date: Wed Sep 7 19:50:01 2011 New Revision: 139271 URL: http://llvm.org/viewvc/llvm-project?rev=139271&view=rev Log: other documentation changes Modified: lldb/trunk/www/varformats.html Modified: lldb/trunk/www/varformats.html URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=139271&r1=139270&r2=139271&view=diff ============================================================================== --- lldb/trunk/www/varformats.html (original) +++ lldb/trunk/www/varformats.html Wed Sep 7 19:50:01 2011 @@ -50,7 +50,7 @@ style="font-style: italic;">filters, synthetic children.

    -

    To reflect this, the the type command has four +

    To reflect this, the type command has four subcommands:

    @@ -84,7 +84,7 @@

    Type formats enable you to quickly override the default format for displaying primitive types (the usual basic - C/C++/ObjC types: int, float, char, ...).

    + C/C++/ObjC types: int, float, char, ...).

    If for some reason you want all int variables in your program to print out as hex, you can add @@ -111,15 +111,16 @@

    But things can quickly get hierarchical. Let's say you have a situation like the following:

    -

    typedef int A;
    - typedef A B;
    - typedef B C;
    - typedef C D;
    +

    typedef int A;
    + typedef A B;
    + typedef B C;
    + typedef C D;

    and you want to show all A's as hex, all C's as byte arrays and leave the defaults - untouched for other types.

    + untouched for other types (albeit its contrived look, the example is far + from unrealistic in large software systems).

    If you simply type
    @@ -181,7 +182,7 @@

    While they can be applied to pointers and references, formats will make no attempt to dereference the pointer and extract the value before applying the format, which means you are effectively formatting the address stored in the pointer rather than the pointee value. - For this reason, you may want to use the -p option when defining formats.

    + For this reason, you may want to use the -p option when defining formats.

    If you need to delete a custom format simply type type format delete followed by the name of the type @@ -467,14 +468,14 @@ Thus, to ask the summary string to display y you would type ${var.y}.

    If you have code like the following:
    - struct A {
    -     int x;
    -     int y;
    + struct A {
    +     int x;
    +     int y;
    };
    - struct B {
    + struct B {
        A x;
        A y;
    -     int *z;
    +     int *z;
    };
    the expression path for the y member of the x member of an object of @@ -488,10 +489,10 @@ would be just as good if you were displaying a B*, or even if the actual definition of B were:
    - struct B {
    + struct B {
        A *x;
        A y;
    -     int *z;
    +     int *z;
    };

    This is unlike the behavior of frame variable @@ -587,6 +588,15 @@ (lldb) frame variable a_pair
    (pair) a_pair = (first=1, second=2)

    + + Of course, one can obtain the same effect by typing +
    + +
    + (lldb) type summary add pair --summary-string "(first=${var.first}, second=${var.second})"
    +
    + + While the final result is the same, using --inline-children can often save time.
    @@ -768,18 +778,18 @@ values. As a small example, let's say we have a Rectangle class:

    -class Rectangle
    +class Rectangle
    {
    -private:
    -     int height;
    -     int width;
    -public:
    +private:
    +     int height;
    +     int width;
    +public:
        Rectangle() : height(3), width(5) {}
    -     Rectangle(int H) : height(H), width(H*2-1) {}
    -     Rectangle(int H, int W) : height(H), width(W) {}
    +     Rectangle(int H) : height(H), width(H*2-1) {}
    +     Rectangle(int H, int W) : height(H), width(W) {}
    -     int GetHeight() { return height; }
    -     int GetWidth() { return width; }
    +     int GetHeight() { return height; }
    +     int GetWidth() { return width; }
    };
    @@ -856,7 +866,9 @@
  • using the --python-function (-F) option to type summary add and giving the name of a Python function with the correct prototype. Most probably, you will define (or have already defined) the function in the interactive interpreter, or somehow - loaded it from a file, using the script import command. + loaded it from a file, using the script import command. LLDB will not make any attempt at determining whether + the function is defined and syntactically correct, until you try to call it. Any errors will be shown at that stage, as if + you were executing your function inside the Python interactive interpreter itself.

    @@ -904,7 +916,14 @@

    One of the ways LLDB uses this feature internally, is to match the names of STL container classes, regardless of the template arguments provided (e.g. std::vector<T> for any - type argument T).

    + type argument T). The regular expressions used for this are: +

    +
      +
    • ^(std::)?vector<.+>$ for std::vector<T>
    • +
    • ^(std::)?list<.+>$ for std::list<T>
    • +
    • ^(std::)?map<.+> >$ for std::map<K,V>
    • +
    + As you can see, the actual template arguments are ignored by the regular expression.

    The regular expression language used by LLDB is the POSIX extended language, as defined by the Single UNIX Specification, of which Mac OS X is a compliant implementation. @@ -1167,10 +1186,11 @@ and can be enabled using the type category enable command. To disable an enabled category, the command to use is type category disable. The order in which categories are enabled or disabled is significant, in that LLDB uses that order when looking for formatters. Therefore, when you enable a category, it becomes - the first one to be searched. The default categories are enabled in the order: default as first, then - gnu-libstdc++, and finally system. As said, gnu-libstdc++ contains formatters for C++ STL - data types. system contains formatters for char* and char[], which are expected to be - consistent throughout libraries and systems, and replace

    + the first one to be searched. The default categories are enabled in such a way that the search order is: default + then gnu-libstdc++ then finally system. As said, gnu-libstdc++ contains formatters for C++ STL + data types. system contains formatters for char* and char[], which reflect the behavior + of previous versions of LLDB which had built-in formatters for these types. Because now these are formatters, you can even + replace them with your own if so you wish.

    There is no special command to create a category. When you place a formatter in a category, if that category does not exist, it is automatically created. For instance,

  • @@ -1209,7 +1229,7 @@ for the pointee type that does not skip pointers, use it
  • If this object is a reference, and there is a - summary for the referred type that does not skip + formatter for the referred type that does not skip references, use it
  • If this object is an Objective-C class with a parent class, look at the parent class (and parent of parent, From jingham at apple.com Wed Sep 7 20:15:10 2011 From: jingham at apple.com (Jim Ingham) Date: Thu, 08 Sep 2011 01:15:10 -0000 Subject: [Lldb-commits] [lldb] r139273 - /lldb/trunk/source/Commands/CommandObjectFrame.cpp Message-ID: <20110908011510.0CCE52A6C12D@llvm.org> Author: jingham Date: Wed Sep 7 20:15:09 2011 New Revision: 139273 URL: http://llvm.org/viewvc/llvm-project?rev=139273&view=rev Log: "frame select -r" should return an error if you are already at the top of the stack & try to go up or at the bottom and try to go down. Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=139273&r1=139272&r2=139273&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Wed Sep 7 20:15:09 2011 @@ -205,14 +205,34 @@ if (frame_idx >= -m_options.relative_frame_offset) frame_idx += m_options.relative_frame_offset; else - frame_idx = 0; + { + if (frame_idx == 0) + { + //If you are already at the bottom of the stack, then just warn and don't reset the frame. + result.AppendError("Already at the bottom of the stack"); + result.SetStatus(eReturnStatusFailed); + return false; + } + else + frame_idx = 0; + } } else if (m_options.relative_frame_offset > 0) { if (num_frames - frame_idx > m_options.relative_frame_offset) frame_idx += m_options.relative_frame_offset; else - frame_idx = num_frames - 1; + { + if (frame_idx == num_frames - 1) + { + //If we are already at the top of the stack, just warn and don't reset the frame. + result.AppendError("Already at the top of the stack"); + result.SetStatus(eReturnStatusFailed); + return false; + } + else + frame_idx = num_frames - 1; + } } } else From johnny.chen at apple.com Wed Sep 7 20:16:50 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 01:16:50 -0000 Subject: [Lldb-commits] [lldb] r139274 - in /lldb/trunk/tools/debugserver/source/MacOSX: i386/DNBArchImplI386.cpp i386/DNBArchImplI386.h x86_64/DNBArchImplX86_64.cpp x86_64/DNBArchImplX86_64.h Message-ID: <20110908011651.03DED2A6C12C@llvm.org> Author: johnny Date: Wed Sep 7 20:16:50 2011 New Revision: 139274 URL: http://llvm.org/viewvc/llvm-project?rev=139274&view=rev Log: Add logic to the DNBArchImplX86_64/DNBArchImplI386::NotifyException() callback method in order to distinguish the real single step exception from a watchpoint exception which uses the same exc_type of EXC_BREAKPOINT and exc_code of EXC_I386_SGL. This is done by checking the debug status register to find out whether the watchpoint data break event has fired, and, if yes, stuff the data break address into the exception's exc_sub_code field on the debugserver side for lldb to consume on the other end. Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=139274&r1=139273&r2=139274&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Wed Sep 7 20:16:50 2011 @@ -625,6 +625,19 @@ return true; } } + else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) + { + // exc_code = EXC_I386_SGL + // + // Check whether this corresponds to a watchpoint hit event. + // If yes, set the exc_sub_code to the data break address. + nub_addr_t addr = 0; + uint32_t hw_index = GetHardwareWatchpointHit(addr); + if (hw_index != INVALID_NUB_HW_INDEX) + exc.exc_data[1] = addr; + + return true; + } break; case EXC_SYSCALL: break; @@ -636,29 +649,6 @@ return false; } -// Iterate through the debug status register; return the index of the first hit. -uint32_t -DNBArchImplI386::GetHardwareWatchpointHit() -{ - // Read the debug state - kern_return_t kret = GetDBGState(false); - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); - if (kret == KERN_SUCCESS) - { - DBG debug_state = m_state.context.dbg; - uint32_t i, num = NumSupportedHardwareWatchpoints(); - for (i = 0; i < num; ++i) - { - if (IsWatchpointHit(debug_state, i)) - { - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i); - return i; - } - } - } - return INVALID_NUB_HW_INDEX; -} - uint32_t DNBArchImplI386::NumSupportedHardwareWatchpoints() { @@ -790,6 +780,23 @@ return (debug_state.__dr6 & (1 << hw_index)); } +nub_addr_t +DNBArchImplI386::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) +{ + switch (hw_index) { + case 0: + return debug_state.__dr0; + case 1: + return debug_state.__dr1; + case 2: + return debug_state.__dr2; + case 3: + return debug_state.__dr3; + default: + assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } +} + uint32_t DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { @@ -865,6 +872,32 @@ return false; } +// Iterate through the debug status register; return the index of the first hit. +uint32_t +DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr) +{ + // Read the debug state + kern_return_t kret = GetDBGState(false); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); + if (kret == KERN_SUCCESS) + { + DBG debug_state = m_state.context.dbg; + uint32_t i, num = NumSupportedHardwareWatchpoints(); + for (i = 0; i < num; ++i) + { + if (IsWatchpointHit(debug_state, i)) + { + addr = GetWatchAddress(debug_state, i); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplI386::GetHardwareWatchpointHit() found => %u (addr = %8.8p).", + i, addr); + return i; + } + } + } + return INVALID_NUB_HW_INDEX; +} + // Set the single step bit in the processor status register. kern_return_t DNBArchImplI386::EnableHardwareSingleStep (bool enable) Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=139274&r1=139273&r2=139274&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Wed Sep 7 20:16:50 2011 @@ -54,7 +54,7 @@ virtual uint32_t NumSupportedHardwareWatchpoints(); virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); - virtual uint32_t GetHardwareWatchpointHit(); + virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: kern_return_t EnableHardwareSingleStep (bool enable); @@ -233,6 +233,7 @@ static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); static void ClearWatchpointHits(DBG &debug_state); static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); + static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); MachThread *m_thread; State m_state; Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=139274&r1=139273&r2=139274&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Wed Sep 7 20:16:50 2011 @@ -554,6 +554,19 @@ return true; } } + else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) + { + // exc_code = EXC_I386_SGL + // + // Check whether this corresponds to a watchpoint hit event. + // If yes, set the exc_sub_code to the data break address. + nub_addr_t addr = 0; + uint32_t hw_index = GetHardwareWatchpointHit(addr); + if (hw_index != INVALID_NUB_HW_INDEX) + exc.exc_data[1] = addr; + + return true; + } break; case EXC_SYSCALL: break; @@ -695,6 +708,23 @@ return (debug_state.__dr6 & (1 << hw_index)); } +nub_addr_t +DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) +{ + switch (hw_index) { + case 0: + return debug_state.__dr0; + case 1: + return debug_state.__dr1; + case 2: + return debug_state.__dr2; + case 3: + return debug_state.__dr3; + default: + assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } +} + uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { @@ -772,7 +802,7 @@ // Iterate through the debug status register; return the index of the first hit. uint32_t -DNBArchImplX86_64::GetHardwareWatchpointHit() +DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) { // Read the debug state kern_return_t kret = GetDBGState(false); @@ -785,7 +815,10 @@ { if (IsWatchpointHit(debug_state, i)) { - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i); + addr = GetWatchAddress(debug_state, i); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u (addr = %8.8p).", + i, addr); return i; } } Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=139274&r1=139273&r2=139274&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Wed Sep 7 20:16:50 2011 @@ -53,7 +53,7 @@ virtual uint32_t NumSupportedHardwareWatchpoints(); virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); - virtual uint32_t GetHardwareWatchpointHit(); + virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: kern_return_t EnableHardwareSingleStep (bool enable); @@ -240,6 +240,7 @@ static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); static void ClearWatchpointHits(DBG &debug_state); static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); + static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); MachThread *m_thread; State m_state; From johnny.chen at apple.com Thu Sep 8 12:07:22 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 17:07:22 -0000 Subject: [Lldb-commits] [lldb] r139294 - in /lldb/trunk/tools/debugserver/source/MacOSX: i386/DNBArchImplI386.cpp x86_64/DNBArchImplX86_64.cpp Message-ID: <20110908170722.5BCAA2A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 12:07:22 2011 New Revision: 139294 URL: http://llvm.org/viewvc/llvm-project?rev=139294&view=rev Log: Added comments about exception code. Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=139294&r1=139293&r2=139294&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Thu Sep 8 12:07:22 2011 @@ -603,6 +603,8 @@ case EXC_BREAKPOINT: if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) { + // exc_code = EXC_I386_BPT + // nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS); if (pc != INVALID_NUB_ADDRESS && pc > 0) { Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=139294&r1=139293&r2=139294&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Thu Sep 8 12:07:22 2011 @@ -532,6 +532,8 @@ case EXC_BREAKPOINT: if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 2) { + // exc_code = EXC_I386_BPT + // nub_addr_t pc = GetPC(INVALID_NUB_ADDRESS); if (pc != INVALID_NUB_ADDRESS && pc > 0) { From gclayton at apple.com Thu Sep 8 15:14:22 2011 From: gclayton at apple.com (Greg Clayton) Date: Thu, 08 Sep 2011 20:14:22 -0000 Subject: [Lldb-commits] [lldb] r139313 - /lldb/trunk/www/lldb-gdb.html Message-ID: <20110908201422.CC9E32A6C12C@llvm.org> Author: gclayton Date: Thu Sep 8 15:14:22 2011 New Revision: 139313 URL: http://llvm.org/viewvc/llvm-project?rev=139313&view=rev Log: Added help on stack frame selection compared to GDB and corrected the register command help to match the current LLDB. Modified: lldb/trunk/www/lldb-gdb.html Modified: lldb/trunk/www/lldb-gdb.html URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/lldb-gdb.html?rev=139313&r1=139312&r2=139313&view=diff ============================================================================== --- lldb/trunk/www/lldb-gdb.html (original) +++ lldb/trunk/www/lldb-gdb.html Thu Sep 8 15:14:22 2011 @@ -303,23 +303,104 @@ -
  • + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -328,10 +409,10 @@ From johnny.chen at apple.com Thu Sep 8 15:52:34 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 20:52:34 -0000 Subject: [Lldb-commits] [lldb] r139315 - in /lldb/trunk: include/lldb/Breakpoint/WatchpointLocationList.h include/lldb/Target/Target.h source/Plugins/Process/Utility/StopInfoMachException.cpp Message-ID: <20110908205234.916B22A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 15:52:34 2011 New Revision: 139315 URL: http://llvm.org/viewvc/llvm-project?rev=139315&view=rev Log: Watchpoint WIP: on the debugger side, create an instance of either StopInfoTrace or StopInfoWatchpoint based on the exc_sub_code, as well. Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp Modified: lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h?rev=139315&r1=139314&r2=139315&view=diff ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h (original) +++ lldb/trunk/include/lldb/Breakpoint/WatchpointLocationList.h Thu Sep 8 15:52:34 2011 @@ -19,6 +19,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" #include "lldb/Host/Mutex.h" +#include "lldb/Breakpoint/WatchpointLocation.h" namespace lldb_private { Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=139315&r1=139314&r2=139315&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 8 15:52:34 2011 @@ -279,6 +279,12 @@ lldb::BreakpointResolverSP &resolver_sp, bool internal = false); + WatchpointLocationList & + GetWatchpointLocationList() + { + return m_watchpoint_location_list; + } + void RemoveAllBreakpoints (bool internal_also = false); Modified: lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp?rev=139315&r1=139314&r2=139315&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/StopInfoMachException.cpp Thu Sep 8 15:52:34 2011 @@ -299,7 +299,14 @@ case llvm::Triple::x86_64: if (exc_code == 1) // EXC_I386_SGL { - return StopInfo::CreateStopReasonToTrace(thread); + if (!exc_sub_code) + return StopInfo::CreateStopReasonToTrace(thread); + + // It's a watchpoint, then. + lldb::WatchpointLocationSP wp_loc_sp = + thread.GetProcess().GetTarget().GetWatchpointLocationList().FindByAddress((lldb::addr_t)exc_sub_code); + if (wp_loc_sp) + return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_loc_sp->GetID()); } else if (exc_code == 2) // EXC_I386_BPT { From filcab+lldb-dev at gmail.com Thu Sep 8 16:56:49 2011 From: filcab+lldb-dev at gmail.com (Filipe Cabecinhas) Date: Thu, 8 Sep 2011 14:56:49 -0700 Subject: [Lldb-commits] Small fixes Message-ID: Hi, I've got two small fixes for lldb: One fixes a trailing comma bug (g++ doesn't like them) The other gets the Error from the result of an expression evaluation and uses it as the error for the Process::LoadImage() method. Thanks, Filipe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/19c0718b/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: trailing-comma.patch Type: application/octet-stream Size: 592 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/19c0718b/attachment.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: process-lost-error.patch Type: application/octet-stream Size: 657 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/19c0718b/attachment-0001.obj From jingham at apple.com Thu Sep 8 17:13:50 2011 From: jingham at apple.com (Jim Ingham) Date: Thu, 08 Sep 2011 22:13:50 -0000 Subject: [Lldb-commits] [lldb] r139323 - in /lldb/trunk: include/lldb/Core/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Plugins/SymbolFile/DWARF/ source/Target/ test/functionalities/breakpoint/breakpoint_command/ Message-ID: <20110908221350.BFB642A6C12C@llvm.org> Author: jingham Date: Thu Sep 8 17:13:49 2011 New Revision: 139323 URL: http://llvm.org/viewvc/llvm-project?rev=139323&view=rev Log: Move the SourceManager from the Debugger to the Target. That way it can store the per-Target default Source File & Line. Set the default Source File & line to main (if it can be found.) at startup. Selecting the current thread & or frame resets the current source file & line, and "source list" as well as the breakpoint command "break set -l " will use the current source file. Modified: lldb/trunk/include/lldb/Core/Debugger.h lldb/trunk/include/lldb/Core/SourceManager.h lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h lldb/trunk/include/lldb/Target/StackFrameList.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/source/API/SBDebugger.cpp lldb/trunk/source/API/SBSourceManager.cpp lldb/trunk/source/API/SBThread.cpp lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp lldb/trunk/source/Commands/CommandObjectSource.cpp lldb/trunk/source/Core/Debugger.cpp lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Core/SourceManager.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/trunk/source/Target/ObjCLanguageRuntime.cpp lldb/trunk/source/Target/StackFrame.cpp lldb/trunk/source/Target/StackFrameList.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadList.cpp lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py Modified: lldb/trunk/include/lldb/Core/Debugger.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Debugger.h (original) +++ lldb/trunk/include/lldb/Core/Debugger.h Thu Sep 8 17:13:49 2011 @@ -345,7 +345,11 @@ SourceManager & GetSourceManager () { - return m_source_manager; + lldb::TargetSP selected_target = GetSelectedTarget(); + if (selected_target) + return selected_target->GetSourceManager(); + else + return m_source_manager; } lldb::TargetSP @@ -458,7 +462,7 @@ TargetList m_target_list; PlatformList m_platform_list; Listener m_listener; - SourceManager m_source_manager; + SourceManager m_source_manager; // This is a scratch source manager that we return if we have no targets. std::auto_ptr m_command_interpreter_ap; InputReaderStack m_input_reader_stack; Modified: lldb/trunk/include/lldb/Core/SourceManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/SourceManager.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/SourceManager.h (original) +++ lldb/trunk/include/lldb/Core/SourceManager.h Thu Sep 8 17:13:49 2011 @@ -71,7 +71,9 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - SourceManager(); + // A source manager can be made with a non-null target, in which case it can use the path remappings to find + // source files that are not in their build locations. With no target it won't be able to do this. + SourceManager(Target *target); ~SourceManager(); @@ -84,16 +86,14 @@ } size_t - DisplaySourceLines (Target *target, - const FileSpec &file, + DisplaySourceLines (const FileSpec &file, uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s); size_t - DisplaySourceLinesWithLineNumbers (Target *target, - const FileSpec &file, + DisplaySourceLinesWithLineNumbers (const FileSpec &file, uint32_t line, uint32_t context_before, uint32_t context_after, @@ -114,12 +114,23 @@ DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *bp_locs = NULL); + bool + SetDefaultFileAndLine (const FileSpec &file_spec, uint32_t line); + + bool + GetDefaultFileAndLine (FileSpec &file_spec, uint32_t &line); + + bool + DefaultFileAndLineSet () + { + return (m_last_file_sp.get() != NULL); + } + protected: FileSP - GetFile (const FileSpec &file_spec, Target *target); + GetFile (const FileSpec &file_spec); - //------------------------------------------------------------------ // Classes that inherit from SourceManager can see and modify these //------------------------------------------------------------------ @@ -129,6 +140,7 @@ uint32_t m_last_file_line; uint32_t m_last_file_context_before; uint32_t m_last_file_context_after; + Target *m_target; private: //------------------------------------------------------------------ // For SourceManager only Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original) +++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Thu Sep 8 17:13:49 2011 @@ -99,6 +99,12 @@ static bool ParseMethodName (const char *name, ConstString *class_name, ConstString *method_name, ConstString *base_name); + static bool + IsPossibleObjCMethodName (const char *name) + { + return (name && (name[0] == '+' || name[0] == '-') && name[1] == '['); + } + protected: //------------------------------------------------------------------ // Classes that inherit from ObjCLanguageRuntime can see and modify these Modified: lldb/trunk/include/lldb/Target/StackFrameList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrameList.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StackFrameList.h (original) +++ lldb/trunk/include/lldb/Target/StackFrameList.h Thu Sep 8 17:13:49 2011 @@ -48,7 +48,7 @@ // Mark a stack frame as the current frame uint32_t SetSelectedFrame (lldb_private::StackFrame *frame); - + uint32_t GetSelectedFrameIndex () const; @@ -57,6 +57,9 @@ SetSelectedFrameByIndex (uint32_t idx); void + SetDefaultFileAndLineToSelectedFrame(); + + void Clear (); void Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 8 17:13:49 2011 @@ -23,6 +23,7 @@ #include "lldb/Core/Event.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/UserSettingsController.h" +#include "lldb/Core/SourceManager.h" #include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Interpreter/NamedOptionValue.h" #include "lldb/Symbol/SymbolContext.h" @@ -758,6 +759,12 @@ { return m_platform_sp; } + + SourceManager & + GetSourceManager () + { + return m_source_manager; + } //------------------------------------------------------------------ // Target::SettingsController @@ -830,6 +837,7 @@ std::auto_ptr m_scratch_ast_context_ap; ClangPersistentVariables m_persistent_variables; ///< These are the persistent variables associated with this process for the expression parser. + SourceManager m_source_manager; typedef std::map StopHookCollection; StopHookCollection m_stop_hooks; Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Thu Sep 8 17:13:49 2011 @@ -326,28 +326,55 @@ } virtual uint32_t - GetStackFrameCount(); + GetStackFrameCount() + { + return GetStackFrameList().GetNumFrames(); + } virtual lldb::StackFrameSP - GetStackFrameAtIndex (uint32_t idx); + GetStackFrameAtIndex (uint32_t idx) + { + return GetStackFrameList().GetFrameAtIndex(idx); + } virtual lldb::StackFrameSP GetFrameWithConcreteFrameIndex (uint32_t unwind_idx); virtual lldb::StackFrameSP - GetFrameWithStackID(StackID &stack_id); + GetFrameWithStackID(StackID &stack_id) + { + return GetStackFrameList().GetFrameWithStackID (stack_id); + } uint32_t - GetSelectedFrameIndex (); + GetSelectedFrameIndex () + { + return GetStackFrameList().GetSelectedFrameIndex(); + } lldb::StackFrameSP - GetSelectedFrame (); + GetSelectedFrame () + { + return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex()); + } uint32_t - SetSelectedFrame (lldb_private::StackFrame *frame); + SetSelectedFrame (lldb_private::StackFrame *frame) + { + return GetStackFrameList().SetSelectedFrame(frame); + } void - SetSelectedFrameByIndex (uint32_t frame_idx); + SetSelectedFrameByIndex (uint32_t frame_idx) + { + GetStackFrameList().SetSelectedFrameByIndex(frame_idx); + } + + void + SetDefaultFileAndLineToSelectedFrame() + { + GetStackFrameList().SetDefaultFileAndLineToSelectedFrame(); + } virtual lldb::RegisterContextSP GetRegisterContext () = 0; Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Thu Sep 8 17:13:49 2011 @@ -360,7 +360,7 @@ SBSourceManager & SBDebugger::GetSourceManager () { - static SourceManager g_lldb_source_manager; + static SourceManager g_lldb_source_manager(NULL); static SBSourceManager g_sb_source_manager (&g_lldb_source_manager); return g_sb_source_manager; } Modified: lldb/trunk/source/API/SBSourceManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBSourceManager.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/API/SBSourceManager.cpp (original) +++ lldb/trunk/source/API/SBSourceManager.cpp Thu Sep 8 17:13:49 2011 @@ -61,8 +61,7 @@ if (file.IsValid()) { - return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (NULL, - *file, + return m_opaque_ptr->DisplaySourceLinesWithLineNumbers (*file, line, context_before, context_after, Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Thu Sep 8 17:13:49 2011 @@ -32,7 +32,7 @@ #include "lldb/API/SBAddress.h" #include "lldb/API/SBFrame.h" -#include "lldb/API/SBSourceManager.h" +// DONT THINK THIS IS NECESSARY: #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBProcess.h" Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Sep 8 17:13:49 2011 @@ -321,32 +321,38 @@ FileSpec file; if (m_options.m_filename.empty()) { - StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame; - if (cur_frame == NULL) + uint32_t default_line; + // First use the Source Manager's default file. + // Then use the current stack frame's file. + if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line)) { - result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame."); - result.SetStatus (eReturnStatusFailed); - break; - } - else if (!cur_frame->HasDebugInformation()) - { - result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info."); - result.SetStatus (eReturnStatusFailed); - break; - } - else - { - const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); - if (sc.line_entry.file) + StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame; + if (cur_frame == NULL) { - file = sc.line_entry.file; + result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame."); + result.SetStatus (eReturnStatusFailed); + break; } - else + else if (!cur_frame->HasDebugInformation()) { - result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame."); + result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info."); result.SetStatus (eReturnStatusFailed); break; } + else + { + const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); + if (sc.line_entry.file) + { + file = sc.line_entry.file; + } + else + { + result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame."); + result.SetStatus (eReturnStatusFailed); + break; + } + } } } else Modified: lldb/trunk/source/Commands/CommandObjectSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSource.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectSource.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectSource.cpp Thu Sep 8 17:13:49 2011 @@ -280,18 +280,23 @@ } ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - + Target *target = NULL; + + if (exe_ctx.target) + target = exe_ctx.target; + else + target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + + if (target == NULL) + { + result.AppendError ("invalid target, create a debug target using the 'target create' command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + if (!m_options.symbol_name.empty()) { // Displaying the source for a symbol: - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - SymbolContextList sc_list; ConstString name(m_options.symbol_name.c_str()); bool include_symbols = false; @@ -418,7 +423,7 @@ char path_buf[PATH_MAX]; start_file.GetPath(path_buf, sizeof(path_buf)); - if (m_options.show_bp_locs && exe_ctx.target) + if (m_options.show_bp_locs) { const bool show_inlines = true; m_breakpoint_locations.Reset (start_file, 0, show_inlines); @@ -429,14 +434,13 @@ m_breakpoint_locations.Clear(); result.AppendMessageWithFormat("File: %s.\n", path_buf); - m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (target, - start_file, - line_no, - 0, - m_options.num_lines, - "", - &result.GetOutputStream(), - GetBreakpointLocations ()); + target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file, + line_no, + 0, + m_options.num_lines, + "", + &result.GetOutputStream(), + GetBreakpointLocations ()); result.SetStatus (eReturnStatusSuccessFinishResult); return true; @@ -458,21 +462,21 @@ } else { - if (m_options.show_bp_locs && exe_ctx.target) + if (m_options.show_bp_locs) { - SourceManager::FileSP last_file_sp (m_interpreter.GetDebugger().GetSourceManager().GetLastFile ()); + SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ()); if (last_file_sp) { const bool show_inlines = true; m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines); - SearchFilter target_search_filter (exe_ctx.target->GetSP()); + SearchFilter target_search_filter (target->GetSP()); target_search_filter.Search (m_breakpoint_locations); } } else m_breakpoint_locations.Clear(); - if (m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile( + if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile( m_options.start_line, // Line to display 0, // Lines before line to display m_options.num_lines, // Lines after line to display @@ -488,14 +492,6 @@ else { const char *filename = m_options.file_name.c_str(); - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, create a debug target using the 'target create' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - bool check_inlines = false; SymbolContextList sc_list; @@ -571,24 +567,23 @@ { if (sc.comp_unit) { - if (m_options.show_bp_locs && exe_ctx.target) + if (m_options.show_bp_locs) { const bool show_inlines = true; m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); - SearchFilter target_search_filter (exe_ctx.target->GetSP()); + SearchFilter target_search_filter (target->GetSP()); target_search_filter.Search (m_breakpoint_locations); } else m_breakpoint_locations.Clear(); - m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (target, - sc.comp_unit, - m_options.start_line, - 0, - m_options.num_lines, - "", - &result.GetOutputStream(), - GetBreakpointLocations ()); + target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, + m_options.start_line, + 0, + m_options.num_lines, + "", + &result.GetOutputStream(), + GetBreakpointLocations ()); result.SetStatus (eReturnStatusSuccessFinishResult); } Modified: lldb/trunk/source/Core/Debugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Core/Debugger.cpp (original) +++ lldb/trunk/source/Core/Debugger.cpp Thu Sep 8 17:13:49 2011 @@ -237,7 +237,7 @@ m_target_list (), m_platform_list (), m_listener ("lldb.Debugger"), - m_source_manager (), + m_source_manager(NULL), m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)), m_input_reader_stack (), m_input_reader_data () Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Thu Sep 8 17:13:49 2011 @@ -369,8 +369,7 @@ if (sc.comp_unit && sc.line_entry.IsValid()) { - debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (debugger.GetTargetList().GetSelectedTarget().get(), - sc.line_entry.file, + debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file, sc.line_entry.line, num_mixed_context_lines, num_mixed_context_lines, Modified: lldb/trunk/source/Core/SourceManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SourceManager.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Core/SourceManager.cpp (original) +++ lldb/trunk/source/Core/SourceManager.cpp Thu Sep 8 17:13:49 2011 @@ -29,12 +29,13 @@ //---------------------------------------------------------------------- // SourceManager constructor //---------------------------------------------------------------------- -SourceManager::SourceManager() : +SourceManager::SourceManager(Target *target) : m_file_cache (), m_last_file_sp (), m_last_file_line (0), m_last_file_context_before (0), - m_last_file_context_after (0) + m_last_file_context_after (10), + m_target (target) { } @@ -48,7 +49,6 @@ size_t SourceManager::DisplaySourceLines ( - Target *target, const FileSpec &file_spec, uint32_t line, uint32_t context_before, @@ -56,7 +56,7 @@ Stream *s ) { - m_last_file_sp = GetFile (file_spec, target); + m_last_file_sp = GetFile (file_spec); m_last_file_line = line + context_after + 1; m_last_file_context_before = context_before; m_last_file_context_after = context_after; @@ -67,7 +67,7 @@ } SourceManager::FileSP -SourceManager::GetFile (const FileSpec &file_spec, Target *target) +SourceManager::GetFile (const FileSpec &file_spec) { FileSP file_sp; FileCache::iterator pos = m_file_cache.find(file_spec); @@ -75,7 +75,7 @@ file_sp = pos->second; else { - file_sp.reset (new File (file_spec, target)); + file_sp.reset (new File (file_spec, m_target)); m_file_cache[file_spec] = file_sp; } return file_sp; @@ -151,7 +151,6 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbers ( - Target *target, const FileSpec &file_spec, uint32_t line, uint32_t context_before, @@ -164,7 +163,7 @@ bool same_as_previous = m_last_file_sp && m_last_file_sp->FileSpecMatches (file_spec); if (!same_as_previous) - m_last_file_sp = GetFile (file_spec, target); + m_last_file_sp = GetFile (file_spec); if (line == 0) { @@ -187,6 +186,35 @@ return 0; } +bool +SourceManager::SetDefaultFileAndLine (const FileSpec &file_spec, uint32_t line) +{ + FileSP old_file_sp = m_last_file_sp; + m_last_file_sp = GetFile (file_spec); + if (m_last_file_sp) + { + m_last_file_line = line; + return true; + } + else + { + m_last_file_sp = old_file_sp; + return false; + } +} + +bool +SourceManager::GetDefaultFileAndLine (FileSpec &file_spec, uint32_t &line) +{ + if (m_last_file_sp) + { + file_spec = m_last_file_sp->GetFileSpec(); + line = m_last_file_line; + return true; + } + else + return false; +} SourceManager::File::File(const FileSpec &file_spec, Target *target) : @@ -198,7 +226,7 @@ { if (!m_mod_time.IsValid()) { - if (target->GetSourcePathMap().RemapPath(file_spec.GetDirectory(), m_file_spec.GetDirectory())) + if (target && target->GetSourcePathMap().RemapPath(file_spec.GetDirectory(), m_file_spec.GetDirectory())) m_mod_time = file_spec.GetModificationTime(); } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Thu Sep 8 17:13:49 2011 @@ -792,22 +792,27 @@ { if (name) { - ConstString objc_class_name; - ConstString objc_method_name; - ConstString objc_base_name; - if (ObjCLanguageRuntime::ParseMethodName (name, - &objc_class_name, - &objc_method_name, - &objc_base_name)) + // Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the + // simple inlined check outside the call. + if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name)) { - objc_class_selectors.Insert(objc_class_name, die_info); - - func_selectors.Insert (objc_method_name, die_info); - - if (!objc_base_name.IsEmpty()) + ConstString objc_class_name; + ConstString objc_method_name; + ConstString objc_base_name; + if (ObjCLanguageRuntime::ParseMethodName (name, + &objc_class_name, + &objc_method_name, + &objc_base_name)) { - func_basenames.Insert (objc_base_name, die_info); - func_fullnames.Insert (objc_base_name, die_info); + objc_class_selectors.Insert(objc_class_name, die_info); + + func_selectors.Insert (objc_method_name, die_info); + + if (!objc_base_name.IsEmpty()) + { + func_basenames.Insert (objc_base_name, die_info); + func_fullnames.Insert (objc_base_name, die_info); + } } } // If we have a mangled name, then the DW_AT_name attribute Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Sep 8 17:13:49 2011 @@ -42,6 +42,8 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ObjCLanguageRuntime.h" + #include "DWARFCompileUnit.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" @@ -3789,7 +3791,7 @@ bool type_handled = false; if (tag == DW_TAG_subprogram) { - if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+')) + if (ObjCLanguageRuntime::IsPossibleObjCMethodName (type_name_cstr)) { // We need to find the DW_TAG_class_type or // DW_TAG_struct_type by name so we can add this Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original) +++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Thu Sep 8 17:13:49 2011 @@ -111,7 +111,7 @@ if (method_name) { method_name->Clear(); } if (base_name) { base_name->Clear(); } - if (name && (name[0] == '-' || name[0] == '+') && name[1] == '[') + if (IsPossibleObjCMethodName (name)) { int name_len = strlen (name); // Objective C methods must have at least: Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Thu Sep 8 17:13:49 2011 @@ -1282,8 +1282,7 @@ if (m_sc.comp_unit && m_sc.line_entry.IsValid()) { Target &target = GetThread().GetProcess().GetTarget(); - target.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers ( - &target, + target.GetSourceManager().DisplaySourceLinesWithLineNumbers ( m_sc.line_entry.file, m_sc.line_entry.line, 3, Modified: lldb/trunk/source/Target/StackFrameList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrameList.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrameList.cpp (original) +++ lldb/trunk/source/Target/StackFrameList.cpp Thu Sep 8 17:13:49 2011 @@ -14,11 +14,14 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/StreamFile.h" +#include "lldb/Core/SourceManager.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" @@ -401,15 +404,16 @@ const_iterator pos; const_iterator begin = m_frames.begin(); const_iterator end = m_frames.end(); + m_selected_frame_idx = 0; for (pos = begin; pos != end; ++pos) { if (pos->get() == frame) { m_selected_frame_idx = std::distance (begin, pos); - return m_selected_frame_idx; + break; } } - m_selected_frame_idx = 0; + SetDefaultFileAndLineToSelectedFrame(); return m_selected_frame_idx; } @@ -419,6 +423,22 @@ { Mutex::Locker locker (m_mutex); m_selected_frame_idx = idx; + SetDefaultFileAndLineToSelectedFrame(); +} + +void +StackFrameList::SetDefaultFileAndLineToSelectedFrame() +{ + if (m_thread.GetID() == m_thread.GetProcess().GetThreadList().GetSelectedThread()->GetID()) + { + StackFrameSP frame_sp = m_frames[m_selected_frame_idx]; + if (frame_sp) + { + SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextEverything); + if (sc.line_entry.file) + m_thread.GetProcess().GetTarget().GetSourceManager().SetDefaultFileAndLine (sc.line_entry.file, sc.line_entry.line); + } + } } // The thread has been run, reset the number stack frames to zero so we can Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Thu Sep 8 17:13:49 2011 @@ -59,6 +59,7 @@ m_image_search_paths (ImageSearchPathsChanged, this), m_scratch_ast_context_ap (NULL), m_persistent_variables (), + m_source_manager(this), m_stop_hooks (), m_stop_hook_next_id (0), m_suppress_stop_hooks (false) @@ -469,6 +470,26 @@ FileSpecList dependent_files; ObjectFile *executable_objfile = executable_sp->GetObjectFile(); + // Let's find the file & line for main and set the default source file from there. + if (!m_source_manager.DefaultFileAndLineSet()) + { + SymbolContextList sc_list; + uint32_t num_matches; + ConstString main_name("main"); + bool symbols_okay = false; // Force it to be a debug symbol. + bool append = false; + num_matches = executable_sp->FindFunctions (main_name, eFunctionNameTypeBase, symbols_okay, append, sc_list); + for (uint32_t idx = 0; idx < num_matches; idx++) + { + SymbolContext sc; + sc_list.GetContextAtIndex(idx, sc); + if (sc.line_entry.file) + { + m_source_manager.SetDefaultFileAndLine(sc.line_entry.file, sc.line_entry.line); + break; + } + } + } if (executable_objfile) { Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Thu Sep 8 17:13:49 2011 @@ -925,15 +925,6 @@ return *m_curr_frames_sp; } - - -uint32_t -Thread::GetStackFrameCount() -{ - return GetStackFrameList().GetNumFrames(); -} - - void Thread::ClearStackFrames () { @@ -943,48 +934,11 @@ } lldb::StackFrameSP -Thread::GetStackFrameAtIndex (uint32_t idx) -{ - return GetStackFrameList().GetFrameAtIndex(idx); -} - -uint32_t -Thread::GetSelectedFrameIndex () -{ - return GetStackFrameList().GetSelectedFrameIndex(); -} - -lldb::StackFrameSP Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) { return GetStackFrameList().GetFrameWithConcreteFrameIndex (unwind_idx); } -lldb::StackFrameSP -Thread::GetFrameWithStackID(StackID &stack_id) -{ - return GetStackFrameList().GetFrameWithStackID (stack_id); -} - - -lldb::StackFrameSP -Thread::GetSelectedFrame () -{ - return GetStackFrameAtIndex (GetStackFrameList().GetSelectedFrameIndex()); -} - -uint32_t -Thread::SetSelectedFrame (lldb_private::StackFrame *frame) -{ - return GetStackFrameList().SetSelectedFrame(frame); -} - -void -Thread::SetSelectedFrameByIndex (uint32_t idx) -{ - GetStackFrameList().SetSelectedFrameByIndex(idx); -} - void Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx) { Modified: lldb/trunk/source/Target/ThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadList.cpp (original) +++ lldb/trunk/source/Target/ThreadList.cpp Thu Sep 8 17:13:49 2011 @@ -558,8 +558,12 @@ ThreadList::SetSelectedThreadByID (lldb::tid_t tid) { Mutex::Locker locker(m_threads_mutex); - if (FindThreadByID(tid).get()) + ThreadSP selected_thread_sp(FindThreadByID(tid)); + if (selected_thread_sp) + { m_selected_tid = tid; + selected_thread_sp->SetDefaultFileAndLineToSelectedFrame(); + } else m_selected_tid = LLDB_INVALID_THREAD_ID; @@ -570,9 +574,12 @@ ThreadList::SetSelectedThreadByIndexID (uint32_t index_id) { Mutex::Locker locker(m_threads_mutex); - ThreadSP thread_sp (FindThreadByIndexID(index_id)); - if (thread_sp.get()) - m_selected_tid = thread_sp->GetID(); + ThreadSP selected_thread_sp (FindThreadByIndexID(index_id)); + if (selected_thread_sp.get()) + { + m_selected_tid = selected_thread_sp->GetID(); + selected_thread_sp->SetDefaultFileAndLineToSelectedFrame(); + } else m_selected_tid = LLDB_INVALID_THREAD_ID; Modified: lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py?rev=139323&r1=139322&r2=139323&view=diff ============================================================================== --- lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py (original) +++ lldb/trunk/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py Thu Sep 8 17:13:49 2011 @@ -40,8 +40,9 @@ exe = os.path.join(os.getcwd(), "a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) - # Add two breakpoints on the same line. - self.expect("breakpoint set -f main.c -l %d" % self.line, + # Add two breakpoints on the same line. The first time we don't specify the file, + # since the default file is the one containing main: + self.expect("breakpoint set -l %d" % self.line, BREAKPOINT_CREATED, startstr = "Breakpoint created: 1: file ='main.c', line = %d, locations = 1" % self.line) From gclayton at apple.com Thu Sep 8 18:18:17 2011 From: gclayton at apple.com (Greg Clayton) Date: Thu, 08 Sep 2011 16:18:17 -0700 Subject: [Lldb-commits] [lldb-dev] FreeBSD fixes In-Reply-To: References: Message-ID: On Sep 8, 2011, at 3:58 PM, Filipe Cabecinhas wrote: > Hi, I tried sending this message earlier, but it seems it got lost along the way. > > I'm re-sending the patch for allowing "target create" on the remote-macosx platform and another patch to augment the FreeBSD platform and make it like the Mac OS X platform. > In order to make the FreeBSD platform we will have to, either implement a local platform (like the Linux one) or implement debugserver on FreeBSD. I'm leaning on the second solution as it would offer us remote debugging for free. > > I just want to confirm something: Is debugserver portable? I'm supposing debugserver is MacOSX specific, but I may be looking at the wrong parts of the code. It is currently very specific. For porting to new systems, we should make binary similar to the lldb-platform binary. It links against the innards of lldb-core, and it also uses the GDBRemoteCommunicationServer class, which is the GDB server side of the GDB remote protocol in LLDB. The GDBRemoteCommunicationServer is a very clean interface and gets you all of the supported packet management built in. It should be extended to do all of the debugging stuff through an interface which is similar to the DNB.h. The DNB.h is a very clean interface as well, but we should copy it, and make a new version that is host agnostic (there are a few "#include " in the DNB.h version). If we abstract all debugging for all systems though a clean interface like the one in "DNB.h", then we can also have native debugger plug-ins that use this interface and allows us to have a native debugger plug-in, _and_ a remote debugger plug-in that use the exact same debug code. So the steps as I see them: - Copy DNB.h and remame it to HostDebugger.h and place it into LLDB core code and use it as the basis for all local native debugging, both local and remote - Create a new Process plug-in named ProcessHostDebugger that would use the new HostDebugger.h interface - Use GDBRemoteCommunicationServer.h to implement a new GDB server binary named "lldb-gdb-server" and have it link to lldb-core like lldb-platform already does and have it use the "HostDebugger.h" to implement the debugging inside GDBRemoteCommunicationServer or a subclass. We can look at the code in debugserver for reference, but I wouldn't use it as the basis for any new GDB server implementations. Does this make sense? Greg > > Thanks, > > Filipe > > > _______________________________________________ > lldb-dev mailing list > lldb-dev at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev From johnny.chen at apple.com Thu Sep 8 18:52:07 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 23:52:07 -0000 Subject: [Lldb-commits] [lldb] r139335 - /lldb/trunk/source/Commands/CommandObjectFrame.cpp Message-ID: <20110908235207.23A792A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 18:52:06 2011 New Revision: 139335 URL: http://llvm.org/viewvc/llvm-project?rev=139335&view=rev Log: Remove code rot (unused class OptionGroupFrameVariable) from CommandObjectFrameVariable. Plus minor indentation change. Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=139335&r1=139334&r2=139335&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Thu Sep 8 18:52:06 2011 @@ -307,86 +307,6 @@ { public: - class OptionGroupFrameVariable : public OptionGroup - { - public: - - OptionGroupFrameVariable () - { - } - - virtual - ~OptionGroupFrameVariable () - { - } - - virtual uint32_t - GetNumDefinitions (); - - virtual const OptionDefinition* - GetDefinitions () - { - return g_option_table; - } - - virtual Error - SetOptionValue (CommandInterpreter &interpreter, - uint32_t option_idx, - const char *option_arg) - { - Error error; - char short_option = (char) g_option_table[option_idx].short_option; - switch (short_option) - { - case 'r': use_regex = true; break; - case 'a': show_args = false; break; - case 'l': show_locals = false; break; - case 'g': show_globals = true; break; - case 'c': show_decl = true; break; - case 'f': error = Args::StringToFormat(option_arg, format, NULL); break; - case 'G': - globals.push_back(ConstString (option_arg)); - break; - case 's': - show_scope = true; - break; - - default: - error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); - break; - } - - return error; - } - - virtual void - OptionParsingStarting (CommandInterpreter &interpreter) - { - show_args = true; - show_decl = false; - format = eFormatDefault; - show_globals = false; - show_locals = true; - use_regex = false; - show_scope = false; - globals.clear(); - } - - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; - - bool use_regex:1, - show_args:1, - show_locals:1, - show_globals:1, - show_scope:1, - show_decl:1; - lldb::Format format; // The format to use when dumping variables or children of variables - std::vector globals; - // Instance variables to hold the values for command options. - }; - CommandObjectFrameVariable (CommandInterpreter &interpreter) : CommandObject (interpreter, "frame variable", @@ -637,7 +557,7 @@ // using the same APIs as the the public API will be // using... valobj_sp = frame_sp->GetValueObjectForFrameVariable (var_sp, - m_varobj_options.use_dynamic); + m_varobj_options.use_dynamic); if (valobj_sp) { if (m_option_variable.format != eFormatDefault) From johnny.chen at apple.com Thu Sep 8 19:01:44 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 00:01:44 -0000 Subject: [Lldb-commits] [lldb] r139336 - in /lldb/trunk/source: Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Target/Process.cpp Message-ID: <20110909000144.2D76D2A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 19:01:43 2011 New Revision: 139336 URL: http://llvm.org/viewvc/llvm-project?rev=139336&view=rev Log: Patch from Filipe! One fixes a trailing comma bug (g++ doesn't like them) The other gets the Error from the result of an expression evaluation and uses it as the error for the Process::LoadImage() method. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=139336&r1=139335&r2=139336&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Thu Sep 8 19:01:43 2011 @@ -234,7 +234,7 @@ flagsGotDebugRangesData = (1 << 9), flagsGotDebugStrData = (1 << 10), flagsGotDebugNamesData = (1 << 11), - flagsGotDebugTypesData = (1 << 12), + flagsGotDebugTypesData = (1 << 12) }; DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=139336&r1=139335&r2=139336&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Thu Sep 8 19:01:43 2011 @@ -1155,7 +1155,8 @@ const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n"; lldb::ValueObjectSP result_valobj_sp; ClangUserExpression::Evaluate (exe_ctx, unwind_on_error, expr.GetData(), prefix, result_valobj_sp); - if (result_valobj_sp->GetError().Success()) + error = result_valobj_sp->GetError(); + if (error.Success()) { Scalar scalar; if (result_valobj_sp->ResolveValue (scalar)) From johnny.chen at apple.com Thu Sep 8 19:04:22 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 17:04:22 -0700 Subject: [Lldb-commits] [lldb-dev] Small fixes In-Reply-To: References: Message-ID: Hi Filipe, Committed revision 139336. Thanks! On Sep 8, 2011, at 2:56 PM, Filipe Cabecinhas wrote: > Hi, > > I've got two small fixes for lldb: > > One fixes a trailing comma bug (g++ doesn't like them) > The other gets the Error from the result of an expression evaluation and uses it as the error for the Process::LoadImage() method. > > Thanks, > > Filipe > _______________________________________________ > lldb-dev mailing list > lldb-dev at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev From granata.enrico at gmail.com Thu Sep 8 19:04:25 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Fri, 09 Sep 2011 00:04:25 -0000 Subject: [Lldb-commits] [lldb] r139337 - in /lldb/trunk/tools/debugserver: debugserver.xcodeproj/project.pbxproj source/MacOSX/MachTask.cpp source/MacOSX/MachTask.h source/MacOSX/stack_logging.h Message-ID: <20110909000425.12EEF2A6C12C@llvm.org> Author: enrico Date: Thu Sep 8 19:04:24 2011 New Revision: 139337 URL: http://llvm.org/viewvc/llvm-project?rev=139337&view=rev Log: Basic infrastructure code to exploit malloc stack logging as available on Mac OS X to track the allocation history of pointers on the target process Added: lldb/trunk/tools/debugserver/source/MacOSX/stack_logging.h Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h Modified: lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=139337&r1=139336&r2=139337&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original) +++ lldb/trunk/tools/debugserver/debugserver.xcodeproj/project.pbxproj Thu Sep 8 19:04:24 2011 @@ -130,6 +130,7 @@ 4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = ""; }; 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = ""; }; 49F5301213316D7F008956F6 /* MachRegisterStatesX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesX86_64.h; sourceTree = ""; }; + 9457ECF61419864100DFE7D8 /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = ""; }; AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = ""; }; AF67AC000D34604D0022D128 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoTerminal.h; sourceTree = ""; }; EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.plist; sourceTree = ""; }; @@ -300,6 +301,7 @@ 26C637F80C71334A0024798E /* MachVMRegion.cpp */, 26B67DE00EE9BC30006C8BC0 /* MachTask.h */, 26B67DE10EE9BC30006C8BC0 /* MachTask.cpp */, + 9457ECF61419864100DFE7D8 /* stack_logging.h */, ); path = MacOSX; sourceTree = ""; Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp?rev=139337&r1=139336&r2=139337&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.cpp Thu Sep 8 19:04:24 2011 @@ -31,6 +31,7 @@ #include "DNBLog.h" #include "MachProcess.h" #include "DNBDataRef.h" +#include "stack_logging.h" #if defined (__arm__) @@ -677,3 +678,86 @@ return false; } +static void foundStackLog(mach_stack_logging_record_t record, void *context) { + *((bool*)context) = true; +} + +bool +MachTask::HasMallocLoggingEnabled () +{ + bool found = false; + + __mach_stack_logging_enumerate_records(m_task, 0x0, foundStackLog, &found); + return found; +} + +struct history_enumerator_impl_data +{ + MachMallocEvent *buffer; + uint32_t *position; + uint32_t count; +}; + +static void history_enumerator_impl(mach_stack_logging_record_t record, void* enum_obj) +{ + history_enumerator_impl_data *data = (history_enumerator_impl_data*)enum_obj; + + if (*data->position >= data->count) + return; + + data->buffer[*data->position].m_base_address = record.address; + data->buffer[*data->position].m_size = record.argument; + data->buffer[*data->position].m_event_id = record.stack_identifier; + data->buffer[*data->position].m_event_type = record.type_flags == stack_logging_type_alloc ? eMachMallocEventTypeAlloc : + record.type_flags == stack_logging_type_dealloc ? eMachMallocEventTypeDealloc : + eMachMallocEventTypeOther; + *data->position+=1; +} + +bool +MachTask::EnumerateMallocRecords (MachMallocEvent *event_buffer, + uint32_t buffer_size, + uint32_t *count) +{ + return EnumerateMallocRecords(0, + event_buffer, + buffer_size, + count); +} + +bool +MachTask::EnumerateMallocRecords (mach_vm_address_t address, + MachMallocEvent *event_buffer, + uint32_t buffer_size, + uint32_t *count) +{ + if (!event_buffer || !count) + return false; + + if (buffer_size == 0) + return false; + + *count = 0; + history_enumerator_impl_data data = { event_buffer, count, buffer_size }; + __mach_stack_logging_enumerate_records(m_task, address, history_enumerator_impl, &data); + return (*count > 0); +} + +bool +MachTask::EnumerateMallocFrames (MachMallocEventId event_id, + mach_vm_address_t *function_addresses_buffer, + uint32_t buffer_size, + uint32_t *count) +{ + if (!function_addresses_buffer || !count) + return false; + + if (buffer_size == 0) + return false; + + __mach_stack_logging_frames_for_uniqued_stack(m_task, event_id, &function_addresses_buffer[0], buffer_size, count); + *count -= 1; + if (function_addresses_buffer[*count-1] < vm_page_size) + *count -= 1; + return (*count > 0); +} Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h?rev=139337&r1=139336&r2=139337&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/MachTask.h Thu Sep 8 19:04:24 2011 @@ -31,6 +31,23 @@ class MachProcess; +typedef uint64_t MachMallocEventId; + +enum MachMallocEventType +{ + eMachMallocEventTypeAlloc = 2, + eMachMallocEventTypeDealloc = 4, + eMachMallocEventTypeOther = 1 +}; + +struct MachMallocEvent +{ + mach_vm_address_t m_base_address; + uint64_t m_size; + MachMallocEventType m_event_type; + MachMallocEventId m_event_id; +}; + class MachTask { public: @@ -70,6 +87,27 @@ MachProcess * Process () { return m_process; } const MachProcess * Process () const { return m_process; } + + + bool HasMallocLoggingEnabled (); + + // enumerate the malloc records for a given address (starting with Mac OS X 10.6 Snow Leopard it should include + // all allocations that *include* address, rather than just those *starting* at address) + bool EnumerateMallocRecords (mach_vm_address_t address, + MachMallocEvent *event_buffer, + uint32_t buffer_size, + uint32_t *count); + + // enumerate every malloc record generated by this task, no matter what the address + bool EnumerateMallocRecords (MachMallocEvent *event_buffer, + uint32_t buffer_size, + uint32_t *count); + + // given a malloc event, report every stack frame that led to this event + bool EnumerateMallocFrames (MachMallocEventId event_id, + mach_vm_address_t *function_addresses_buffer, + uint32_t buffer_size, + uint32_t *count); protected: MachProcess * m_process; // The mach process that owns this MachTask Added: lldb/trunk/tools/debugserver/source/MacOSX/stack_logging.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/stack_logging.h?rev=139337&view=auto ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/stack_logging.h (added) +++ lldb/trunk/tools/debugserver/source/MacOSX/stack_logging.h Thu Sep 8 19:04:24 2011 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1999-2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef malloc_history_test_stack_logging_h +#define malloc_history_test_stack_logging_h + +#import + +#define stack_logging_type_free 0 +#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */ +#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */ +#define stack_logging_type_dealloc 4 /* free, realloc, etc... */ + +// Following flags are absorbed by stack_logging_log_stack() +#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */ +#define stack_logging_flag_calloc 16 /* multiply arguments to get the size */ +#define stack_logging_flag_object 32 /* NSAllocateObject(Class, extraBytes, zone) */ +#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */ +#define stack_logging_flag_handle 128 /* for Handle (de-)allocation routines */ +#define stack_logging_flag_set_handle_size 256 /* (Handle, newSize) treated specially */ + +/* Macro used to disguise addresses so that leak finding can work */ +#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */ + +extern "C" int stack_logging_enable_logging; /* when clear, no logging takes place */ +extern "C" int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */ + + +extern "C" void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip); +/* This is the old log-to-memory logger, which is now deprecated. It remains for compatibility with performance tools that haven't been updated to disk_stack_logging_log_stack() yet. */ + +extern "C" void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip); +/* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */ + + +/* 64-bit-aware stack log access. */ +typedef struct { + uint32_t type_flags; + uint64_t stack_identifier; + uint64_t argument; + mach_vm_address_t address; +} mach_stack_logging_record_t; + +extern "C" kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); +/* Gets the last allocation record (malloc, realloc, or free) about address */ + +extern "C" kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context); +/* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */ + +extern "C" kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count); +/* Given a uniqued_stack fills stack_frames_buffer */ + + +#pragma mark - +#pragma mark Legacy + +/* The following is the old 32-bit-only, in-process-memory stack logging. This is deprecated and clients should move to the above 64-bit-aware disk stack logging SPI. */ + +typedef struct { + unsigned type; + unsigned uniqued_stack; + unsigned argument; + unsigned address; /* disguised, to avoid confusing leaks */ +} stack_logging_record_t; + +typedef struct { + unsigned overall_num_bytes; + unsigned num_records; + unsigned lock; /* 0 means OK to lock; used for inter-process locking */ + unsigned *uniquing_table; /* allocated using vm_allocate() */ + /* hashtable organized as (PC, uniqued parent) + Only the second half of the table is active + To enable us to grow dynamically */ + unsigned uniquing_table_num_pages; /* number of pages of the table */ + unsigned extra_retain_count; /* not used by stack_logging_log_stack */ + unsigned filler[2]; /* align to cache lines for better performance */ + stack_logging_record_t records[0]; /* records follow here */ +} stack_logging_record_list_t; + +extern "C" stack_logging_record_list_t *stack_logging_the_record_list; +/* This is the global variable containing all logs */ + +extern "C" kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); +/* Gets the last record in stack_logging_the_record_list about address */ + +#define STACK_LOGGING_ENUMERATION_PROVIDED 1 // temporary to avoid dependencies between projects + +extern "C" kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context); +/* Gets all the records about address; + If !address, gets all records */ + +extern "C" kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames); +/* Given a uniqued_stack fills stack_frames_buffer */ + + + +extern "C" void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num); +/* Convenience to fill buffer with the PCs of the frames, starting with the hot frames; + num: returned number of frames + */ + +#endif From johnny.chen at apple.com Thu Sep 8 19:10:04 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 00:10:04 -0000 Subject: [Lldb-commits] [lldb] r139338 - in /lldb/trunk/source/Plugins/Platform/FreeBSD: PlatformFreeBSD.cpp PlatformFreeBSD.h Message-ID: <20110909001004.C9A3D2A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 19:10:04 2011 New Revision: 139338 URL: http://llvm.org/viewvc/llvm-project?rev=139338&view=rev Log: FreeBSD platform patch from Filipe! Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=139338&r1=139337&r2=139338&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original) +++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Thu Sep 8 19:10:04 2011 @@ -17,14 +17,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Error.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Process.h" using namespace lldb; using namespace lldb_private; @@ -87,38 +82,99 @@ PluginManager::UnregisterPlugin (PlatformFreeBSD::CreateInstance); } +//------------------------------------------------------------------ +/// Default Constructor +//------------------------------------------------------------------ +PlatformFreeBSD::PlatformFreeBSD (bool is_host) : +Platform(is_host) +{ +} + +//------------------------------------------------------------------ +/// Destructor. +/// +/// The destructor is virtual since this class is designed to be +/// inherited from by the plug-in instance. +//------------------------------------------------------------------ +PlatformFreeBSD::~PlatformFreeBSD() +{ +} + Error PlatformFreeBSD::ResolveExecutable (const FileSpec &exe_file, - const ArchSpec &exe_arch, - lldb::ModuleSP &exe_module_sp) + const ArchSpec &exe_arch, + lldb::ModuleSP &exe_module_sp) { Error error; // Nothing special to do here, just use the actual file and architecture + char exe_path[PATH_MAX]; FileSpec resolved_exe_file (exe_file); - - // If we have "ls" as the exe_file, resolve the executable loation based on - // the current path variables - if (!resolved_exe_file.Exists()) - resolved_exe_file.ResolveExecutableLocation (); - // Resolve any executable within a bundle on MacOSX - Host::ResolveExecutableInBundle (resolved_exe_file); + if (IsHost()) + { + // If we have "ls" as the exe_file, resolve the executable loation based on + // the current path variables + if (!resolved_exe_file.Exists()) + { + exe_file.GetPath(exe_path, sizeof(exe_path)); + resolved_exe_file.SetFile(exe_path, true); + } + + if (!resolved_exe_file.Exists()) + resolved_exe_file.ResolveExecutableLocation (); + + // Resolve any executable within a bundle on MacOSX + //Host::ResolveExecutableInBundle (resolved_exe_file); + + if (resolved_exe_file.Exists()) + error.Clear(); + else + { + exe_file.GetPath(exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); + } + } + else + { + if (m_remote_platform_sp) + { + error = m_remote_platform_sp->ResolveExecutable (exe_file, + exe_arch, + exe_module_sp); + } + else + { + // We may connect to a process and use the provided executable (Don't use local $PATH). + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle (resolved_exe_file); + + if (resolved_exe_file.Exists()) { + error.Clear(); + } + else + { + error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root."); + } + } + } + - if (resolved_exe_file.Exists()) + if (error.Success()) { if (exe_arch.IsValid()) { - error = ModuleList::GetSharedModule (resolved_exe_file, - exe_arch, + error = ModuleList::GetSharedModule (resolved_exe_file, + exe_arch, + NULL, + NULL, + 0, + exe_module_sp, NULL, - NULL, - 0, - exe_module_sp, - NULL, NULL); - + if (exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); @@ -138,15 +194,15 @@ ArchSpec platform_arch; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) { - error = ModuleList::GetSharedModule (resolved_exe_file, - platform_arch, + error = ModuleList::GetSharedModule (resolved_exe_file, + platform_arch, + NULL, + NULL, + 0, + exe_module_sp, NULL, - NULL, - 0, - exe_module_sp, - NULL, NULL); - // Did we find an executable using one of the + // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) @@ -154,12 +210,12 @@ else error.SetErrorToGenericError(); } - + if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (platform_arch.GetArchitectureName()); } - + if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", @@ -182,90 +238,203 @@ return error; } -Error -PlatformFreeBSD::GetFile (const FileSpec &platform_file, - const UUID *uuid, FileSpec &local_file) +size_t +PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) { - // Default to the local case - local_file = platform_file; - return Error(); -} + ArchSpec arch = target.GetArchitecture(); + const uint8_t *trap_opcode = NULL; + size_t trap_opcode_size = 0; + switch (arch.GetCore()) + { + default: + assert(false && "Unhandled architecture in PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode()"); + break; -//------------------------------------------------------------------ -/// Default Constructor -//------------------------------------------------------------------ -PlatformFreeBSD::PlatformFreeBSD (bool is_host) : - Platform(is_host) + case ArchSpec::eCore_x86_32_i386: + case ArchSpec::eCore_x86_64_x86_64: + { + static const uint8_t g_i386_opcode[] = { 0xCC }; + trap_opcode = g_i386_opcode; + trap_opcode_size = sizeof(g_i386_opcode); + } + break; + } + + if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) + return trap_opcode_size; + + return 0; +} + +bool +PlatformFreeBSD::GetRemoteOSVersion () { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetOSVersion (m_major_os_version, + m_minor_os_version, + m_update_os_version); + return false; } -//------------------------------------------------------------------ -/// Destructor. -/// -/// The destructor is virtual since this class is designed to be -/// inherited from by the plug-in instance. -//------------------------------------------------------------------ -PlatformFreeBSD::~PlatformFreeBSD() +bool +PlatformFreeBSD::GetRemoteOSBuildString (std::string &s) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSBuildString (s); + s.clear(); + return false; } bool -PlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) +PlatformFreeBSD::GetRemoteOSKernelDescription (std::string &s) +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSKernelDescription (s); + s.clear(); + return false; +} + +// Remote Platform subclasses need to override this function +ArchSpec +PlatformFreeBSD::GetRemoteSystemArchitecture () +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteSystemArchitecture (); + return ArchSpec(); +} + + +const char * +PlatformFreeBSD::GetHostname () { - return Host::GetProcessInfo (pid, process_info); + if (IsHost()) + return Platform::GetHostname(); + + if (m_remote_platform_sp) + return m_remote_platform_sp->GetHostname (); + return NULL; } bool -PlatformFreeBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +PlatformFreeBSD::IsConnected () const { - if (idx == 0) - { - arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); - return arch.IsValid(); - } + if (IsHost()) + return true; + else if (m_remote_platform_sp) + return m_remote_platform_sp->IsConnected(); return false; } -void -PlatformFreeBSD::GetStatus (Stream &strm) +Error +PlatformFreeBSD::ConnectRemote (Args& args) { - struct utsname un; + Error error; + if (IsHost()) + { + error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetShortPluginName()); + } + else + { + if (!m_remote_platform_sp) + m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); - if (uname(&un)) { - strm << "FreeBSD"; - return; + if (m_remote_platform_sp) + { + if (error.Success()) + { + if (m_remote_platform_sp) + { + error = m_remote_platform_sp->ConnectRemote (args); + } + else + { + error.SetErrorString ("\"platform connect\" takes a single argument: "); + } + } + } + else + error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); + + if (error.Fail()) + m_remote_platform_sp.reset(); } - strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n'; - Platform::GetStatus(strm); + return error; } -size_t -PlatformFreeBSD::GetSoftwareBreakpointTrapOpcode (Target &target, - BreakpointSite *bp_site) +Error +PlatformFreeBSD::DisconnectRemote () { - static const uint8_t g_i386_opcode[] = { 0xCC }; + Error error; - ArchSpec arch = target.GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; + if (IsHost()) + { + error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetShortPluginName()); + } + else + { + if (m_remote_platform_sp) + error = m_remote_platform_sp->DisconnectRemote (); + else + error.SetErrorString ("the platform is not currently connected"); + } + return error; +} - switch (arch.GetCore()) +bool +PlatformFreeBSD::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) +{ + bool sucess = false; + if (IsHost()) { - default: - assert(false && "CPU type not supported!"); - break; + sucess = Platform::GetProcessInfo (pid, process_info); + } + else + { + if (m_remote_platform_sp) + sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); + } + return sucess; +} - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_64_x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); - break; + + +uint32_t +PlatformFreeBSD::FindProcesses (const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) +{ + uint32_t match_count = 0; + if (IsHost()) + { + // Let the base class figure out the host details + match_count = Platform::FindProcesses (match_info, process_infos); + } + else + { + // If we are remote, we can only return results if we are connected + if (m_remote_platform_sp) + match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); } + return match_count; +} - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; +Error +PlatformFreeBSD::LaunchProcess (ProcessLaunchInfo &launch_info) +{ + Error error; + if (IsHost()) + { + error = Platform::LaunchProcess (launch_info); + } + else + { + if (m_remote_platform_sp) + error = m_remote_platform_sp->LaunchProcess (launch_info); + else + error.SetErrorString ("the platform is not currently connected"); + } + return error; } lldb::ProcessSP @@ -275,7 +444,173 @@ Listener &listener, Error &error) { - ProcessSP processSP; - assert(!"Not implemented yet!"); - return processSP; + lldb::ProcessSP process_sp; + if (IsHost()) + { + if (target == NULL) + { + TargetSP new_target_sp; + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; + + error = debugger.GetTargetList().CreateTarget (debugger, + emptyFileSpec, + emptyArchSpec, + false, + new_target_sp); + target = new_target_sp.get(); + } + else + error.Clear(); + + if (target && error.Success()) + { + debugger.GetTargetList().SetSelectedTarget(target); + // The freebsd always currently uses the GDB remote debugger plug-in + // so even when debugging locally we are debugging remotely! + // Just like the darwin plugin. + process_sp = target->CreateProcess (listener, "gdb-remote"); + + if (process_sp) + error = process_sp->Attach (pid); + } + } + else + { + if (m_remote_platform_sp) + process_sp = m_remote_platform_sp->Attach (pid, debugger, target, listener, error); + else + error.SetErrorString ("the platform is not currently connected"); + } + return process_sp; +} + +const char * +PlatformFreeBSD::GetUserName (uint32_t uid) +{ + // Check the cache in Platform in case we have already looked this uid up + const char *user_name = Platform::GetUserName(uid); + if (user_name) + return user_name; + + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetUserName(uid); + return NULL; +} + +const char * +PlatformFreeBSD::GetGroupName (uint32_t gid) +{ + const char *group_name = Platform::GetGroupName(gid); + if (group_name) + return group_name; + + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetGroupName(gid); + return NULL; +} + + +// From PlatformMacOSX only +Error +PlatformFreeBSD::GetFile (const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) +{ + if (IsRemote()) + { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFile (platform_file, uuid_ptr, local_file); + } + + // Default to the local case + local_file = platform_file; + return Error(); +} + +Error +PlatformFreeBSD::GetSharedModule (const FileSpec &platform_file, + const ArchSpec &arch, + const UUID *uuid_ptr, + const ConstString *object_name_ptr, + off_t object_offset, + ModuleSP &module_sp, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) +{ + Error error; + module_sp.reset(); + + if (IsRemote()) + { + // If we have a remote platform always, let it try and locate + // the shared module first. + if (m_remote_platform_sp) + { + error = m_remote_platform_sp->GetSharedModule (platform_file, + arch, + uuid_ptr, + object_name_ptr, + object_offset, + module_sp, + old_module_sp_ptr, + did_create_ptr); + } + } + + if (!module_sp) + { + // Fall back to the local platform and find the file locally + error = Platform::GetSharedModule (platform_file, + arch, + uuid_ptr, + object_name_ptr, + object_offset, + module_sp, + old_module_sp_ptr, + did_create_ptr); + } + if (module_sp) + module_sp->SetPlatformFileSpec(platform_file); + return error; +} + + +bool +PlatformFreeBSD::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) +{ + // From macosx;s plugin code. For FreeBSD we may want to support more archs. + if (idx == 0) + { + arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); + return arch.IsValid(); + } + else if (idx == 1) + { + ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); + ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); + if (platform_arch == platform_arch64) + { + // This freebsd platform supports both 32 and 64 bit. Since we already + // returned the 64 bit arch for idx == 0, return the 32 bit arch + // for idx == 1 + arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); + return arch.IsValid(); + } + } + return false; +} + +void +PlatformFreeBSD::GetStatus (Stream &strm) +{ + struct utsname un; + + if (uname(&un)) { + strm << "FreeBSD"; + return; + } + + strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n'; + Platform::GetStatus(strm); } Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h?rev=139338&r1=139337&r2=139338&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (original) +++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h Thu Sep 8 19:10:04 2011 @@ -16,97 +16,154 @@ // Project includes #include "lldb/Target/Platform.h" -namespace lldb_private { +class PlatformFreeBSD : public lldb_private::Platform +{ +public: + // Mostly taken from PlatformDarwin and PlatformMacOSX + + //------------------------------------------------------------ + // Class functions + //------------------------------------------------------------ + static lldb_private::Platform* + CreateInstance (); + + static void + Initialize (); + + static void + Terminate (); + + static const char * + GetPluginNameStatic(); + + static const char * + GetShortPluginNameStatic(bool is_host); + + static const char * + GetDescriptionStatic(bool is_host); + + //------------------------------------------------------------ + // Class Methods + //------------------------------------------------------------ + PlatformFreeBSD (bool is_host); + + virtual + ~PlatformFreeBSD(); + + //------------------------------------------------------------ + // lldb_private::PluginInterface functions + //------------------------------------------------------------ + virtual const char * + GetPluginName() + { + return GetPluginNameStatic(); + } + + virtual const char * + GetShortPluginName() + { + return GetShortPluginNameStatic (IsHost()); + } - class PlatformFreeBSD : public Platform + virtual uint32_t + GetPluginVersion() { - public: + return 1; + } - static void - Initialize (); + virtual const char * + GetDescription () + { + return GetDescriptionStatic(IsHost()); + } - static void - Terminate (); - - PlatformFreeBSD (bool is_host); - - virtual - ~PlatformFreeBSD(); - - //------------------------------------------------------------ - // lldb_private::PluginInterface functions - //------------------------------------------------------------ - static Platform * - CreateInstance (); - - static const char * - GetPluginNameStatic(); - - static const char * - GetShortPluginNameStatic(bool is_host); - - static const char * - GetDescriptionStatic(bool is_host); - - virtual const char * - GetPluginName() - { - return GetPluginNameStatic(); - } - - virtual const char * - GetShortPluginName() - { - return GetShortPluginNameStatic (IsHost()); - } - - virtual uint32_t - GetPluginVersion() - { - return 1; - } - - //------------------------------------------------------------ - // lldb_private::Platform functions - //------------------------------------------------------------ - virtual Error - ResolveExecutable (const FileSpec &exe_file, - const ArchSpec &arch, - lldb::ModuleSP &module_sp); - - virtual const char * - GetDescription () - { - return GetDescriptionStatic(IsHost()); - } - - virtual void - GetStatus (Stream &strm); - - virtual Error - GetFile (const FileSpec &platform_file, - const UUID* uuid, FileSpec &local_file); - - virtual bool - GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); - - virtual bool - GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch); - - virtual size_t - GetSoftwareBreakpointTrapOpcode (Target &target, - BreakpointSite *bp_site); - - virtual lldb::ProcessSP - Attach(lldb::pid_t pid, Debugger &debugger, Target *target, - Listener &listener, Error &error); - - protected: - - - private: - DISALLOW_COPY_AND_ASSIGN (PlatformFreeBSD); - }; -} // namespace lldb_private + //------------------------------------------------------------ + // lldb_private::Platform functions + //------------------------------------------------------------ + virtual lldb_private::Error + ResolveExecutable (const lldb_private::FileSpec &exe_file, + const lldb_private::ArchSpec &arch, + lldb::ModuleSP &module_sp); + + virtual size_t + GetSoftwareBreakpointTrapOpcode (lldb_private::Target &target, + lldb_private::BreakpointSite *bp_site); + + virtual bool + GetRemoteOSVersion (); + + virtual bool + GetRemoteOSBuildString (std::string &s); + + virtual bool + GetRemoteOSKernelDescription (std::string &s); + + // Remote Platform subclasses need to override this function + virtual lldb_private::ArchSpec + GetRemoteSystemArchitecture (); + + virtual bool + IsConnected () const; + + virtual lldb_private::Error + ConnectRemote (lldb_private::Args& args); + + virtual lldb_private::Error + DisconnectRemote (); + + virtual const char * + GetHostname (); + + virtual const char * + GetUserName (uint32_t uid); + + virtual const char * + GetGroupName (uint32_t gid); + + virtual bool + GetProcessInfo (lldb::pid_t pid, + lldb_private::ProcessInstanceInfo &proc_info); + + virtual uint32_t + FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info, + lldb_private::ProcessInstanceInfoList &process_infos); + + virtual lldb_private::Error + LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); + + virtual lldb::ProcessSP + Attach(lldb::pid_t pid, + lldb_private::Debugger &debugger, + lldb_private::Target *target, + lldb_private::Listener &listener, + lldb_private::Error &error); + + // Only on PlatformMacOSX: + virtual lldb_private::Error + GetFile (const lldb_private::FileSpec &platform_file, + const lldb_private::UUID* uuid, lldb_private::FileSpec &local_file); + + lldb_private::Error + GetSharedModule (const lldb_private::FileSpec &platform_file, + const lldb_private::ArchSpec &arch, + const lldb_private::UUID *uuid_ptr, + const lldb_private::ConstString *object_name_ptr, + off_t object_offset, + lldb::ModuleSP &module_sp, + lldb::ModuleSP *old_module_sp_ptr, + bool *did_create_ptr); + + virtual bool + GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch); + + virtual void + GetStatus (lldb_private::Stream &strm); + +protected: + lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote freebsd OS + +private: + DISALLOW_COPY_AND_ASSIGN (PlatformFreeBSD); +}; #endif // liblldb_PlatformFreeBSD_h_ From johnny.chen at apple.com Thu Sep 8 19:20:12 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 00:20:12 -0000 Subject: [Lldb-commits] [lldb] r139342 - /lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Message-ID: <20110909002012.2B4C02A6C12C@llvm.org> Author: johnny Date: Thu Sep 8 19:20:12 2011 New Revision: 139342 URL: http://llvm.org/viewvc/llvm-project?rev=139342&view=rev Log: Patch from Pilipe to allow "target create" on the remote-macosx platform! Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=139342&r1=139341&r2=139342&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Thu Sep 8 19:20:12 2011 @@ -87,7 +87,17 @@ exe_module_sp); } else - error.SetErrorString ("the platform is not currently connected"); + { + // We may connect to a process and use the provided executable (Don't use local $PATH). + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle (resolved_exe_file); + + if (resolved_exe_file.Exists()) + error.Clear(); + else + error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root."); + } } From johnny.chen at apple.com Thu Sep 8 19:23:04 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 08 Sep 2011 17:23:04 -0700 Subject: [Lldb-commits] [lldb-dev] Fwd: FreeBSD fixes In-Reply-To: References: Message-ID: <3CAAD3D2-0AF6-4598-AFE7-BDFB19234934@apple.com> Patches applied, thanks! 139338 and 139342. On Sep 8, 2011, at 3:58 PM, Filipe Cabecinhas wrote: > Hi, I tried sending this message earlier, but it seems it got lost along the way. > > I'm re-sending the patch for allowing "target create" on the remote-macosx platform and another patch to augment the FreeBSD platform and make it like the Mac OS X platform. > In order to make the FreeBSD platform we will have to, either implement a local platform (like the Linux one) or implement debugserver on FreeBSD. I'm leaning on the second solution as it would offer us remote debugging for free. > > I just want to confirm something: Is debugserver portable? I'm supposing debugserver is MacOSX specific, but I may be looking at the wrong parts of the code. > > Thanks, > > Filipe > > > _______________________________________________ > lldb-dev mailing list > lldb-dev at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/95c33f26/attachment.html From granata.enrico at gmail.com Thu Sep 8 20:41:30 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Fri, 09 Sep 2011 01:41:30 -0000 Subject: [Lldb-commits] [lldb] r139345 - /lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Message-ID: <20110909014130.8CA632A6C12C@llvm.org> Author: enrico Date: Thu Sep 8 20:41:30 2011 New Revision: 139345 URL: http://llvm.org/viewvc/llvm-project?rev=139345&view=rev Log: Fixing an issue with Python commands defined interactively Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=139345&r1=139344&r2=139345&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Thu Sep 8 20:41:30 2011 @@ -1304,7 +1304,7 @@ // Create the function name & definition string. - sstr.Printf ("def %s (debugger, args, dict):", auto_generated_function_name.c_str()); + sstr.Printf ("def %s (debugger, args, result, dict):", auto_generated_function_name.c_str()); auto_generated_function.AppendString (sstr.GetData()); // Pre-pend code for setting up the session dictionary. From filcab at gmail.com Thu Sep 8 17:13:05 2011 From: filcab at gmail.com (Filipe Cabecinhas) Date: Thu, 8 Sep 2011 15:13:05 -0700 Subject: [Lldb-commits] FreeBSD fixes Message-ID: Hi, I'm re-sending the patch for allowing "target create" on the remote-macosx platform and another patch to augment the FreeBSD platform and make it like the Mac OS X platform. In order to make the FreeBSD platform we will have to, either implement a local platform (like the Linux one) or implement debugserver on FreeBSD. I'm leaning on the second solution as it would offer us remote debugging for free. I just want to confirm something: Is debugserver portable? I'm supposing debugserver is MacOSX specific, but I may be looking at the wrong parts of the code. Thanks, Filipe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/9870ee81/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: freebsd-platform.patch Type: application/octet-stream Size: 27302 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/9870ee81/attachment-0002.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: darwin-remote-fix.patch Type: application/octet-stream Size: 1017 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/9870ee81/attachment-0003.obj From filcab+lldb-dev at gmail.com Thu Sep 8 17:58:14 2011 From: filcab+lldb-dev at gmail.com (Filipe Cabecinhas) Date: Thu, 8 Sep 2011 15:58:14 -0700 Subject: [Lldb-commits] Fwd: FreeBSD fixes In-Reply-To: References: Message-ID: Hi, I tried sending this message earlier, but it seems it got lost along the way. I'm re-sending the patch for allowing "target create" on the remote-macosx platform and another patch to augment the FreeBSD platform and make it like the Mac OS X platform. In order to make the FreeBSD platform we will have to, either implement a local platform (like the Linux one) or implement debugserver on FreeBSD. I'm leaning on the second solution as it would offer us remote debugging for free. I just want to confirm something: Is debugserver portable? I'm supposing debugserver is MacOSX specific, but I may be looking at the wrong parts of the code. Thanks, Filipe -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/ec8af2e4/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: freebsd-platform.patch Type: application/octet-stream Size: 27302 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/ec8af2e4/attachment-0002.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: darwin-remote-fix.patch Type: application/octet-stream Size: 1017 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/lldb-commits/attachments/20110908/ec8af2e4/attachment-0003.obj From granata.enrico at gmail.com Fri Sep 9 11:47:15 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Fri, 09 Sep 2011 16:47:15 -0000 Subject: [Lldb-commits] [lldb] r139372 - /lldb/trunk/examples/synthetic/objc.py Message-ID: <20110909164715.D993A2A6C12C@llvm.org> Author: enrico Date: Fri Sep 9 11:47:15 2011 New Revision: 139372 URL: http://llvm.org/viewvc/llvm-project?rev=139372&view=rev Log: Objective-C runtime wrapper Added: lldb/trunk/examples/synthetic/objc.py Added: lldb/trunk/examples/synthetic/objc.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/objc.py?rev=139372&view=auto ============================================================================== --- lldb/trunk/examples/synthetic/objc.py (added) +++ lldb/trunk/examples/synthetic/objc.py Fri Sep 9 11:47:15 2011 @@ -0,0 +1,128 @@ +""" +Objective-C runtime wrapper - Replicates the behavior of AppleObjCRuntimeV2.cpp in Python code +for the benefit of synthetic children providers and Python summaries + +part of The LLVM Compiler Infrastructure +This file is distributed under the University of Illinois Open Source +License. See LICENSE.TXT for details. +""" +import lldb + +class ObjCRuntime: + + def __init__(self,valobj = None): + self.valobj = valobj; + self.adjust_for_architecture() + + def adjust_for_architecture(self): + self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8) + self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle) + self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize() + self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) + self.addr_ptr_type = self.addr_type.GetPointerType() + + def is_tagged(self): + if valobj is None: + return None + ptr_value = self.valobj.GetPointerValue() + if (ptr_value % 2) == 1: + return True + else: + return False + + def read_ascii(self, pointer): + process = self.valobj.GetTarget().GetProcess() + error = lldb.SBError() + pystr = '' + # cannot do the read at once because there is no length byte + while True: + content = process.ReadMemory(pointer, 1, error) + new_bytes = bytearray(content) + b0 = new_bytes[0] + pointer = pointer + 1 + if b0 == 0: + break + pystr = pystr + chr(b0) + return pystr + + def read_isa(self): + # read ISA pointer + isa_pointer = self.valobj.CreateChildAtOffset("cfisa", + 0, + self.addr_ptr_type) + if isa_pointer == None or isa_pointer.IsValid() == False: + return None; + if isa_pointer.GetValue() == None: + return None; + isa = int(isa_pointer.GetValue(), 0) + if isa == 0 or isa == None: + return None; + return isa + + + def get_parent_class(self, isa = None): + if isa is None: + isa = self.read_isa() + # read superclass pointer + rw_pointer = isa + self.pointer_size + rw_object = self.valobj.CreateValueFromAddress("parent_isa", + rw_pointer, + self.addr_type) + if rw_object == None or rw_object.IsValid() == False: + return None; + if rw_object.GetValue() == None: + return None; + rw = int(rw_object.GetValue(), 0) + if rw == 0 or rw == None: + return None; + return rw + + def get_class_name(self, isa = None): + if isa is None: + isa = self.read_isa() + # read rw pointer + rw_pointer = isa + 4 * self.pointer_size + rw_object = self.valobj.CreateValueFromAddress("rw", + rw_pointer, + self.addr_type) + if rw_object == None or rw_object.IsValid() == False: + return None; + if rw_object.GetValue() == None: + return None; + rw = int(rw_object.GetValue(), 0) + if rw == 0 or rw == None: + return None; + + # read data pointer + data_pointer = rw + 8 + data_object = self.valobj.CreateValueFromAddress("data", + data_pointer, + self.addr_type) + if data_object == None or data_object.IsValid() == False: + return None; + if data_object.GetValue() == None: + return None; + data = int(data_object.GetValue(), 0) + if data == 0 or data == None: + return None; + + # read ro pointer + ro_pointer = data + 12 + self.pointer_size + if self.lp64: + ro_pointer += 4 + ro_object = self.valobj.CreateValueFromAddress("ro", + ro_pointer, + self.addr_type) + if ro_object == None or ro_object.IsValid() == False: + return None; + if ro_object.GetValue() == None: + return None; + name_pointer = int(ro_object.GetValue(), 0) + if name_pointer == 0 or name_pointer == None: + return None; + + # now read the actual name and compare it to known stuff + name_string = self.read_ascii(name_pointer) + if (name_string.startswith("NSKVONotify")): + return self.get_class_name(self.get_parent_class()) + return name_string From johnny.chen at apple.com Fri Sep 9 12:37:06 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 17:37:06 -0000 Subject: [Lldb-commits] [lldb] r139376 - /lldb/trunk/scripts/Python/build-swig-Python.sh Message-ID: <20110909173706.C61C72A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 12:37:06 2011 New Revision: 139376 URL: http://llvm.org/viewvc/llvm-project?rev=139376&view=rev Log: Fixed the error message: ./build-swig-Python.sh: line 76: INTERFACE_FILES: command not found when running SWIG, which was introduced during the last checkin. Modified: lldb/trunk/scripts/Python/build-swig-Python.sh Modified: lldb/trunk/scripts/Python/build-swig-Python.sh URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=139376&r1=139375&r2=139376&view=diff ============================================================================== --- lldb/trunk/scripts/Python/build-swig-Python.sh (original) +++ lldb/trunk/scripts/Python/build-swig-Python.sh Fri Sep 9 12:37:06 2011 @@ -73,39 +73,39 @@ " ${SRC_ROOT}/include/lldb/API/SBValue.h"\ " ${SRC_ROOT}/include/lldb/API/SBValueList.h" -INTERFACE_FILES = "${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\ -" ${SRC_ROOT}/scripts/Python/interface/SBBlock.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBBreakpoint.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBBreakpointLocation.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBBroadcaster.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBCommandInterpreter.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBCommandReturnObject.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBCommunication.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBCompileUnit.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBData.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBDebugger.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBError.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBEvent.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBFileSpec.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBFrame.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBFunction.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBHostOS.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBInputReader.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBInstruction.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBInstructionList.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBLineEntry.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBListener.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBModule.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBProcess.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBSourceManager.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBStream.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBStringList.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBSymbol.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBSymbolContext.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBTarget.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBThread.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBType.i" \ -" ${SRC_ROOT}/scripts/Python/interface/SBValue.i" \ +INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBBlock.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBBreakpoint.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBBreakpointLocation.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBBroadcaster.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBCommandInterpreter.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBCommandReturnObject.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBCommunication.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBCompileUnit.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBData.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBDebugger.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBError.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBEvent.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBFileSpec.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBFrame.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBFunction.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBHostOS.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBInputReader.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBInstruction.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBInstructionList.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBLineEntry.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBListener.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBModule.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBProcess.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBSourceManager.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBStream.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBStringList.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBSymbol.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBSymbolContext.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBTarget.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBThread.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBType.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBValue.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBValueList.i" if [ $Debug == 1 ] From granata.enrico at gmail.com Fri Sep 9 12:49:36 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Fri, 09 Sep 2011 17:49:36 -0000 Subject: [Lldb-commits] [lldb] r139377 - in /lldb/trunk: include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectHelp.cpp source/Commands/CommandObjectHelp.h source/Interpreter/CommandInterpreter.cpp test/functionalities/alias/TestAliases.py test/functionalities/command_python/TestCommandPython.py test/help/TestHelp.py Message-ID: <20110909174936.B38242A6C12C@llvm.org> Author: enrico Date: Fri Sep 9 12:49:36 2011 New Revision: 139377 URL: http://llvm.org/viewvc/llvm-project?rev=139377&view=rev Log: Adding two new options to the 'help' command: --show-aliases (-a) shows aliases for commands, as well as built-in commands --hide-user-defined (-u) hides user defined commands by default 'help' without arguments does not show aliases anymore. to see them, add --show-aliases to have only built-in commands appear, use 'help --hide-user-defined' ; there is currently no way to hide built-in commands from the help output 'help command' is not changed by this commit, and help is shown even if command is an alias and -a is not specified Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h lldb/trunk/source/Commands/CommandObjectHelp.cpp lldb/trunk/source/Commands/CommandObjectHelp.h lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/test/functionalities/alias/TestAliases.py lldb/trunk/test/functionalities/command_python/TestCommandPython.py lldb/trunk/test/help/TestHelp.py Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original) +++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Fri Sep 9 12:49:36 2011 @@ -259,7 +259,7 @@ void GetHelp (CommandReturnObject &result, - CommandTypes types = eCommandTypesAllThem); + uint32_t types = eCommandTypesAllThem); void GetAliasHelp (const char *alias_name, Modified: lldb/trunk/source/Commands/CommandObjectHelp.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.cpp?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectHelp.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectHelp.cpp Fri Sep 9 12:49:36 2011 @@ -29,7 +29,7 @@ CommandObject (interpreter, "help", "Show a list of all debugger commands, or give details about specific commands.", - "help []") + "help []"), m_options (interpreter) { CommandArgumentEntry arg; CommandArgumentData command_arg; @@ -49,6 +49,14 @@ { } +OptionDefinition +CommandObjectHelp::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "show-aliases", 'a', no_argument, NULL, 0, eArgTypeNone, "Show aliases in the command list."}, + { LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', no_argument, NULL, 0, eArgTypeNone, "Hide user-defined commands from the list."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + bool CommandObjectHelp::Execute (Args& command, CommandReturnObject &result) { @@ -56,12 +64,18 @@ CommandObject *cmd_obj; const int argc = command.GetArgumentCount (); - // 'help' doesn't take any options or arguments, other than command names. If argc is 0, we show the user - // all commands and aliases. Otherwise every argument must be the name of a command or a sub-command. + // 'help' doesn't take any arguments, other than command names. If argc is 0, we show the user + // all commands (aliases and user commands if asked for). Otherwise every argument must be the name of a command or a sub-command. if (argc == 0) { + uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin; + if (m_options.m_show_aliases) + cmd_types |= CommandInterpreter::eCommandTypesAliases; + if (m_options.m_show_user_defined) + cmd_types |= CommandInterpreter::eCommandTypesUserDef; + result.SetStatus (eReturnStatusSuccessFinishNoResult); - m_interpreter.GetHelp (result); // General help, for ALL commands. + m_interpreter.GetHelp (result, cmd_types); // General help } else { Modified: lldb/trunk/source/Commands/CommandObjectHelp.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.h?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectHelp.h (original) +++ lldb/trunk/source/Commands/CommandObjectHelp.h Fri Sep 9 12:49:36 2011 @@ -15,6 +15,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/Options.h" namespace lldb_private { @@ -43,6 +44,71 @@ int max_return_elements, bool &word_complete, StringList &matches); + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + } + + virtual + ~CommandOptions (){} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'a': + m_show_aliases = true; + break; + case 'u': + m_show_user_defined = false; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_show_aliases = false; + m_show_user_defined = true; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_show_aliases; + bool m_show_user_defined; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } }; Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Fri Sep 9 12:49:36 2011 @@ -701,7 +701,7 @@ void CommandInterpreter::GetHelp (CommandReturnObject &result, - CommandTypes cmd_types) + uint32_t cmd_types) { CommandObject::CommandMap::const_iterator pos; uint32_t max_len = FindLongestCommandWord (m_command_dict); Modified: lldb/trunk/test/functionalities/alias/TestAliases.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/alias/TestAliases.py?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/test/functionalities/alias/TestAliases.py (original) +++ lldb/trunk/test/functionalities/alias/TestAliases.py Fri Sep 9 12:49:36 2011 @@ -90,6 +90,14 @@ self.expect ("help run", substrs = [ "'run' is an abbreviation for 'process launch --'" ]) + self.expect ("help -a run", + substrs = [ "'run' is an abbreviation for 'process launch --'" ]) + + self.expect ("help -a", + substrs = [ 'run', 'process launch' ]) + + self.expect ("help", matching=False, + substrs = [ "'run'", 'process launch' ]) self.expect ("run", patterns = [ "Process .* launched: .*a.out" ]) Modified: lldb/trunk/test/functionalities/command_python/TestCommandPython.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/command_python/TestCommandPython.py?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/test/functionalities/command_python/TestCommandPython.py (original) +++ lldb/trunk/test/functionalities/command_python/TestCommandPython.py Fri Sep 9 12:49:36 2011 @@ -38,6 +38,18 @@ substrs = ['Just a docstring for welcome_impl', 'A command that says hello to LLDB users']) + self.expect("help", + substrs = ['Run Python function welcome.welcome_impl', + 'welcome']) + + self.expect("help -a", + substrs = ['Run Python function welcome.welcome_impl', + 'welcome']) + + self.expect("help -u", matching=False, + substrs = ['Run Python function welcome.welcome_impl', + 'welcome']) + self.runCmd("command script delete welcome"); self.expect('welcome Enrico', matching=False, error=True, Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=139377&r1=139376&r2=139377&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Fri Sep 9 12:49:36 2011 @@ -18,6 +18,18 @@ self.expect("help", startstr = 'The following is a list of built-in, permanent debugger commands') + self.expect("help", matching=False, + substrs = ['next']) + + self.expect("help -a", matching=True, + substrs = ['next']) + + def test_help_on_help(self): + """Testing the help on the help facility.""" + self.expect("help help", matching=True, + substrs = ['--show-aliases', + '--hide-user-commands']) + def version_number_string(self): """Helper function to find the version number string of lldb.""" plist = os.path.join(os.environ["LLDB_SRC"], "resources", "LLDB-Info.plist") From gclayton at apple.com Fri Sep 9 15:33:05 2011 From: gclayton at apple.com (Greg Clayton) Date: Fri, 09 Sep 2011 20:33:05 -0000 Subject: [Lldb-commits] [lldb] r139401 - in /lldb/trunk: lldb.xcodeproj/project.pbxproj source/Plugins/ObjectFile/PECOFF/ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h source/lldb.cpp Message-ID: <20110909203305.96EC22A6C12C@llvm.org> Author: gclayton Date: Fri Sep 9 15:33:05 2011 New Revision: 139401 URL: http://llvm.org/viewvc/llvm-project?rev=139401&view=rev Log: Added first pass at PE COFF file reading support. It parses the sections correctly, symbols are coming soon. It also needs to be 32/64 bit hardened with more testing. Added: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/lldb.cpp Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=139401&r1=139400&r2=139401&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 9 15:33:05 2011 @@ -384,6 +384,7 @@ 26DE20611161902700A093E2 /* SBBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20601161902600A093E2 /* SBBlock.cpp */; }; 26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20621161904200A093E2 /* SBLineEntry.cpp */; }; 26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DE20641161904E00A093E2 /* SBSymbol.cpp */; }; + 26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E152231419CACA007967D0 /* ObjectFilePECOFF.cpp */; }; 26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.cpp */; }; 26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26ED3D6C13C563810017D45E /* OptionGroupVariable.cpp */; }; 26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F4A21A13FBA31A0064B613 /* ThreadMemory.cpp */; }; @@ -1060,6 +1061,8 @@ 26DFBC57113B48F300DD817F /* CommandObjectCrossref.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectCrossref.cpp; path = source/Commands/CommandObjectCrossref.cpp; sourceTree = ""; }; 26DFBC58113B48F300DD817F /* CommandObjectMultiword.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectMultiword.cpp; path = source/Commands/CommandObjectMultiword.cpp; sourceTree = ""; }; 26DFBC59113B48F300DD817F /* CommandObjectRegexCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectRegexCommand.cpp; path = source/Interpreter/CommandObjectRegexCommand.cpp; sourceTree = ""; }; + 26E152231419CACA007967D0 /* ObjectFilePECOFF.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectFilePECOFF.cpp; sourceTree = ""; }; + 26E152241419CACA007967D0 /* ObjectFilePECOFF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjectFilePECOFF.h; sourceTree = ""; }; 26E3EEBD11A9870400FBADB6 /* Unwind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Unwind.h; path = include/lldb/Target/Unwind.h; sourceTree = ""; }; 26E3EEE311A9901300FBADB6 /* UnwindMacOSXFrameBackchain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindMacOSXFrameBackchain.cpp; path = Utility/UnwindMacOSXFrameBackchain.cpp; sourceTree = ""; }; 26E3EEE411A9901300FBADB6 /* UnwindMacOSXFrameBackchain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindMacOSXFrameBackchain.h; path = Utility/UnwindMacOSXFrameBackchain.h; sourceTree = ""; }; @@ -1494,6 +1497,7 @@ children = ( 260C898310F57C5600BB2B04 /* ELF */, 260C898710F57C5600BB2B04 /* Mach-O */, + 26E152221419CACA007967D0 /* PECOFF */, ); path = ObjectFile; sourceTree = ""; @@ -2553,6 +2557,15 @@ name = "lldb-platform"; sourceTree = ""; }; + 26E152221419CACA007967D0 /* PECOFF */ = { + isa = PBXGroup; + children = ( + 26E152231419CACA007967D0 /* ObjectFilePECOFF.cpp */, + 26E152241419CACA007967D0 /* ObjectFilePECOFF.h */, + ); + path = PECOFF; + sourceTree = ""; + }; 26F5C22410F3D950009D5894 /* Tools */ = { isa = PBXGroup; children = ( @@ -3344,6 +3357,7 @@ 268ED0A5140FF54200DE830F /* DataEncoder.cpp in Sources */, 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */, B27318421416AC12006039C8 /* WatchpointLocationList.cpp in Sources */, + 26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Added: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=139401&view=auto ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (added) +++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Fri Sep 9 15:33:05 2011 @@ -0,0 +1,805 @@ +//===-- ObjectFilePECOFF.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ObjectFilePECOFF.h" + +#include "llvm/Support/MachO.h" + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBuffer.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/Timer.h" +#include "lldb/Core/UUID.h" +#include "lldb/Symbol/ObjectFile.h" + +static uint32_t COFFMachineToMachCPU(uint16_t machine); + +#define IMAGE_FILE_MACHINE_UNKNOWN 0x0000 +#define IMAGE_FILE_MACHINE_AM33 0x01d3 // Matsushita AM33 +#define IMAGE_FILE_MACHINE_AMD64 0x8664 // x64 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little endian +#define IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI byte code +#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386 or later processors and compatible processors +#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel Itanium processor family +#define IMAGE_FILE_MACHINE_M32R 0x9041 // Mitsubishi M32R little endian +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS16 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS with FPU +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS16 with FPU +#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 // Power PC little endian +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 // Power PC with floating point support +#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little endian +#define IMAGE_FILE_MACHINE_SH3 0x01a2 // Hitachi SH3 +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 // Hitachi SH3 DSP +#define IMAGE_FILE_MACHINE_SH4 0x01a6 // Hitachi SH4 +#define IMAGE_FILE_MACHINE_SH5 0x01a8 // Hitachi SH5 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // Thumb +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 + + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_OS2_SIGNATURE 0x454E // NE +#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define OPT_HEADER_MAGIC_PE32 0x010b +#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +//#define 0x0040 // Reserved +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +using namespace lldb; +using namespace lldb_private; + +void +ObjectFilePECOFF::Initialize() +{ + PluginManager::RegisterPlugin (GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void +ObjectFilePECOFF::Terminate() +{ + PluginManager::UnregisterPlugin (CreateInstance); +} + + +const char * +ObjectFilePECOFF::GetPluginNameStatic() +{ + return "object-file.pe-coff"; +} + +const char * +ObjectFilePECOFF::GetPluginDescriptionStatic() +{ + return "Portable Executable and Common Object File Format object file reader (32 and 64 bit)"; +} + + +ObjectFile * +ObjectFilePECOFF::CreateInstance (Module* module, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length) +{ + if (ObjectFilePECOFF::MagicBytesMatch(dataSP)) + { + std::auto_ptr objfile_ap(new ObjectFilePECOFF (module, dataSP, file, offset, length)); + if (objfile_ap.get() && objfile_ap->ParseHeader()) + return objfile_ap.release(); + } + return NULL; +} + +bool +ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP) +{ + DataExtractor data(dataSP, eByteOrderLittle, 4); + uint32_t offset = 0; + uint16_t magic = data.GetU16 (&offset); + return magic == IMAGE_DOS_SIGNATURE; +} + + +ObjectFilePECOFF::ObjectFilePECOFF (Module* module, + DataBufferSP& dataSP, + const FileSpec* file, + addr_t offset, + addr_t length) : + ObjectFile (module, file, offset, length, dataSP), + m_mutex (Mutex::eMutexTypeRecursive), + m_dos_header (), + m_coff_header (), + m_coff_header_opt (), + m_sect_headers () +{ + ::memset (&m_dos_header, 0, sizeof(m_dos_header)); + ::memset (&m_coff_header, 0, sizeof(m_coff_header)); + ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); +} + + +ObjectFilePECOFF::~ObjectFilePECOFF() +{ +} + + +bool +ObjectFilePECOFF::ParseHeader () +{ + Mutex::Locker locker(m_mutex); + m_sect_headers.clear(); + m_data.SetByteOrder (eByteOrderLittle); + uint32_t offset = 0; + + if (ParseDOSHeader()) + { + offset = m_dos_header.e_lfanew; + uint32_t pe_signature = m_data.GetU32 (&offset); + if (pe_signature != IMAGE_NT_SIGNATURE) + return false; + } + if (ParseCOFFHeader(&offset)) + { + if (m_coff_header.hdrsize > 0) + ParseCOFFOptionalHeader(&offset); + ParseSectionHeaders (offset); + return true; + } + return false; +} + + +ByteOrder +ObjectFilePECOFF::GetByteOrder () const +{ + return eByteOrderLittle; +} + +bool +ObjectFilePECOFF::IsExecutable() const +{ + return (m_coff_header.flags & IMAGE_FILE_DLL) == 0; +} + +size_t +ObjectFilePECOFF::GetAddressByteSize () const +{ + if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS) + return 8; + else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) + return 4; + return 4; +} + +//---------------------------------------------------------------------- +// NeedsEndianSwap +// +// Return true if an endian swap needs to occur when extracting data +// from this file. +//---------------------------------------------------------------------- +bool +ObjectFilePECOFF::NeedsEndianSwap() const +{ +#if defined(__LITTLE_ENDIAN__) + return false; +#else + return true; +#endif +} +//---------------------------------------------------------------------- +// ParseDOSHeader +//---------------------------------------------------------------------- +bool +ObjectFilePECOFF::ParseDOSHeader () +{ + bool success = false; + uint32_t offset = 0; + success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header)); + + if (success) + { + m_dos_header.e_magic = m_data.GetU16(&offset); // Magic number + success = m_dos_header.e_magic == IMAGE_DOS_SIGNATURE; + + if (success) + { + m_dos_header.e_cblp = m_data.GetU16(&offset); // Bytes on last page of file + m_dos_header.e_cp = m_data.GetU16(&offset); // Pages in file + m_dos_header.e_crlc = m_data.GetU16(&offset); // Relocations + m_dos_header.e_cparhdr = m_data.GetU16(&offset); // Size of header in paragraphs + m_dos_header.e_minalloc = m_data.GetU16(&offset); // Minimum extra paragraphs needed + m_dos_header.e_maxalloc = m_data.GetU16(&offset); // Maximum extra paragraphs needed + m_dos_header.e_ss = m_data.GetU16(&offset); // Initial (relative) SS value + m_dos_header.e_sp = m_data.GetU16(&offset); // Initial SP value + m_dos_header.e_csum = m_data.GetU16(&offset); // Checksum + m_dos_header.e_ip = m_data.GetU16(&offset); // Initial IP value + m_dos_header.e_cs = m_data.GetU16(&offset); // Initial (relative) CS value + m_dos_header.e_lfarlc = m_data.GetU16(&offset); // File address of relocation table + m_dos_header.e_ovno = m_data.GetU16(&offset); // Overlay number + + m_dos_header.e_res[0] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res[1] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res[2] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res[3] = m_data.GetU16(&offset); // Reserved words + + m_dos_header.e_oemid = m_data.GetU16(&offset); // OEM identifier (for e_oeminfo) + m_dos_header.e_oeminfo = m_data.GetU16(&offset); // OEM information; e_oemid specific + m_dos_header.e_res2[0] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[1] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[2] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[3] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[4] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[5] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[6] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[7] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[8] = m_data.GetU16(&offset); // Reserved words + m_dos_header.e_res2[9] = m_data.GetU16(&offset); // Reserved words + + m_dos_header.e_lfanew = m_data.GetU32(&offset); // File address of new exe header + } + } + if (!success) + memset(&m_dos_header, 0, sizeof(m_dos_header)); + return success; +} + + +//---------------------------------------------------------------------- +// ParserCOFFHeader +//---------------------------------------------------------------------- +bool +ObjectFilePECOFF::ParseCOFFHeader(uint32_t* offset_ptr) +{ + bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header)); + if (success) + { + m_coff_header.machine = m_data.GetU16(offset_ptr); + m_coff_header.nsects = m_data.GetU16(offset_ptr); + m_coff_header.modtime = m_data.GetU32(offset_ptr); + m_coff_header.symoff = m_data.GetU32(offset_ptr); + m_coff_header.nsyms = m_data.GetU32(offset_ptr); + m_coff_header.hdrsize = m_data.GetU16(offset_ptr); + m_coff_header.flags = m_data.GetU16(offset_ptr); + } + if (!success) + memset(&m_coff_header, 0, sizeof(m_coff_header)); + return success; +} + +bool +ObjectFilePECOFF::ParseCOFFOptionalHeader(uint32_t* offset_ptr) +{ + bool success = false; + const uint32_t end_offset = *offset_ptr + m_coff_header.hdrsize; + if (*offset_ptr < end_offset) + { + success = true; + m_coff_header_opt.magic = m_data.GetU16(offset_ptr); + m_coff_header_opt.major_linker_version = m_data.GetU8 (offset_ptr); + m_coff_header_opt.minor_linker_version = m_data.GetU8 (offset_ptr); + m_coff_header_opt.code_size = m_data.GetU32(offset_ptr); + m_coff_header_opt.data_size = m_data.GetU32(offset_ptr); + m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr); + m_coff_header_opt.entry = m_data.GetU32(offset_ptr); + m_coff_header_opt.code_offset = m_data.GetU32(offset_ptr); + + const uint32_t addr_byte_size = GetAddressByteSize (); + + if (*offset_ptr < end_offset) + { + if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) + { + // PE32 only + m_coff_header_opt.data_offset = m_data.GetU32(offset_ptr); + } + else + m_coff_header_opt.data_offset = 0; + + if (*offset_ptr < end_offset) + { + m_coff_header_opt.image_base = m_data.GetMaxU64 (offset_ptr, addr_byte_size); + m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr); + m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr); + m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr); + m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr); + m_coff_header_opt.image_size = m_data.GetU32(offset_ptr); + m_coff_header_opt.header_size = m_data.GetU32(offset_ptr); + m_coff_header_opt.checksym = m_data.GetU32(offset_ptr); + m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr); + m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr); + m_coff_header_opt.stack_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); + m_coff_header_opt.stack_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); + m_coff_header_opt.heap_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); + m_coff_header_opt.heap_commit_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); + m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr); + uint32_t num_data_dir_entries = m_data.GetU32(offset_ptr); + m_coff_header_opt.data_dirs.clear(); + m_coff_header_opt.data_dirs.resize(num_data_dir_entries); + uint32_t i; + for (i=0; i 0) + { + const uint32_t addr_byte_size = GetAddressByteSize (); + const size_t section_header_byte_size = nsects * sizeof(section_header_t); + DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size)); + DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size); + + uint32_t offset = 0; + if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size)) + { + m_sect_headers.resize(nsects); + + for (uint32_t idx = 0; idxGetMutex()); + DataExtractor stab_data; + DataExtractor stabstr_data; + static ConstString g_stab_sect_name(".stab"); + static ConstString g_stabstr_sect_name(".stabstr"); + const Section *stab_section = sect_list->FindSectionByName (g_stab_sect_name).get(); + if (stab_section == NULL) + return m_symtab_ap.get(); + const Section *stabstr_section = sect_list->FindSectionByName (g_stabstr_sect_name).get(); + if (stabstr_section == NULL) + return m_symtab_ap.get(); + uint32_t offset = 0; + if (stab_section->ReadSectionDataFromObjectFile (this, stab_data) && + stabstr_section->ReadSectionDataFromObjectFile (this, stabstr_data)) + { + const uint32_t num_syms = stab_data.GetByteSize() / sizeof (coff_symbol_t); + Symbol *symbols = m_symtab_ap->Resize (num_syms); + for (uint32_t i=0; iGetSectionAtIndex(symbol.sect-1).get(), symbol.value); + symbols[i].GetMangled ().SetValue(symbol.name, symbol.name[0]=='_' && symbol.name[1] == 'Z'); + symbols[i].SetValue(symbol_addr); + + if (symbol.naux > 0) + i += symbol.naux; + } + + } + } + return m_symtab_ap.get(); + +} + +SectionList * +ObjectFilePECOFF::GetSectionList() +{ + Mutex::Locker symfile_locker(m_mutex); + if (m_sections_ap.get() == NULL) + { + m_sections_ap.reset(new SectionList()); + const uint32_t nsects = m_sect_headers.size(); + Module *module = GetModule(); + for (uint32_t idx = 0; idxSetIsEncrypted (segment_is_encrypted); + + m_sections_ap->AddSection(section_sp); + } + } + return m_sections_ap.get(); +} + +bool +ObjectFilePECOFF::GetUUID (UUID* uuid) +{ + return false; +} + +uint32_t +ObjectFilePECOFF::GetDependentModules (FileSpecList& files) +{ + return 0; +} + + +//---------------------------------------------------------------------- +// Dump +// +// Dump the specifics of the runtime file container (such as any headers +// segments, sections, etc). +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::Dump(Stream *s) +{ + Mutex::Locker locker(m_mutex); + s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); + s->Indent(); + s->PutCString("ObjectFilePECOFF"); + + ArchSpec header_arch; + GetArchitecture (header_arch); + + *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; + + if (m_sections_ap.get()) + m_sections_ap->Dump(s, NULL, true, UINT32_MAX); + + if (m_symtab_ap.get()) + m_symtab_ap->Dump(s, NULL, eSortOrderNone); + + if (m_dos_header.e_magic) + DumpDOSHeader (s, m_dos_header); + if (m_coff_header.machine) + { + DumpCOFFHeader (s, m_coff_header); + if (m_coff_header.hdrsize) + DumpOptCOFFHeader (s, m_coff_header_opt); + } + s->EOL(); + DumpSectionHeaders(s); + s->EOL(); +} + +//---------------------------------------------------------------------- +// DumpDOSHeader +// +// Dump the MS-DOS header to the specified output stream +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header) +{ + s->PutCString ("MSDOS Header\n"); + s->Printf (" e_magic = 0x%4.4x\n", header.e_magic); + s->Printf (" e_cblp = 0x%4.4x\n", header.e_cblp); + s->Printf (" e_cp = 0x%4.4x\n", header.e_cp); + s->Printf (" e_crlc = 0x%4.4x\n", header.e_crlc); + s->Printf (" e_cparhdr = 0x%4.4x\n", header.e_cparhdr); + s->Printf (" e_minalloc = 0x%4.4x\n", header.e_minalloc); + s->Printf (" e_maxalloc = 0x%4.4x\n", header.e_maxalloc); + s->Printf (" e_ss = 0x%4.4x\n", header.e_ss); + s->Printf (" e_sp = 0x%4.4x\n", header.e_sp); + s->Printf (" e_csum = 0x%4.4x\n", header.e_csum); + s->Printf (" e_ip = 0x%4.4x\n", header.e_ip); + s->Printf (" e_cs = 0x%4.4x\n", header.e_cs); + s->Printf (" e_lfarlc = 0x%4.4x\n", header.e_lfarlc); + s->Printf (" e_ovno = 0x%4.4x\n", header.e_ovno); + s->Printf (" e_res[4] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", + header.e_res[0], + header.e_res[1], + header.e_res[2], + header.e_res[3]); + s->Printf (" e_oemid = 0x%4.4x\n", header.e_oemid); + s->Printf (" e_oeminfo = 0x%4.4x\n", header.e_oeminfo); + s->Printf (" e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n", + header.e_res2[0], + header.e_res2[1], + header.e_res2[2], + header.e_res2[3], + header.e_res2[4], + header.e_res2[5], + header.e_res2[6], + header.e_res2[7], + header.e_res2[8], + header.e_res2[9]); + s->Printf (" e_lfanew = 0x%8.8x\n", header.e_lfanew); +} + +//---------------------------------------------------------------------- +// DumpCOFFHeader +// +// Dump the COFF header to the specified output stream +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header) +{ + s->PutCString ("COFF Header\n"); + s->Printf (" machine = 0x%4.4x\n", header.machine); + s->Printf (" nsects = 0x%4.4x\n", header.nsects); + s->Printf (" modtime = 0x%8.8x\n", header.modtime); + s->Printf (" symoff = 0x%8.8x\n", header.symoff); + s->Printf (" nsyms = 0x%8.8x\n", header.nsyms); + s->Printf (" hdrsize = 0x%4.4x\n", header.hdrsize); +} + +//---------------------------------------------------------------------- +// DumpOptCOFFHeader +// +// Dump the optional COFF header to the specified output stream +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s, const coff_opt_header_t& header) +{ + s->PutCString ("Optional COFF Header\n"); + s->Printf (" magic = 0x%4.4x\n", header.magic); + s->Printf (" major_linker_version = 0x%2.2x\n", header.major_linker_version); + s->Printf (" minor_linker_version = 0x%2.2x\n", header.minor_linker_version); + s->Printf (" code_size = 0x%8.8x\n", header.code_size); + s->Printf (" data_size = 0x%8.8x\n", header.data_size); + s->Printf (" bss_size = 0x%8.8x\n", header.bss_size); + s->Printf (" entry = 0x%8.8x\n", header.entry); + s->Printf (" code_offset = 0x%8.8x\n", header.code_offset); + s->Printf (" data_offset = 0x%8.8x\n", header.data_offset); + s->Printf (" image_base = 0x%16.16llx\n", header.image_base); + s->Printf (" sect_alignment = 0x%8.8x\n", header.sect_alignment); + s->Printf (" file_alignment = 0x%8.8x\n", header.file_alignment); + s->Printf (" major_os_system_version = 0x%4.4x\n", header.major_os_system_version); + s->Printf (" minor_os_system_version = 0x%4.4x\n", header.minor_os_system_version); + s->Printf (" major_image_version = 0x%4.4x\n", header.major_image_version); + s->Printf (" minor_image_version = 0x%4.4x\n", header.minor_image_version); + s->Printf (" major_subsystem_version = 0x%4.4x\n", header.major_subsystem_version); + s->Printf (" minor_subsystem_version = 0x%4.4x\n", header.minor_subsystem_version); + s->Printf (" reserved1 = 0x%8.8x\n", header.reserved1); + s->Printf (" image_size = 0x%8.8x\n", header.image_size); + s->Printf (" header_size = 0x%8.8x\n", header.header_size); + s->Printf (" checksym = 0x%8.8x\n", header.checksym); + s->Printf (" subsystem = 0x%4.4x\n", header.subsystem); + s->Printf (" dll_flags = 0x%4.4x\n", header.dll_flags); + s->Printf (" stack_reserve_size = 0x%16.16llx\n", header.stack_reserve_size); + s->Printf (" stack_commit_size = 0x%16.16llx\n", header.stack_commit_size); + s->Printf (" heap_reserve_size = 0x%16.16llx\n", header.heap_reserve_size); + s->Printf (" heap_commit_size = 0x%16.16llx\n", header.heap_commit_size); + s->Printf (" loader_flags = 0x%8.8x\n", header.loader_flags); + s->Printf (" num_data_dir_entries = 0x%8.8zx\n", header.data_dirs.size()); + uint32_t i; + for (i=0; iPrintf (" data_dirs[%u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", + i, + header.data_dirs[i].vmaddr, + header.data_dirs[i].vmsize); + } +} +//---------------------------------------------------------------------- +// DumpSectionHeader +// +// Dump a single ELF section header to the specified output stream +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::DumpSectionHeader(Stream *s, const section_header_t& sh) +{ + std::string name; + GetSectionName(name, sh); + s->Printf ("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x 0x%4.4x 0x%8.8x\n", + name.c_str(), + sh.vmsize, + sh.vmaddr, + sh.size, + sh.offset, + sh.reloff, + sh.lineoff, + sh.nreloc, + sh.nline, + sh.flags); +} + + +//---------------------------------------------------------------------- +// DumpSectionHeaders +// +// Dump all of the ELF section header to the specified output stream +//---------------------------------------------------------------------- +void +ObjectFilePECOFF::DumpSectionHeaders(Stream *s) +{ + + s->PutCString ("Section Headers\n"); + s->PutCString ("IDX name vm size vm addr size offset reloff lineoff nrel nlin flags\n"); + s->PutCString ("==== ---------------- -------- -------- -------- -------- -------- -------- ---- ---- --------\n"); + + uint32_t idx = 0; + SectionHeaderCollIter pos, end = m_sect_headers.end(); + + for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) + { + s->Printf ("[%2u]", idx); + ObjectFilePECOFF::DumpSectionHeader(s, *pos); + } +} + +static bool +COFFMachineToMachCPU (uint16_t machine, ArchSpec &arch) +{ + switch (machine) + { + case IMAGE_FILE_MACHINE_AMD64: + case IMAGE_FILE_MACHINE_IA64: + arch.SetArchitecture (eArchTypeMachO, + llvm::MachO::CPUTypeX86_64, + llvm::MachO::CPUSubType_X86_64_ALL); + return true; + + case IMAGE_FILE_MACHINE_I386: + arch.SetArchitecture (eArchTypeMachO, + llvm::MachO::CPUTypeI386, + llvm::MachO::CPUSubType_I386_ALL); + return true; + + case IMAGE_FILE_MACHINE_POWERPC: + case IMAGE_FILE_MACHINE_POWERPCFP: + arch.SetArchitecture (eArchTypeMachO, + llvm::MachO::CPUTypePowerPC, + llvm::MachO::CPUSubType_POWERPC_ALL); + return true; + case IMAGE_FILE_MACHINE_ARM: + case IMAGE_FILE_MACHINE_THUMB: + arch.SetArchitecture (eArchTypeMachO, + llvm::MachO::CPUTypeARM, + llvm::MachO::CPUSubType_ARM_V7); + return true; + } + return false; +} +bool +ObjectFilePECOFF::GetArchitecture (ArchSpec &arch) +{ + // For index zero return our cpu type + return COFFMachineToMachCPU (m_coff_header.machine, arch); +} + +ObjectFile::Type +ObjectFilePECOFF::CalculateType() +{ + if (m_coff_header.machine != 0) + { + if ((m_coff_header.flags & IMAGE_FILE_DLL) == 0) + return eTypeExecutable; + else + return eTypeSharedLibrary; + } + return eTypeExecutable; +} + +ObjectFile::Strata +ObjectFilePECOFF::CalculateStrata() +{ + return eStrataUser; +} +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +const char * +ObjectFilePECOFF::GetPluginName() +{ + return "ObjectFilePECOFF"; +} + +const char * +ObjectFilePECOFF::GetShortPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +ObjectFilePECOFF::GetPluginVersion() +{ + return 1; +} + Added: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=139401&view=auto ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (added) +++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Fri Sep 9 15:33:05 2011 @@ -0,0 +1,235 @@ +//===-- ObjectFilePECOFF.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_ObjectFilePECOFF_h_ +#define liblldb_ObjectFilePECOFF_h_ + +#include + +#include "lldb/Host/Mutex.h" +#include "lldb/Symbol/ObjectFile.h" + +class ObjectFilePECOFF : + public lldb_private::ObjectFile +{ +public: + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static const char * + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + static ObjectFile * + CreateInstance (lldb_private::Module* module, + lldb::DataBufferSP& dataSP, + const lldb_private::FileSpec* file, + lldb::addr_t offset, + lldb::addr_t length); + + static bool + MagicBytesMatch (lldb::DataBufferSP& dataSP); + + + ObjectFilePECOFF (lldb_private::Module* module, + lldb::DataBufferSP& dataSP, + const lldb_private::FileSpec* file, + lldb::addr_t offset, + lldb::addr_t length); + + virtual + ~ObjectFilePECOFF(); + + virtual bool + ParseHeader (); + + virtual lldb::ByteOrder + GetByteOrder () const; + + virtual bool + IsExecutable () const; + + virtual size_t + GetAddressByteSize () const; + +// virtual lldb_private::AddressClass +// GetAddressClass (lldb::addr_t file_addr); +// + virtual lldb_private::Symtab * + GetSymtab(); + + virtual lldb_private::SectionList * + GetSectionList(); + + virtual void + Dump (lldb_private::Stream *s); + + virtual bool + GetArchitecture (lldb_private::ArchSpec &arch); + + virtual bool + GetUUID (lldb_private::UUID* uuid); + + virtual uint32_t + GetDependentModules (lldb_private::FileSpecList& files); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual const char * + GetPluginName(); + + virtual const char * + GetShortPluginName(); + + virtual uint32_t + GetPluginVersion(); +// +// virtual lldb_private::Address +// GetEntryPointAddress (); + + virtual ObjectFile::Type + CalculateType(); + + virtual ObjectFile::Strata + CalculateStrata(); + +protected: + bool NeedsEndianSwap() const; + + typedef struct dos_header { // DOS .EXE header + uint16_t e_magic; // Magic number + uint16_t e_cblp; // Bytes on last page of file + uint16_t e_cp; // Pages in file + uint16_t e_crlc; // Relocations + uint16_t e_cparhdr; // Size of header in paragraphs + uint16_t e_minalloc; // Minimum extra paragraphs needed + uint16_t e_maxalloc; // Maximum extra paragraphs needed + uint16_t e_ss; // Initial (relative) SS value + uint16_t e_sp; // Initial SP value + uint16_t e_csum; // Checksum + uint16_t e_ip; // Initial IP value + uint16_t e_cs; // Initial (relative) CS value + uint16_t e_lfarlc; // File address of relocation table + uint16_t e_ovno; // Overlay number + uint16_t e_res[4]; // Reserved words + uint16_t e_oemid; // OEM identifier (for e_oeminfo) + uint16_t e_oeminfo; // OEM information; e_oemid specific + uint16_t e_res2[10]; // Reserved words + uint32_t e_lfanew; // File address of new exe header + } dos_header_t; + + typedef struct coff_header { + uint16_t machine; + uint16_t nsects; + uint32_t modtime; + uint32_t symoff; + uint32_t nsyms; + uint16_t hdrsize; + uint16_t flags; + } coff_header_t; + + typedef struct data_directory { + uint32_t vmaddr; + uint32_t vmsize; + } data_directory_t; + + typedef struct coff_opt_header + { + uint16_t magic; + uint8_t major_linker_version; + uint8_t minor_linker_version; + uint32_t code_size; + uint32_t data_size; + uint32_t bss_size; + uint32_t entry; + uint32_t code_offset; + uint32_t data_offset; + + uint64_t image_base; + uint32_t sect_alignment; + uint32_t file_alignment; + uint16_t major_os_system_version; + uint16_t minor_os_system_version; + uint16_t major_image_version; + uint16_t minor_image_version; + uint16_t major_subsystem_version; + uint16_t minor_subsystem_version; + uint32_t reserved1; + uint32_t image_size; + uint32_t header_size; + uint32_t checksym; + uint16_t subsystem; + uint16_t dll_flags; + uint64_t stack_reserve_size; + uint64_t stack_commit_size; + uint64_t heap_reserve_size; + uint64_t heap_commit_size; + uint32_t loader_flags; + // uint32_t num_data_dir_entries; + std::vector data_dirs; // will contain num_data_dir_entries entries + } coff_opt_header_t; + + typedef struct section_header { + char name[8]; + uint32_t vmsize; // Virtual Size + uint32_t vmaddr; // Virtual Addr + uint32_t size; // File size + uint32_t offset; // File offset + uint32_t reloff; // Offset to relocations + uint32_t lineoff;// Offset to line table entries + uint16_t nreloc; // Number of relocation entries + uint16_t nline; // Number of line table entries + uint32_t flags; + } section_header_t; + + typedef struct coff_symbol { + char name[8]; + uint32_t value; + uint16_t sect; + uint16_t type; + uint8_t storage; + uint8_t naux; + } coff_symbol_t; + + bool ParseDOSHeader (); + bool ParseCOFFHeader (uint32_t* offset_ptr); + bool ParseCOFFOptionalHeader (uint32_t* offset_ptr); + bool ParseSectionHeaders (uint32_t offset); + + static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header); + static void DumpCOFFHeader(lldb_private::Stream *s, const coff_header_t& header); + static void DumpOptCOFFHeader(lldb_private::Stream *s, const coff_opt_header_t& header); + void DumpSectionHeaders(lldb_private::Stream *s); + void DumpSectionHeader(lldb_private::Stream *s, const section_header_t& sh); + bool GetSectionName(std::string& sect_name, const section_header_t& sect); + + typedef std::vector SectionHeaderColl; + typedef SectionHeaderColl::iterator SectionHeaderCollIter; + typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; +private: + mutable lldb_private::Mutex m_mutex; + mutable std::auto_ptr m_sections_ap; + mutable std::auto_ptr m_symtab_ap; + dos_header_t m_dos_header; + coff_header_t m_coff_header; + coff_opt_header_t m_coff_header_opt; + SectionHeaderColl m_sect_headers; +}; + +#endif // #ifndef liblldb_ObjectFilePECOFF_h_ Modified: lldb/trunk/source/lldb.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=139401&r1=139400&r2=139401&view=diff ============================================================================== --- lldb/trunk/source/lldb.cpp (original) +++ lldb/trunk/source/lldb.cpp Fri Sep 9 15:33:05 2011 @@ -35,7 +35,7 @@ #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" #include "Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h" #include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h" - +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" #if defined (__APPLE__) #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" @@ -94,7 +94,7 @@ UnwindAssemblyInstEmulation::Initialize(); UnwindAssembly_x86::Initialize(); EmulateInstructionARM::Initialize (); - + ObjectFilePECOFF::Initialize (); #if defined (__APPLE__) //---------------------------------------------------------------------- // Apple/Darwin hosted plugins @@ -166,6 +166,7 @@ UnwindAssembly_x86::Terminate(); UnwindAssemblyInstEmulation::Terminate(); EmulateInstructionARM::Terminate (); + ObjectFilePECOFF::Terminate (); #if defined (__APPLE__) DynamicLoaderMacOSXDYLD::Terminate(); From johnny.chen at apple.com Fri Sep 9 15:35:15 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 20:35:15 -0000 Subject: [Lldb-commits] [lldb] r139402 - /lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Message-ID: <20110909203515.7A3922A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 15:35:15 2011 New Revision: 139402 URL: http://llvm.org/viewvc/llvm-project?rev=139402&view=rev Log: Fix compiler warnings for GetGDBStoppointType(). Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=139402&r1=139401&r2=139402&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 9 15:35:15 2011 @@ -1894,9 +1894,9 @@ assert(watch_read || watch_write); if (watch_read && watch_write) return eWatchpointReadWrite; - if (watch_read) + else if (watch_read) return eWatchpointRead; - if (watch_write) + else // Must be watch_write, then. return eWatchpointWrite; } From johnny.chen at apple.com Fri Sep 9 16:11:26 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 21:11:26 -0000 Subject: [Lldb-commits] [lldb] r139410 - in /lldb/trunk/tools/debugserver/source/MacOSX: i386/DNBArchImplI386.cpp x86_64/DNBArchImplX86_64.cpp Message-ID: <20110909211126.0DB652A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 16:11:25 2011 New Revision: 139410 URL: http://llvm.org/viewvc/llvm-project?rev=139410&view=rev Log: Reset the debug status register, only if necessary, before we resume, which saves unnecessary traffic to the kernel. Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=139410&r1=139409&r2=139410&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Fri Sep 9 16:11:25 2011 @@ -546,15 +546,24 @@ EnableHardwareSingleStep(true); } - // Reset the debug status register before we resume. + // Reset the debug status register, if necessary, before we resume. kern_return_t kret = GetDBGState(false); - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); - if (kret == KERN_SUCCESS) + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); + if (kret != KERN_SUCCESS) + return; + + DBG debug_state = m_state.context.dbg; + bool need_reset = false; + uint32_t i, num = NumSupportedHardwareWatchpoints(); + for (i = 0; i < num; ++i) + if (IsWatchpointHit(debug_state, i)) + need_reset = true; + + if (need_reset) { - DBG debug_state = m_state.context.dbg; ClearWatchpointHits(debug_state); kret = SetDBGState(); - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); } } Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=139410&r1=139409&r2=139410&view=diff ============================================================================== --- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original) +++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Fri Sep 9 16:11:25 2011 @@ -475,12 +475,21 @@ EnableHardwareSingleStep(true); } - // Reset the debug status register before we resume. + // Reset the debug status register, if necessary, before we resume. kern_return_t kret = GetDBGState(false); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); - if (kret == KERN_SUCCESS) + if (kret != KERN_SUCCESS) + return; + + DBG debug_state = m_state.context.dbg; + bool need_reset = false; + uint32_t i, num = NumSupportedHardwareWatchpoints(); + for (i = 0; i < num; ++i) + if (IsWatchpointHit(debug_state, i)) + need_reset = true; + + if (need_reset) { - DBG debug_state = m_state.context.dbg; ClearWatchpointHits(debug_state); kret = SetDBGState(); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); @@ -807,7 +816,7 @@ DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) { // Read the debug state - kern_return_t kret = GetDBGState(false); + kern_return_t kret = GetDBGState(true); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); if (kret == KERN_SUCCESS) { From gclayton at apple.com Fri Sep 9 18:04:00 2011 From: gclayton at apple.com (Greg Clayton) Date: Fri, 09 Sep 2011 23:04:00 -0000 Subject: [Lldb-commits] [lldb] r139428 - in /lldb/trunk: include/lldb/API/SBFrame.h include/lldb/API/SBType.h include/lldb/API/SBValue.h include/lldb/Symbol/ClangASTContext.h include/lldb/Symbol/ClangASTType.h include/lldb/Symbol/Type.h include/lldb/lldb-enumerations.h include/lldb/lldb-forward.h scripts/Python/interface/SBType.i scripts/Python/interface/SBValue.i source/API/SBFrame.cpp source/API/SBType.cpp source/API/SBValue.cpp source/Symbol/ClangASTContext.cpp source/Symbol/ClangASTType.cpp Message-ID: <20110909230400.C55882A6C12C@llvm.org> Author: gclayton Date: Fri Sep 9 18:04:00 2011 New Revision: 139428 URL: http://llvm.org/viewvc/llvm-project?rev=139428&view=rev Log: Added the ability to introspect types thourgh the public SBType interface. Fixed up many API calls to not be "const" as const doesn't mean anything to most of our lldb::SB objects since they contain a shared pointer, auto_ptr, or pointer to the types which circumvent the constness anyway. Modified: lldb/trunk/include/lldb/API/SBFrame.h lldb/trunk/include/lldb/API/SBType.h lldb/trunk/include/lldb/API/SBValue.h lldb/trunk/include/lldb/Symbol/ClangASTContext.h lldb/trunk/include/lldb/Symbol/ClangASTType.h lldb/trunk/include/lldb/Symbol/Type.h lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/include/lldb/lldb-forward.h lldb/trunk/scripts/Python/interface/SBType.i lldb/trunk/scripts/Python/interface/SBValue.i lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/API/SBType.cpp lldb/trunk/source/API/SBValue.cpp lldb/trunk/source/Symbol/ClangASTContext.cpp lldb/trunk/source/Symbol/ClangASTType.cpp Modified: lldb/trunk/include/lldb/API/SBFrame.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBFrame.h (original) +++ lldb/trunk/include/lldb/API/SBFrame.h Fri Sep 9 18:04:00 2011 @@ -200,8 +200,8 @@ lldb_private::StackFrame * get() const; - const lldb::StackFrameSP & - get_sp() const; + lldb::StackFrameSP & + get_sp(); #endif Modified: lldb/trunk/include/lldb/API/SBType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBType.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBType.h (original) +++ lldb/trunk/include/lldb/API/SBType.h Fri Sep 9 18:04:00 2011 @@ -16,78 +16,148 @@ class SBTypeList; -class SBType +class SBTypeMember { public: - - SBType (const SBType &rhs); - - ~SBType (); - -#ifndef SWIG - const lldb::SBType & - operator = (const lldb::SBType &rhs); + SBTypeMember (); - bool - operator == (const lldb::SBType &rhs) const; + SBTypeMember (const lldb::SBTypeMember& rhs); + + ~SBTypeMember(); +#ifndef SWIG + lldb::SBTypeMember& + operator = (const lldb::SBTypeMember& rhs); +#endif + bool - operator != (const lldb::SBType &rhs) const; + IsValid() const; - lldb_private::TypeImpl & - ref (); + const char * + GetName (); - const lldb_private::TypeImpl & - ref () const; + lldb::SBType + GetType (); -#endif + uint64_t + GetOffsetByteSize(); +protected: + friend class SBType; + +#ifndef SWIG + void + reset (lldb_private::TypeMemberImpl *); + + lldb_private::TypeMemberImpl & + ref (); + + const lldb_private::TypeMemberImpl & + ref () const; +#endif + + std::auto_ptr m_opaque_ap; +}; + +class SBType +{ +public: + + SBType(); + + SBType (const lldb::SBType &rhs); + + ~SBType (); + bool IsValid() const; size_t - GetByteSize() const; + GetByteSize(); bool - IsPointerType() const; + IsPointerType(); bool - IsReferenceType() const; + IsReferenceType(); - SBType - GetPointerType() const; + lldb::SBType + GetPointerType(); - SBType - GetPointeeType() const; + lldb::SBType + GetPointeeType(); - SBType - GetReferenceType() const; + lldb::SBType + GetReferenceType(); - SBType - GetDereferencedType() const; + lldb::SBType + GetDereferencedType(); - SBType - GetBasicType(lldb::BasicType type) const; - + lldb::SBType + GetBasicType(lldb::BasicType type); + + uint32_t + GetNumberOfFields (); + + uint32_t + GetNumberOfDirectBaseClasses (); + + uint32_t + GetNumberOfVirtualBaseClasses (); + + lldb::SBTypeMember + GetFieldAtIndex (uint32_t idx); + + lldb::SBTypeMember + GetDirectBaseClassAtIndex (uint32_t idx); + + lldb::SBTypeMember + GetVirtualBaseClassAtIndex (uint32_t idx); + const char* GetName(); + lldb::TypeClass + GetTypeClass (); + // DEPRECATED: but needed for Xcode right now static bool IsPointerType (void * clang_type); protected: + +#ifndef SWIG + lldb::SBType & + operator = (const lldb::SBType &rhs); + + bool + operator == (lldb::SBType &rhs); + + bool + operator != (lldb::SBType &rhs); + + lldb_private::TypeImpl & + ref (); + + const lldb_private::TypeImpl & + ref () const; + + void + reset(const lldb::TypeImplSP &type_impl_sp); +#endif + + lldb::TypeImplSP m_opaque_sp; friend class SBModule; friend class SBTarget; friend class SBValue; + friend class SBTypeMember; friend class SBTypeList; SBType (const lldb_private::ClangASTType &); SBType (const lldb::TypeSP &); SBType (const lldb::TypeImplSP &); - SBType(); }; @@ -96,28 +166,30 @@ public: SBTypeList(); - SBTypeList(const SBTypeList& rhs); + SBTypeList(const lldb::SBTypeList& rhs); - SBTypeList& - operator = (const SBTypeList& rhs); + ~SBTypeList(); + + lldb::SBTypeList& + operator = (const lldb::SBTypeList& rhs); bool - IsValid() const; + IsValid(); void - Append (const SBType& type); + Append (lldb::SBType type); - SBType - GetTypeAtIndex(int index) const; + lldb::SBType + GetTypeAtIndex (uint32_t index); - int - GetSize() const; + uint32_t + GetSize(); - ~SBTypeList(); private: std::auto_ptr m_opaque_ap; }; + } // namespace lldb Modified: lldb/trunk/include/lldb/API/SBValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBValue.h (original) +++ lldb/trunk/include/lldb/API/SBValue.h Fri Sep 9 18:04:00 2011 @@ -22,17 +22,17 @@ public: SBValue (); - SBValue (const SBValue &rhs); + SBValue (const lldb::SBValue &rhs); #ifndef SWIG - const SBValue & - operator =(const SBValue &rhs); + lldb::SBValue & + operator =(const lldb::SBValue &rhs); #endif ~SBValue (); bool - IsValid() const; + IsValid(); SBError GetError(); @@ -50,28 +50,22 @@ GetByteSize (); bool - IsInScope (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - bool IsInScope (); lldb::Format - GetFormat () const; + GetFormat (); void SetFormat (lldb::Format format); const char * - GetValue (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - const char * GetValue (); int64_t - GetValueAsSigned(SBError& error, int64_t fail_value=0); + GetValueAsSigned (lldb::SBError& error, int64_t fail_value=0); uint64_t - GetValueAsUnsigned(SBError& error, uint64_t fail_value=0); + GetValueAsUnsigned (lldb::SBError& error, uint64_t fail_value=0); int64_t GetValueAsSigned(int64_t fail_value=0); @@ -83,56 +77,43 @@ GetValueType (); bool - GetValueDidChange (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - bool GetValueDidChange (); const char * - GetSummary (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - const char * GetSummary (); const char * - GetObjectDescription (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - const char * GetObjectDescription (); const char * - GetLocation (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. - - const char * GetLocation (); bool - SetValueFromCString (const lldb::SBFrame &frame, const char *value_str); // DEPRECATED - SBValues know their own frames. - - bool SetValueFromCString (const char *value_str); lldb::SBValue GetChildAtIndex (uint32_t idx); lldb::SBValue - CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type); + CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type); lldb::SBValue - Cast(const SBType& type); + Cast (lldb::SBType type); lldb::SBValue CreateValueFromExpression (const char *name, const char* expression); lldb::SBValue - CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type); + CreateValueFromAddress (const char* name, + lldb::addr_t address, + lldb::SBType type); // this has no address! GetAddress() and GetLoadAddress() as well as AddressOf() // on the return of this call all return invalid lldb::SBValue CreateValueFromData (const char* name, - const SBData& data, - const SBType& type); + lldb::SBData data, + lldb::SBType type); //------------------------------------------------------------------ /// Get a child value by index from a value. @@ -279,7 +260,7 @@ bool TypeIsPointerType (); - SBType + lldb::SBType GetType(); bool @@ -289,7 +270,8 @@ GetExpressionPath (lldb::SBStream &description); bool - GetExpressionPath (lldb::SBStream &description, bool qualify_cxx_base_classes); + GetExpressionPath (lldb::SBStream &description, + bool qualify_cxx_base_classes); SBValue (const lldb::ValueObjectSP &value_sp); @@ -298,8 +280,8 @@ // currently rely on being able to extract the SharedPointer out of an SBValue. if the implementation // is deferred to the .cpp file instead of being inlined here, the platform will fail to link // correctly. however, this is temporary till a better general solution is found. FIXME - const lldb::ValueObjectSP& - get_sp() const + lldb::ValueObjectSP& + get_sp() { return m_opaque_sp; } Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Sep 9 18:04:00 2011 @@ -413,6 +413,37 @@ lldb::clang_type_t clang_type, bool omit_empty_base_classes); + static uint32_t + GetNumDirectBaseClasses (clang::ASTContext *ast, + lldb::clang_type_t clang_type); + + static uint32_t + GetNumVirtualBaseClasses (clang::ASTContext *ast, + lldb::clang_type_t clang_type); + + static uint32_t + GetNumFields (clang::ASTContext *ast, + lldb::clang_type_t clang_type); + + static lldb::clang_type_t + GetDirectBaseClassAtIndex (clang::ASTContext *ast, + lldb::clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr); + + static lldb::clang_type_t + GetVirtualBaseClassAtIndex (clang::ASTContext *ast, + lldb::clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr); + + static lldb::clang_type_t + GetFieldAtIndex (clang::ASTContext *ast, + lldb::clang_type_t clang_type, + uint32_t idx, + std::string& name, + uint32_t *byte_offset_ptr); + static uint32_t GetNumPointeeChildren (lldb::clang_type_t clang_type); Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Fri Sep 9 18:04:00 2011 @@ -107,6 +107,10 @@ GetMinimumLanguage (clang::ASTContext *ctx, lldb::clang_type_t clang_type); + static lldb::TypeClass + GetTypeClass (clang::ASTContext *ast_context, + lldb::clang_type_t clang_type); + void DumpValue (ExecutionContext *exe_ctx, Stream *s, Modified: lldb/trunk/include/lldb/Symbol/Type.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/Type.h (original) +++ lldb/trunk/include/lldb/Symbol/Type.h Fri Sep 9 18:04:00 2011 @@ -390,6 +390,57 @@ private: std::vector m_content; }; + +class TypeMemberImpl +{ +public: + TypeMemberImpl () : + m_type_impl_sp (), + m_bit_offset (0), + m_name () + { + } + + TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, + uint64_t bit_offset, + const ConstString &name) : + m_type_impl_sp (type_impl_sp), + m_bit_offset (bit_offset), + m_name (name) + { + } + + TypeMemberImpl (const lldb::TypeImplSP &type_impl_sp, + uint64_t bit_offset): + m_type_impl_sp (type_impl_sp), + m_bit_offset (bit_offset), + m_name () + { + } + + const lldb::TypeImplSP & + GetTypeImpl () + { + return m_type_impl_sp; + } + + const ConstString & + GetName () const + { + return m_name; + } + + uint64_t + GetBitOffset () const + { + return m_bit_offset; + } + +protected: + lldb::TypeImplSP m_type_impl_sp; + uint64_t m_bit_offset; + ConstString m_name; +}; } // namespace lldb_private Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Sep 9 18:04:00 2011 @@ -550,7 +550,34 @@ eBasicTypeObjCClass, eBasicTypeObjCSel } BasicType; - + + typedef enum TypeClass + { + eTypeClassInvalid = (0u), + eTypeClassArray = (1u << 0), + eTypeClassBlockPointer = (1u << 1), + eTypeClassBuiltin = (1u << 2), + eTypeClassClass = (1u << 3), + eTypeClassComplexFloat = (1u << 4), + eTypeClassComplexInteger = (1u << 5), + eTypeClassEnumeration = (1u << 6), + eTypeClassFunction = (1u << 7), + eTypeClassMemberPointer = (1u << 8), + eTypeClassObjCObject = (1u << 9), + eTypeClassObjCInterface = (1u << 10), + eTypeClassObjCObjectPointer = (1u << 11), + eTypeClassPointer = (1u << 12), + eTypeClassReference = (1u << 13), + eTypeClassStruct = (1u << 14), + eTypeClassTypedef = (1u << 15), + eTypeClassUnion = (1u << 16), + eTypeClassVector = (1u << 17), + // Define the last type class as the MSBit of a 32 bit value + eTypeClassOther = (1u << 31), + // Define a mask that can be used for any type when finding types + eTypeClassAny = (0xffffffffu) + }TypeClass; + } // namespace lldb Modified: lldb/trunk/include/lldb/lldb-forward.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-forward.h (original) +++ lldb/trunk/include/lldb/lldb-forward.h Fri Sep 9 18:04:00 2011 @@ -170,6 +170,7 @@ class TypeAndOrName; class TypeList; class TypeListImpl; +class TypeMemberImpl; class UUID; class Unwind; class UnwindAssembly; Modified: lldb/trunk/scripts/Python/interface/SBType.i URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBType.i?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/scripts/Python/interface/SBType.i (original) +++ lldb/trunk/scripts/Python/interface/SBType.i Fri Sep 9 18:04:00 2011 @@ -9,6 +9,35 @@ namespace lldb { + %feature("docstring", +"Represents a member of a type in lldb. +") SBTypeMember; + +class SBTypeMember +{ +public: + SBTypeMember (); + + SBTypeMember (const lldb::SBTypeMember& rhs); + + ~SBTypeMember(); + + bool + IsValid() const; + + const char * + GetName (); + + lldb::SBType + GetType (); + + uint64_t + GetOffsetByteSize(); + +protected: + std::auto_ptr m_opaque_ap; +}; + %feature("docstring", "Represents a data type in lldb. The FindFirstType() method of SBTarget/SBModule returns a SBType. @@ -85,39 +114,60 @@ class SBType { public: - SBType (const SBType &rhs); + SBType (const lldb::SBType &rhs); ~SBType (); bool - IsValid() const; + IsValid(); size_t - GetByteSize() const; + GetByteSize(); bool - IsPointerType() const; + IsPointerType(); bool - IsReferenceType() const; - - SBType - GetPointerType() const; + IsReferenceType(); - SBType - GetPointeeType() const; + lldb::SBType + GetPointerType(); - SBType - GetReferenceType() const; + lldb::SBType + GetPointeeType(); - SBType - GetDereferencedType() const; - - SBType - GetBasicType(lldb::BasicType type) const; + lldb::SBType + GetReferenceType(); + + lldb::SBType + GetDereferencedType(); + + lldb::SBType + GetBasicType (lldb::BasicType type); + + uint32_t + GetNumberOfFields (); + + uint32_t + GetNumberOfDirectBaseClasses (); + + uint32_t + GetNumberOfVirtualBaseClasses (); + + lldb::SBTypeMember + GetFieldAtIndex (uint32_t idx); + + lldb::SBTypeMember + GetDirectBaseClassAtIndex (uint32_t idx); + + lldb::SBTypeMember + GetVirtualBaseClassAtIndex (uint32_t idx); const char* GetName(); + + lldb::TypeClass + GetTypeClass (); }; %feature("docstring", @@ -157,15 +207,15 @@ SBTypeList(); bool - IsValid() const; + IsValid(); void - Append(const SBType& type); + Append (lldb::SBType type); - SBType - GetTypeAtIndex(int index); + lldb::SBType + GetTypeAtIndex (uint32_t index); - int + uint32_t GetSize(); ~SBTypeList(); Modified: lldb/trunk/scripts/Python/interface/SBValue.i URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBValue.i?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/scripts/Python/interface/SBValue.i (original) +++ lldb/trunk/scripts/Python/interface/SBValue.i Fri Sep 9 18:04:00 2011 @@ -65,7 +65,7 @@ ~SBValue (); bool - IsValid() const; + IsValid(); SBError GetError(); @@ -86,7 +86,7 @@ IsInScope (); lldb::Format - GetFormat () const; + GetFormat (); void SetFormat (lldb::Format format); @@ -185,21 +185,21 @@ bool can_create_synthetic); lldb::SBValue - CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type); + CreateChildAtOffset (const char *name, uint32_t offset, lldb::SBType type); lldb::SBValue - SBValue::Cast(const SBType& type); + SBValue::Cast (lldb::SBType type); lldb::SBValue CreateValueFromExpression (const char *name, const char* expression); lldb::SBValue - CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type); + CreateValueFromAddress(const char* name, lldb::addr_t address, lldb::SBType type); lldb::SBValue CreateValueFromData (const char* name, - const SBData& data, - const SBType& type); + lldb::SBData data, + lldb::SBType type); lldb::SBType GetType(); Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Fri Sep 9 18:04:00 2011 @@ -538,8 +538,8 @@ return m_opaque_sp.get(); } -const lldb::StackFrameSP & -SBFrame::get_sp() const +lldb::StackFrameSP & +SBFrame::get_sp() { return m_opaque_sp; } Modified: lldb/trunk/source/API/SBType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBType.cpp?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/source/API/SBType.cpp (original) +++ lldb/trunk/source/API/SBType.cpp Fri Sep 9 18:04:00 2011 @@ -31,7 +31,7 @@ { } -SBType::SBType (const lldb_private::ClangASTType &type) : +SBType::SBType (const ClangASTType &type) : m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), type.GetOpaqueQualType()))) { @@ -63,7 +63,7 @@ //{} // bool -SBType::operator == (const lldb::SBType &rhs) const +SBType::operator == (SBType &rhs) { if (IsValid() == false) return !rhs.IsValid(); @@ -73,7 +73,7 @@ } bool -SBType::operator != (const lldb::SBType &rhs) const +SBType::operator != (SBType &rhs) { if (IsValid() == false) return rhs.IsValid(); @@ -82,11 +82,16 @@ (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); } +void +SBType::reset(const lldb::TypeImplSP &type_impl_sp) +{ + m_opaque_sp = type_impl_sp; +} -const lldb::SBType & -SBType::operator = (const lldb::SBType &rhs) +SBType & +SBType::operator = (const SBType &rhs) { - if (*this != rhs) + if (this != &rhs) { m_opaque_sp = rhs.m_opaque_sp; } @@ -96,15 +101,15 @@ SBType::~SBType () {} -lldb_private::TypeImpl & +TypeImpl & SBType::ref () { if (m_opaque_sp.get() == NULL) - m_opaque_sp.reset (new lldb_private::TypeImpl()); + m_opaque_sp.reset (new TypeImpl()); return *m_opaque_sp; } -const lldb_private::TypeImpl & +const TypeImpl & SBType::ref () const { // "const SBAddress &addr" should already have checked "addr.IsValid()" @@ -124,7 +129,7 @@ } size_t -SBType::GetByteSize() const +SBType::GetByteSize() { if (!IsValid()) return 0; @@ -134,7 +139,7 @@ } bool -SBType::IsPointerType() const +SBType::IsPointerType() { if (!IsValid()) return false; @@ -148,7 +153,7 @@ } bool -SBType::IsReferenceType() const +SBType::IsReferenceType() { if (!IsValid()) return false; @@ -162,7 +167,7 @@ } SBType -SBType::GetPointerType() const +SBType::GetPointerType() { if (!IsValid()) return SBType(); @@ -172,7 +177,7 @@ } SBType -SBType::GetPointeeType() const +SBType::GetPointeeType() { if (!IsValid()) return SBType(); @@ -186,7 +191,7 @@ } SBType -SBType::GetReferenceType() const +SBType::GetReferenceType() { if (!IsValid()) return SBType(); @@ -196,7 +201,7 @@ } SBType -SBType::GetDereferencedType() const +SBType::GetDereferencedType() { if (!IsValid()) return SBType(); @@ -207,7 +212,7 @@ } SBType -SBType::GetBasicType(lldb::BasicType type) const +SBType::GetBasicType(lldb::BasicType type) { if (!IsValid()) @@ -302,6 +307,89 @@ return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr())); } +uint32_t +SBType::GetNumberOfDirectBaseClasses () +{ + if (IsValid()) + return ClangASTContext::GetNumDirectBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +uint32_t +SBType::GetNumberOfVirtualBaseClasses () +{ + if (IsValid()) + return ClangASTContext::GetNumVirtualBaseClasses(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +uint32_t +SBType::GetNumberOfFields () +{ + if (IsValid()) + return ClangASTContext::GetNumFields(m_opaque_sp->GetASTContext(), m_opaque_sp->GetOpaqueQualType()); + return 0; +} + +SBTypeMember +SBType::GetDirectBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + uint32_t byte_offset = 0; + clang_type_t clang_type = ClangASTContext::GetDirectBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); + if (clang_type) + { + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); + } + } + return sb_type_member; + +} + +SBTypeMember +SBType::GetVirtualBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + uint32_t byte_offset = 0; + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + clang_type_t clang_type = ClangASTContext::GetVirtualBaseClassAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, &byte_offset); + if (clang_type) + { + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset)); + } + } + return sb_type_member; +} + +SBTypeMember +SBType::GetFieldAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + uint32_t byte_offset = 0; + clang::ASTContext* ast = m_opaque_sp->GetASTContext(); + std::string name_sstr; + clang_type_t clang_type = ClangASTContext::GetFieldAtIndex (ast, m_opaque_sp->GetOpaqueQualType(), idx, name_sstr, &byte_offset); + if (clang_type) + { + ConstString name; + if (!name_sstr.empty()) + name.SetCString(name_sstr.c_str()); + TypeImplSP type_impl_sp (new TypeImpl(ClangASTType (ast, clang_type))); + sb_type_member.reset (new TypeMemberImpl (type_impl_sp, byte_offset, name)); + } + } + return sb_type_member; +} + const char* SBType::GetName() { @@ -311,6 +399,15 @@ return ClangASTType::GetConstTypeName(m_opaque_sp->GetOpaqueQualType()).GetCString(); } +lldb::TypeClass +SBType::GetTypeClass () +{ + if (IsValid()) + return ClangASTType::GetTypeClass (m_opaque_sp->GetASTContext(), + m_opaque_sp->GetOpaqueQualType()); + return lldb::eTypeClassInvalid; +} + SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) { @@ -319,12 +416,12 @@ SBTypeList::SBTypeList(const SBTypeList& rhs) : m_opaque_ap(new TypeListImpl()) { - for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) - Append(rhs.GetTypeAtIndex(i)); + for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(rhs).GetTypeAtIndex(i)); } bool -SBTypeList::IsValid () const +SBTypeList::IsValid () { return (m_opaque_ap.get() != NULL); } @@ -332,30 +429,32 @@ SBTypeList& SBTypeList::operator = (const SBTypeList& rhs) { - if (this != &rhs && m_opaque_ap.get() != rhs.m_opaque_ap.get()) + if (this != &rhs) { - m_opaque_ap.reset(new TypeListImpl()); - for (uint32_t i = 0, rhs_size = rhs.GetSize(); i < rhs_size; i++) - Append(rhs.GetTypeAtIndex(i)); + m_opaque_ap.reset (new TypeListImpl()); + for (uint32_t i = 0, rhs_size = const_cast(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast(rhs).GetTypeAtIndex(i)); } return *this; } void -SBTypeList::Append (const SBType& type) +SBTypeList::Append (SBType type) { if (type.IsValid()) m_opaque_ap->Append (type.m_opaque_sp); } SBType -SBTypeList::GetTypeAtIndex(int index) const +SBTypeList::GetTypeAtIndex(uint32_t index) { - return SBType(m_opaque_ap->GetTypeAtIndex(index)); + if (m_opaque_ap.get()) + return SBType(m_opaque_ap->GetTypeAtIndex(index)); + return SBType(); } -int -SBTypeList::GetSize() const +uint32_t +SBTypeList::GetSize() { return m_opaque_ap->GetSize(); } @@ -367,7 +466,7 @@ bool SBType::IsPointerType (void *opaque_type) { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); bool ret_value = ClangASTContext::IsPointerType (opaque_type); @@ -376,3 +475,89 @@ return ret_value; } + + +SBTypeMember::SBTypeMember() : + m_opaque_ap() +{ +} + +SBTypeMember::~SBTypeMember() +{ +} + +SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : + m_opaque_ap() +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } +} + +lldb::SBTypeMember& +SBTypeMember::operator = (const lldb::SBTypeMember& rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } + return *this; +} + +bool +SBTypeMember::IsValid() const +{ + return m_opaque_ap.get(); +} + +const char * +SBTypeMember::GetName () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetName().GetCString(); + return NULL; +} + +SBType +SBTypeMember::GetType () +{ + SBType sb_type; + if (m_opaque_ap.get()) + { + sb_type.reset (m_opaque_ap->GetTypeImpl()); + } + return sb_type; + +} + +uint64_t +SBTypeMember::GetOffsetByteSize() +{ + if (m_opaque_ap.get()) + return (m_opaque_ap->GetBitOffset() + 7) / 8u; + return 0; +} + +void +SBTypeMember::reset(TypeMemberImpl *type_member_impl) +{ + m_opaque_ap.reset(type_member_impl); +} + +TypeMemberImpl & +SBTypeMember::ref () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new TypeMemberImpl()); + return *m_opaque_ap.get(); +} + +const TypeMemberImpl & +SBTypeMember::ref () const +{ + return *m_opaque_ap.get(); +} + Modified: lldb/trunk/source/API/SBValue.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/source/API/SBValue.cpp (original) +++ lldb/trunk/source/API/SBValue.cpp Fri Sep 9 18:04:00 2011 @@ -52,7 +52,7 @@ { } -const SBValue & +SBValue & SBValue::operator = (const SBValue &rhs) { if (this != &rhs) @@ -65,7 +65,7 @@ } bool -SBValue::IsValid () const +SBValue::IsValid () { // If this function ever changes to anything that does more than just // check if the opaque shared pointer is non NULL, then we need to update @@ -146,12 +146,6 @@ } bool -SBValue::IsInScope (const SBFrame &sb_frame) -{ - return IsInScope(); -} - -bool SBValue::IsInScope () { bool result = false; @@ -173,12 +167,6 @@ } const char * -SBValue::GetValue (const SBFrame &sb_frame) -{ - return GetValue(); -} - -const char * SBValue::GetValue () { const char *cstr = NULL; @@ -228,12 +216,6 @@ } const char * -SBValue::GetObjectDescription (const SBFrame &sb_frame) -{ - return GetObjectDescription (); -} - -const char * SBValue::GetObjectDescription () { const char *cstr = NULL; @@ -256,12 +238,6 @@ return cstr; } -bool -SBValue::GetValueDidChange (const SBFrame &sb_frame) -{ - return GetValueDidChange (); -} - SBType SBValue::GetType() { @@ -305,12 +281,6 @@ } const char * -SBValue::GetSummary (const SBFrame &sb_frame) -{ - return GetSummary (); -} - -const char * SBValue::GetSummary () { const char *cstr = NULL; @@ -334,12 +304,6 @@ } const char * -SBValue::GetLocation (const SBFrame &sb_frame) -{ - return GetLocation (); -} - -const char * SBValue::GetLocation () { const char *cstr = NULL; @@ -363,12 +327,6 @@ } bool -SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str) -{ - return SetValueFromCString (value_str); -} - -bool SBValue::SetValueFromCString (const char *value_str) { bool success = false; @@ -384,7 +342,7 @@ } lldb::SBValue -SBValue::CreateChildAtOffset (const char *name, uint32_t offset, const SBType& type) +SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) { lldb::SBValue result; if (m_opaque_sp) @@ -407,7 +365,7 @@ } lldb::SBValue -SBValue::Cast(const SBType& type) +SBValue::Cast (SBType type) { return CreateChildAtOffset(m_opaque_sp->GetName().GetCString(), 0, type); } @@ -419,10 +377,10 @@ if (m_opaque_sp) { ValueObjectSP result_valobj_sp; - m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression(expression, - m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), - true, true, eNoDynamicValues, - result_valobj_sp); + m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, + m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), + true, true, eNoDynamicValues, + result_valobj_sp); result_valobj_sp->SetName(ConstString(name)); result = SBValue(result_valobj_sp); } @@ -438,7 +396,7 @@ } lldb::SBValue -SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, const SBType& type) +SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType type) { lldb::SBValue result; if (m_opaque_sp) @@ -448,13 +406,13 @@ lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); - ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(), - real_type.m_opaque_sp->GetASTContext(), - real_type.m_opaque_sp->GetOpaqueQualType(), - ConstString(name), - buffer, - lldb::endian::InlHostByteOrder(), - GetTarget().GetProcess().GetAddressByteSize())); + ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope(), + real_type.m_opaque_sp->GetASTContext(), + real_type.m_opaque_sp->GetOpaqueQualType(), + ConstString(name), + buffer, + lldb::endian::InlHostByteOrder(), + GetTarget().GetProcess().GetAddressByteSize())); ValueObjectSP result_valobj_sp; @@ -480,9 +438,7 @@ } lldb::SBValue -SBValue::CreateValueFromData (const char* name, - const SBData& data, - const SBType& type) +SBValue::CreateValueFromData (const char* name, SBData data, SBType type) { SBValue result; @@ -869,7 +825,7 @@ { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { - result = SBThread(lldb::ThreadSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread())); + result = SBThread(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateThread()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -891,7 +847,7 @@ { if (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()) { - result = SBFrame(lldb::StackFrameSP(m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame())); + result.SetFrame (m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame()->GetSP()); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -980,7 +936,7 @@ } lldb::Format -SBValue::GetFormat () const +SBValue::GetFormat () { if (m_opaque_sp) return m_opaque_sp->GetFormat(); Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Sep 9 18:04:00 2011 @@ -2397,6 +2397,386 @@ return num_children; } +uint32_t +ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumBases(); + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl && class_interface_decl->getSuperClass()) + count = 1; + } + } + break; + + + case clang::Type::Typedef: + count = ClangASTContext::GetNumDirectBaseClasses (ast, cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumDirectBaseClasses (ast, cast(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +uint32_t +ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, + clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + count = cxx_record_decl->getNumVBases(); + } + break; + + case clang::Type::Typedef: + count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +uint32_t +ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type) +{ + if (clang_type == NULL) + return 0; + + uint32_t count = 0; + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const RecordType *record_type = dyn_cast(qual_type.getTypePtr()); + if (record_type) + { + RecordDecl *record_decl = record_type->getDecl(); + if (record_decl) + { + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) + ++field_idx; + count = field_idx; + } + } + } + break; + + case clang::Type::Typedef: + count = ClangASTContext::GetNumFields (ast, cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); + break; + + case clang::Type::Elaborated: + count = ClangASTContext::GetNumFields (ast, cast(qual_type)->getNamedType().getAsOpaquePtr()); + break; + + default: + break; + } + return count; +} + +clang_type_t +ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast(base_class->getType()->getAs()->getDecl()); +// if (base_class->isVirtual()) +// *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; +// else + *byte_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; + } + return base_class->getType().getAsOpaquePtr(); + } + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (idx == 0 && GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); + if (superclass_interface_decl) + { + if (byte_offset_ptr) + *byte_offset_ptr = 0; + return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); + } + } + } + } + break; + + + case clang::Type::Typedef: + return ClangASTContext::GetDirectBaseClassAtIndex (ast, + cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetDirectBaseClassAtIndex (ast, + cast(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + +clang_type_t +ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); + if (cxx_record_decl) + { + uint32_t curr_idx = 0; + CXXRecordDecl::base_class_const_iterator base_class, base_class_end; + for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end(); + base_class != base_class_end; + ++base_class, ++curr_idx) + { + if (curr_idx == idx) + { + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); + const CXXRecordDecl *base_class_decl = cast(base_class->getType()->getAs()->getDecl()); + *byte_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; + + } + return base_class->getType().getAsOpaquePtr(); + } + } + } + } + break; + + case clang::Type::Typedef: + return ClangASTContext::GetVirtualBaseClassAtIndex (ast, + cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetVirtualBaseClassAtIndex (ast, + cast(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + +clang_type_t +ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast, + clang_type_t clang_type, + uint32_t idx, + std::string& name, + uint32_t *byte_offset_ptr) +{ + if (clang_type == NULL) + return 0; + + QualType qual_type(QualType::getFromOpaquePtr(clang_type)); + const clang::Type::TypeClass type_class = qual_type->getTypeClass(); + switch (type_class) + { + case clang::Type::Record: + if (GetCompleteQualType (ast, qual_type)) + { + const RecordType *record_type = cast(qual_type.getTypePtr()); + const RecordDecl *record_decl = record_type->getDecl(); + uint32_t field_idx = 0; + RecordDecl::field_iterator field, field_end; + for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) + { + if (idx == field_idx) + { + // Print the member type if requested + // Print the member name and equal sign + name.assign(field->getNameAsString()); + + // Figure out the type byte size (field_type_info.first) and + // alignment (field_type_info.second) from the AST context. + if (byte_offset_ptr) + { + const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); + *byte_offset_ptr = (record_layout.getFieldOffset (field_idx) + 7) / 8; + } + + return field->getType().getAsOpaquePtr(); + } + } + } + break; + + case clang::Type::ObjCObject: + case clang::Type::ObjCInterface: + if (GetCompleteQualType (ast, qual_type)) + { + const ObjCObjectType *objc_class_type = dyn_cast(qual_type.getTypePtr()); + assert (objc_class_type); + if (objc_class_type) + { + ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); + + if (class_interface_decl) + { + if (idx < (class_interface_decl->ivar_size())) + { + ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); + uint32_t ivar_idx = 0; + + for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx) + { + if (ivar_idx == idx) + { + const ObjCIvarDecl* ivar_decl = *ivar_pos; + + QualType ivar_qual_type(ivar_decl->getType()); + + name.assign(ivar_decl->getNameAsString()); + + if (byte_offset_ptr) + { + const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); + *byte_offset_ptr = (interface_layout.getFieldOffset (ivar_idx) + 7)/8; + } + + return ivar_qual_type.getAsOpaquePtr(); + } + } + } + } + } + } + break; + + + case clang::Type::Typedef: + return ClangASTContext::GetFieldAtIndex (ast, + cast(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), + idx, + name, + byte_offset_ptr); + + case clang::Type::Elaborated: + return ClangASTContext::GetFieldAtIndex (ast, + cast(qual_type)->getNamedType().getAsOpaquePtr(), + idx, + name, + byte_offset_ptr); + + default: + break; + } + return NULL; +} + + // If a pointer to a pointee type (the clang_type arg) says that it has no // children, then we either need to trust it, or override it and return a // different result. For example, an "int *" has one child that is an integer, @@ -2616,7 +2996,6 @@ bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; // Base classes should be a multiple of 8 bits in size - assert (bit_offset % 8 == 0); child_byte_offset = bit_offset/8; child_name = ClangASTType::GetTypeNameForQualType(base_class->getType()); Modified: lldb/trunk/source/Symbol/ClangASTType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=139428&r1=139427&r2=139428&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ClangASTType.cpp (original) +++ lldb/trunk/source/Symbol/ClangASTType.cpp Fri Sep 9 18:04:00 2011 @@ -215,6 +215,79 @@ m_type); } +lldb::TypeClass +ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type) +{ + if (clang_type == NULL) + return lldb::eTypeClassInvalid; + + clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type)); + + switch (qual_type->getTypeClass()) + { + case clang::Type::UnaryTransform: break; + case clang::Type::FunctionNoProto: return lldb::eTypeClassFunction; + case clang::Type::FunctionProto: return lldb::eTypeClassFunction; + case clang::Type::IncompleteArray: return lldb::eTypeClassArray; + case clang::Type::VariableArray: return lldb::eTypeClassArray; + case clang::Type::ConstantArray: return lldb::eTypeClassArray; + case clang::Type::DependentSizedArray: return lldb::eTypeClassArray; + case clang::Type::DependentSizedExtVector: return lldb::eTypeClassVector; + case clang::Type::ExtVector: return lldb::eTypeClassVector; + case clang::Type::Vector: return lldb::eTypeClassVector; + case clang::Type::Builtin: return lldb::eTypeClassBuiltin; + case clang::Type::ObjCObjectPointer: return lldb::eTypeClassObjCObjectPointer; + case clang::Type::BlockPointer: return lldb::eTypeClassBlockPointer; + case clang::Type::Pointer: return lldb::eTypeClassPointer; + case clang::Type::LValueReference: return lldb::eTypeClassReference; + case clang::Type::RValueReference: return lldb::eTypeClassReference; + case clang::Type::MemberPointer: return lldb::eTypeClassMemberPointer; + case clang::Type::Complex: + if (qual_type->isComplexType()) + return lldb::eTypeClassComplexFloat; + else + return lldb::eTypeClassComplexInteger; + case clang::Type::ObjCObject: return lldb::eTypeClassObjCObject; + case clang::Type::ObjCInterface: return lldb::eTypeClassObjCInterface; + case clang::Type::Record: + if (ClangASTContext::GetCompleteType (ast_context, clang_type)) + { + const clang::RecordType *record_type = llvm::cast(qual_type.getTypePtr()); + const clang::RecordDecl *record_decl = record_type->getDecl(); + if (record_decl->isUnion()) + return lldb::eTypeClassUnion; + else if (record_decl->isStruct()) + return lldb::eTypeClassStruct; + else + return lldb::eTypeClassClass; + } + break; + case clang::Type::Enum: return lldb::eTypeClassEnumeration; + case clang::Type::Typedef: return lldb::eTypeClassTypedef; + case clang::Type::UnresolvedUsing: break; + case clang::Type::Paren: break; + case clang::Type::Elaborated: break; + case clang::Type::Attributed: break; + case clang::Type::TemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParm: break; + case clang::Type::SubstTemplateTypeParmPack:break; + case clang::Type::Auto: break; + case clang::Type::InjectedClassName: break; + case clang::Type::DependentName: break; + case clang::Type::DependentTemplateSpecialization: break; + case clang::Type::PackExpansion: break; + + case clang::Type::TypeOfExpr: break; + case clang::Type::TypeOf: break; + case clang::Type::Decltype: break; + case clang::Type::TemplateSpecialization: break; + } + // We don't know hot to display this type... + return lldb::eTypeClassOther; + +} + + lldb::LanguageType ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx, lldb::clang_type_t clang_type) From johnny.chen at apple.com Fri Sep 9 18:25:26 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 09 Sep 2011 23:25:26 -0000 Subject: [Lldb-commits] [lldb] r139434 - in /lldb/trunk: include/lldb/Interpreter/OptionGroupWatchpoint.h include/lldb/lldb-enumerations.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectFrame.cpp source/Interpreter/CommandObject.cpp source/Interpreter/OptionGroupWatchpoint.cpp Message-ID: <20110909232526.8546F2A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 18:25:26 2011 New Revision: 139434 URL: http://llvm.org/viewvc/llvm-project?rev=139434&view=rev Log: Add OptionGroupWatchpoint.cpp/.h (preparatory work) for hooking up watchpoint to the 'frame variable' comand. To watch a variable for read/write, issue: frame variable -w read_write Note that '-w' option is not working yet. :-) Added: lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Modified: lldb/trunk/include/lldb/lldb-enumerations.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Interpreter/CommandObject.cpp Added: lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h?rev=139434&view=auto ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h (added) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h Fri Sep 9 18:25:26 2011 @@ -0,0 +1,63 @@ +//===-- OptionGroupWatchpoint.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_OptionGroupWatchpoint_h_ +#define liblldb_OptionGroupWatchpoint_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Interpreter/Options.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// OptionGroupWatchpoint +//------------------------------------------------------------------------- + + class OptionGroupWatchpoint : public OptionGroup + { + public: + + OptionGroupWatchpoint (); + + virtual + ~OptionGroupWatchpoint (); + + virtual uint32_t + GetNumDefinitions (); + + virtual const OptionDefinition* + GetDefinitions (); + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg); + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter); + + typedef enum WatchMode { + eWatchRead, + eWatchWrite, + eWatchReadWrite + } WatchMode; + + bool watch_variable; + WatchMode watch_mode; + + private: + DISALLOW_COPY_AND_ASSIGN(OptionGroupWatchpoint); + }; + +} // namespace lldb_private + +#endif // liblldb_OptionGroupWatchpoint_h_ Modified: lldb/trunk/include/lldb/lldb-enumerations.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=139434&r1=139433&r2=139434&view=diff ============================================================================== --- lldb/trunk/include/lldb/lldb-enumerations.h (original) +++ lldb/trunk/include/lldb/lldb-enumerations.h Fri Sep 9 18:25:26 2011 @@ -408,6 +408,7 @@ eArgTypeWidth, eArgTypeNone, eArgTypePlatform, + eArgTypeWatchMode, eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!! } CommandArgumentType; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=139434&r1=139433&r2=139434&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 9 18:25:26 2011 @@ -437,6 +437,7 @@ 9AC70390117675270086C050 /* SBInstructionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC7038F117675270086C050 /* SBInstructionList.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9AC703AF117675410086C050 /* SBInstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC703AE117675410086C050 /* SBInstruction.cpp */; }; 9AC703B1117675490086C050 /* SBInstructionList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AC703B0117675490086C050 /* SBInstructionList.cpp */; }; + B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */; }; B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */; }; B27318421416AC12006039C8 /* WatchpointLocationList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B27318411416AC12006039C8 /* WatchpointLocationList.cpp */; }; B28058A1139988B0002D96D0 /* InferiorCallPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */; }; @@ -1295,6 +1296,8 @@ AF68D3301255A110002FF25B /* UnwindLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnwindLLDB.h; path = Utility/UnwindLLDB.h; sourceTree = ""; }; AF94005711C03F6500085DB9 /* SymbolVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SymbolVendor.cpp; path = source/Symbol/SymbolVendor.cpp; sourceTree = ""; }; B23DD24F12EDFAC1000C3894 /* ARMUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARMUtils.h; path = Utility/ARMUtils.h; sourceTree = ""; }; + B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupWatchpoint.cpp; path = source/Interpreter/OptionGroupWatchpoint.cpp; sourceTree = ""; }; + B2462248141AD39B00F3D409 /* OptionGroupWatchpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupWatchpoint.h; path = include/lldb/Interpreter/OptionGroupWatchpoint.h; sourceTree = ""; }; B27318411416AC12006039C8 /* WatchpointLocationList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocationList.cpp; path = source/Breakpoint/WatchpointLocationList.cpp; sourceTree = ""; }; B27318431416AC43006039C8 /* WatchpointLocationList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WatchpointLocationList.h; path = include/lldb/Breakpoint/WatchpointLocationList.h; sourceTree = ""; }; B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InferiorCallPOSIX.cpp; path = Utility/InferiorCallPOSIX.cpp; sourceTree = ""; }; @@ -2351,7 +2354,9 @@ 267C0128136880C7006E963E /* OptionGroupValueObjectDisplay.h */, 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */, 26ED3D6F13C5638A0017D45E /* OptionGroupVariable.h */, + B2462248141AD39B00F3D409 /* OptionGroupWatchpoint.h */, 26ED3D6C13C563810017D45E /* OptionGroupVariable.cpp */, + B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */, 26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */, 9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */, 9A2771FB1135A35C00E6ADB6 /* ScriptInterpreterNone.h */, @@ -3358,6 +3363,7 @@ 26A0DA4E140F7226006DA411 /* HashedNameToDIE.cpp in Sources */, B27318421416AC12006039C8 /* WatchpointLocationList.cpp in Sources */, 26E152261419CAD4007967D0 /* ObjectFilePECOFF.cpp in Sources */, + B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=139434&r1=139433&r2=139434&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Fri Sep 9 18:25:26 2011 @@ -28,6 +28,7 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Interpreter/OptionGroupVariable.h" +#include "lldb/Interpreter/OptionGroupWatchpoint.h" #include "lldb/Symbol/ClangASTType.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" @@ -315,11 +316,15 @@ "If any arguments are specified, they can be names of " "argument, local, file static and file global variables. " "Children of aggregate variables can be specified such as " - "'var->child.x'.", + "'var->child.x'. " + "NOTE that '-w' option is not working yet!!! " + "You can choose to watch a variable with the '-w' option. " + "Note that hardware resources for watching are often limited.", NULL, eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), m_option_group (interpreter), m_option_variable(true), // Include the frame specific options by passing "true" + m_option_watchpoint(), m_varobj_options() { CommandArgumentEntry arg; @@ -336,6 +341,7 @@ m_arguments.push_back (arg); m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Finalize(); } @@ -601,6 +607,7 @@ OptionGroupOptions m_option_group; OptionGroupVariable m_option_variable; + OptionGroupWatchpoint m_option_watchpoint; OptionGroupValueObjectDisplay m_varobj_options; }; Modified: lldb/trunk/source/Interpreter/CommandObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=139434&r1=139433&r2=139434&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandObject.cpp (original) +++ lldb/trunk/source/Interpreter/CommandObject.cpp Fri Sep 9 18:25:26 2011 @@ -829,7 +829,8 @@ { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { NULL, false }, "A value could be anything, depending on where and how it is used." }, { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." }, { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { NULL, false }, "No help available for this." }, - { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { NULL, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." } + { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { NULL, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." }, + { eArgTypeWatchMode, "watch-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Specify the mode for a watchpoint." } }; const CommandObject::ArgumentTableEntry* Added: lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp?rev=139434&view=auto ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp (added) +++ lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Fri Sep 9 18:25:26 2011 @@ -0,0 +1,90 @@ +//===-- OptionGroupWatchpoint.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Interpreter/OptionGroupWatchpoint.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-enumerations.h" +#include "lldb/Interpreter/Args.h" + +using namespace lldb; +using namespace lldb_private; + +static OptionEnumValueElement g_watch_mode[] = +{ + { OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"}, + { OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"}, + { OptionGroupWatchpoint::eWatchReadWrite, "read_write", "Watch for read/write"}, + { 0, NULL, NULL } +}; + +// if you add any options here, remember to update the counters in OptionGroupWatchpoint::GetNumDefinitions() +static OptionDefinition +g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "watch", 'w', required_argument, g_watch_mode, 0, eArgTypeWatchMode, "Determine how to watch a memory location (read, write, or read/write)."} +}; + + +OptionGroupWatchpoint::OptionGroupWatchpoint () : + OptionGroup() +{ +} + +OptionGroupWatchpoint::~OptionGroupWatchpoint () +{ +} + +Error +OptionGroupWatchpoint::SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) +{ + Error error; + char short_option = (char) g_option_table[option_idx].short_option; + switch (short_option) + { + case 'w': { + watch_variable = false; + OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; + watch_mode = (WatchMode) Args::StringToOptionEnum(option_arg, enum_values, 0, &watch_variable); + break; + } + default: + error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option); + break; + } + + return error; +} + +void +OptionGroupWatchpoint::OptionParsingStarting (CommandInterpreter &interpreter) +{ + watch_variable = false; + watch_mode = eWatchRead; +} + + +const OptionDefinition* +OptionGroupWatchpoint::GetDefinitions () +{ + return g_option_table; +} + +uint32_t +OptionGroupWatchpoint::GetNumDefinitions () +{ + return 1; +} + + From granata.enrico at gmail.com Fri Sep 9 18:33:15 2011 From: granata.enrico at gmail.com (Enrico Granata) Date: Fri, 09 Sep 2011 23:33:15 -0000 Subject: [Lldb-commits] [lldb] r139435 - in /lldb/trunk: include/lldb/Core/DataVisualization.h source/Commands/CommandObjectFrame.cpp source/Commands/CommandObjectType.cpp source/Core/DataVisualization.cpp source/Core/ValueObject.cpp Message-ID: <20110909233315.1C9CF2A6C12C@llvm.org> Author: enrico Date: Fri Sep 9 18:33:14 2011 New Revision: 139435 URL: http://llvm.org/viewvc/llvm-project?rev=139435&view=rev Log: Renaming a bulk of method calls from Get() to something more descriptive Modified: lldb/trunk/include/lldb/Core/DataVisualization.h lldb/trunk/source/Commands/CommandObjectFrame.cpp lldb/trunk/source/Commands/CommandObjectType.cpp lldb/trunk/source/Core/DataVisualization.cpp lldb/trunk/source/Core/ValueObject.cpp Modified: lldb/trunk/include/lldb/Core/DataVisualization.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataVisualization.h?rev=139435&r1=139434&r2=139435&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/DataVisualization.h (original) +++ lldb/trunk/include/lldb/Core/DataVisualization.h Fri Sep 9 18:33:14 2011 @@ -49,7 +49,7 @@ { public: static lldb::ValueFormatSP - Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic); + GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic); static void Add (const ConstString &type, const lldb::ValueFormatSP &entry); @@ -86,7 +86,7 @@ { public: static bool - Get (const ConstString &type, lldb::SummaryFormatSP &entry); + GetSummaryFormat (const ConstString &type, lldb::SummaryFormatSP &entry); static void Add (const ConstString &type, const lldb::SummaryFormatSP &entry); @@ -109,7 +109,7 @@ public: static bool - Get (const ConstString &category, lldb::FormatCategorySP &entry); + GetCategory (const ConstString &category, lldb::FormatCategorySP &entry); static void Add (const ConstString &category); Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=139435&r1=139434&r2=139435&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Fri Sep 9 18:33:14 2011 @@ -394,7 +394,7 @@ SummaryFormatSP summary_format_sp; if (!m_option_variable.summary.empty()) - DataVisualization::NamedSummaryFormats::Get(ConstString(m_option_variable.summary.c_str()), summary_format_sp); + DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(m_option_variable.summary.c_str()), summary_format_sp); ValueObject::DumpValueObjectOptions options; Modified: lldb/trunk/source/Commands/CommandObjectType.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=139435&r1=139434&r2=139435&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectType.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectType.cpp Fri Sep 9 18:33:14 2011 @@ -1049,7 +1049,7 @@ Error* error) { lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(category_name.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); if (type == eRegexSummary) { @@ -1234,7 +1234,7 @@ } lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(m_options.m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); bool delete_category = category->Delete(typeCS, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); @@ -1365,10 +1365,10 @@ { const char* cat_name = command.GetArgumentAtIndex(0); ConstString cat_nameCS(cat_name); - DataVisualization::Categories::Get(cat_nameCS, category); + DataVisualization::Categories::GetCategory(cat_nameCS, category); } else - DataVisualization::Categories::Get(ConstString(NULL), category); + DataVisualization::Categories::GetCategory(ConstString(NULL), category); category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); } @@ -1667,7 +1667,7 @@ } DataVisualization::Categories::Enable(typeCS); lldb::FormatCategorySP cate; - if (DataVisualization::Categories::Get(typeCS, cate) && cate.get()) + if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) { if (cate->GetCount() == 0) { @@ -2462,7 +2462,7 @@ } lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(m_options.m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); bool delete_category = category->GetFilterNavigator()->Delete(typeCS); delete_category = category->GetRegexFilterNavigator()->Delete(typeCS) || delete_category; @@ -2624,7 +2624,7 @@ } lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(m_options.m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); bool delete_category = category->GetSyntheticNavigator()->Delete(typeCS); delete_category = category->GetRegexSyntheticNavigator()->Delete(typeCS) || delete_category; @@ -2757,10 +2757,10 @@ { const char* cat_name = command.GetArgumentAtIndex(0); ConstString cat_nameCS(cat_name); - DataVisualization::Categories::Get(cat_nameCS, category); + DataVisualization::Categories::GetCategory(cat_nameCS, category); } else - DataVisualization::Categories::Get(ConstString(NULL), category); + DataVisualization::Categories::GetCategory(ConstString(NULL), category); category->GetFilterNavigator()->Clear(); category->GetRegexFilterNavigator()->Clear(); } @@ -2883,10 +2883,10 @@ { const char* cat_name = command.GetArgumentAtIndex(0); ConstString cat_nameCS(cat_name); - DataVisualization::Categories::Get(cat_nameCS, category); + DataVisualization::Categories::GetCategory(cat_nameCS, category); } else - DataVisualization::Categories::Get(ConstString(NULL), category); + DataVisualization::Categories::GetCategory(ConstString(NULL), category); category->GetSyntheticNavigator()->Clear(); category->GetRegexSyntheticNavigator()->Clear(); } @@ -3037,7 +3037,7 @@ lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(options->m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category); Error error; @@ -3156,7 +3156,7 @@ // now I have a valid provider, let's add it to every type lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(m_options.m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); Error error; @@ -3215,7 +3215,7 @@ Error* error) { lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(category_name.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); if (category->AnyMatches(type_name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, @@ -3392,7 +3392,7 @@ Error* error) { lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(category_name.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); if (category->AnyMatches(type_name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, @@ -3514,7 +3514,7 @@ // now I have a valid provider, let's add it to every type lldb::FormatCategorySP category; - DataVisualization::Categories::Get(ConstString(m_options.m_category.c_str()), category); + DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); Error error; Modified: lldb/trunk/source/Core/DataVisualization.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataVisualization.cpp?rev=139435&r1=139434&r2=139435&view=diff ============================================================================== --- lldb/trunk/source/Core/DataVisualization.cpp (original) +++ lldb/trunk/source/Core/DataVisualization.cpp Fri Sep 9 18:33:14 2011 @@ -39,7 +39,7 @@ } lldb::ValueFormatSP -DataVisualization::ValueFormats::Get (ValueObject& valobj, lldb::DynamicValueType use_dynamic) +DataVisualization::ValueFormats::GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic) { lldb::ValueFormatSP entry; GetFormatManager().GetValueNavigator().Get(valobj, entry, use_dynamic); @@ -105,7 +105,7 @@ } bool -DataVisualization::Categories::Get (const ConstString &category, lldb::FormatCategorySP &entry) +DataVisualization::Categories::GetCategory (const ConstString &category, lldb::FormatCategorySP &entry) { entry = GetFormatManager().GetCategory(category); return true; @@ -168,7 +168,7 @@ } bool -DataVisualization::NamedSummaryFormats::Get (const ConstString &type, lldb::SummaryFormatSP &entry) +DataVisualization::NamedSummaryFormats::GetSummaryFormat (const ConstString &type, lldb::SummaryFormatSP &entry) { return GetFormatManager().GetNamedSummaryNavigator().Get(type,entry); } Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=139435&r1=139434&r2=139435&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Fri Sep 9 18:33:14 2011 @@ -248,9 +248,9 @@ if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) || m_last_format_mgr_dynamic != use_dynamic) { - SetValueFormat(DataVisualization::ValueFormats::Get(*this, eNoDynamicValues)); - SetSummaryFormat(DataVisualization::GetSummaryFormat(*this, use_dynamic)); - SetSyntheticChildren(DataVisualization::GetSyntheticChildren(*this, use_dynamic)); + SetValueFormat(DataVisualization::ValueFormats::GetFormat (*this, eNoDynamicValues)); + SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, use_dynamic)); + SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, use_dynamic)); m_last_format_mgr_revision = DataVisualization::GetCurrentRevision(); m_last_format_mgr_dynamic = use_dynamic; From johnny.chen at apple.com Fri Sep 9 19:48:33 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 10 Sep 2011 00:48:33 -0000 Subject: [Lldb-commits] [lldb] r139444 - in /lldb/trunk: include/lldb/Utility/Utils.h lldb.xcodeproj/project.pbxproj source/Interpreter/OptionGroupArchitecture.cpp source/Interpreter/OptionGroupFormat.cpp source/Interpreter/OptionGroupOutputFile.cpp source/Interpreter/OptionGroupPlatform.cpp source/Interpreter/OptionGroupUUID.cpp source/Interpreter/OptionGroupValueObjectDisplay.cpp source/Interpreter/OptionGroupWatchpoint.cpp Message-ID: <20110910004833.C86EF2A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 19:48:33 2011 New Revision: 139444 URL: http://llvm.org/viewvc/llvm-project?rev=139444&view=rev Log: Refactoring: replace a bunch of static array size computation or hardcoded constant with a template function 'arraysize(static_array)', defined in Utils.h. Added: lldb/trunk/include/lldb/Utility/Utils.h Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Interpreter/OptionGroupArchitecture.cpp lldb/trunk/source/Interpreter/OptionGroupFormat.cpp lldb/trunk/source/Interpreter/OptionGroupOutputFile.cpp lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp lldb/trunk/source/Interpreter/OptionGroupUUID.cpp lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Added: lldb/trunk/include/lldb/Utility/Utils.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Utils.h?rev=139444&view=auto ============================================================================== --- lldb/trunk/include/lldb/Utility/Utils.h (added) +++ lldb/trunk/include/lldb/Utility/Utils.h Fri Sep 9 19:48:33 2011 @@ -0,0 +1,19 @@ +//===-- Utils.h -------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_Utils_h_ +#define utility_Utils_h_ + +namespace lldb_private { + +template +inline unsigned arraysize(T (&v)[size]) { return size; } + +} // namespace lldb_private +#endif // utility_Utils Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Sep 9 19:48:33 2011 @@ -1298,6 +1298,7 @@ B23DD24F12EDFAC1000C3894 /* ARMUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARMUtils.h; path = Utility/ARMUtils.h; sourceTree = ""; }; B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupWatchpoint.cpp; path = source/Interpreter/OptionGroupWatchpoint.cpp; sourceTree = ""; }; B2462248141AD39B00F3D409 /* OptionGroupWatchpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupWatchpoint.h; path = include/lldb/Interpreter/OptionGroupWatchpoint.h; sourceTree = ""; }; + B2462249141AE62200F3D409 /* Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = include/lldb/Utility/Utils.h; sourceTree = ""; }; B27318411416AC12006039C8 /* WatchpointLocationList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointLocationList.cpp; path = source/Breakpoint/WatchpointLocationList.cpp; sourceTree = ""; }; B27318431416AC43006039C8 /* WatchpointLocationList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WatchpointLocationList.h; path = include/lldb/Breakpoint/WatchpointLocationList.h; sourceTree = ""; }; B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InferiorCallPOSIX.cpp; path = Utility/InferiorCallPOSIX.cpp; sourceTree = ""; }; @@ -1841,6 +1842,7 @@ 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */, 94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */, 94EBAC8313D9EE26009BA64E /* PythonPointer.h */, + B2462249141AE62200F3D409 /* Utils.h */, ); name = Utility; sourceTree = ""; Modified: lldb/trunk/source/Interpreter/OptionGroupArchitecture.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupArchitecture.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupArchitecture.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupArchitecture.cpp Fri Sep 9 19:48:33 2011 @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -29,15 +30,13 @@ static OptionDefinition g_option_table[] = { -{ LLDB_OPT_SET_1 , false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Specify the architecture for the target."}, + { LLDB_OPT_SET_1 , false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Specify the architecture for the target."}, }; -const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); - uint32_t OptionGroupArchitecture::GetNumDefinitions () { - return k_num_file_options; + return arraysize(g_option_table); } const OptionDefinition * Modified: lldb/trunk/source/Interpreter/OptionGroupFormat.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupFormat.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupFormat.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupFormat.cpp Fri Sep 9 19:48:33 2011 @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -35,14 +36,13 @@ static OptionDefinition g_option_table[] = { -{ LLDB_OPT_SET_1 , false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat , "Specify a format to be used for display."}, + { LLDB_OPT_SET_1 , false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat , "Specify a format to be used for display."}, }; -const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); uint32_t OptionGroupFormat::GetNumDefinitions () { - return k_num_file_options; + return arraysize(g_option_table); } const OptionDefinition * Modified: lldb/trunk/source/Interpreter/OptionGroupOutputFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupOutputFile.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupOutputFile.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupOutputFile.cpp Fri Sep 9 19:48:33 2011 @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -30,16 +31,14 @@ static OptionDefinition g_option_table[] = { -{ LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypePath , "Specify a path for capturing command output."}, -{ LLDB_OPT_SET_1 , false, "append-outfile" , 'A', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile '."}, + { LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypePath , "Specify a path for capturing command output."}, + { LLDB_OPT_SET_1 , false, "append-outfile" , 'A', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile '."}, }; -const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); - uint32_t OptionGroupOutputFile::GetNumDefinitions () { - return k_num_file_options; + return arraysize(g_option_table); } const OptionDefinition * Modified: lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupPlatform.cpp Fri Sep 9 19:48:33 2011 @@ -15,6 +15,7 @@ // Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/Platform.h" +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -67,8 +68,6 @@ { LLDB_OPT_SET_ALL, false, "sysroot" , 's', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." } }; -static const uint32_t k_option_table_size = sizeof(g_option_table)/sizeof (OptionDefinition); - const OptionDefinition* OptionGroupPlatform::GetDefinitions () { @@ -81,8 +80,8 @@ OptionGroupPlatform::GetNumDefinitions () { if (m_include_platform_option) - return k_option_table_size; - return k_option_table_size - 1; + return arraysize(g_option_table); + return arraysize(g_option_table) - 1; } Modified: lldb/trunk/source/Interpreter/OptionGroupUUID.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupUUID.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupUUID.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupUUID.cpp Fri Sep 9 19:48:33 2011 @@ -13,6 +13,7 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -29,15 +30,13 @@ static OptionDefinition g_option_table[] = { -{ LLDB_OPT_SET_1 , false, "uuid", 'u', required_argument, NULL, 0, eArgTypeNone, "A module UUID value."}, + { LLDB_OPT_SET_1 , false, "uuid", 'u', required_argument, NULL, 0, eArgTypeNone, "A module UUID value."}, }; -const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); - uint32_t OptionGroupUUID::GetNumDefinitions () { - return k_num_file_options; + return arraysize(g_option_table); } const OptionDefinition * Modified: lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Fri Sep 9 19:48:33 2011 @@ -15,6 +15,7 @@ // Project includes #include "lldb/Target/Target.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -45,12 +46,10 @@ { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } }; -const uint32_t k_num_file_options = sizeof(g_option_table)/sizeof(OptionDefinition); - uint32_t OptionGroupValueObjectDisplay::GetNumDefinitions () { - return k_num_file_options; + return arraysize(g_option_table); } const OptionDefinition * Modified: lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp?rev=139444&r1=139443&r2=139444&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Fri Sep 9 19:48:33 2011 @@ -15,6 +15,7 @@ // Project includes #include "lldb/lldb-enumerations.h" #include "lldb/Interpreter/Args.h" +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -84,7 +85,5 @@ uint32_t OptionGroupWatchpoint::GetNumDefinitions () { - return 1; + return arraysize(g_option_table); } - - From johnny.chen at apple.com Fri Sep 9 20:01:44 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 10 Sep 2011 01:01:44 -0000 Subject: [Lldb-commits] [lldb] r139447 - /lldb/trunk/include/lldb/Utility/Utils.h Message-ID: <20110910010144.585982A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 20:01:44 2011 New Revision: 139447 URL: http://llvm.org/viewvc/llvm-project?rev=139447&view=rev Log: Add comment. Modified: lldb/trunk/include/lldb/Utility/Utils.h Modified: lldb/trunk/include/lldb/Utility/Utils.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/Utils.h?rev=139447&r1=139446&r2=139447&view=diff ============================================================================== --- lldb/trunk/include/lldb/Utility/Utils.h (original) +++ lldb/trunk/include/lldb/Utility/Utils.h Fri Sep 9 20:01:44 2011 @@ -12,6 +12,7 @@ namespace lldb_private { +// Return the number of elements of a static array. template inline unsigned arraysize(T (&v)[size]) { return size; } From gclayton at apple.com Fri Sep 9 20:04:42 2011 From: gclayton at apple.com (Greg Clayton) Date: Sat, 10 Sep 2011 01:04:42 -0000 Subject: [Lldb-commits] [lldb] r139448 - in /lldb/trunk/source/Plugins/ObjectFile/PECOFF: ObjectFilePECOFF.cpp ObjectFilePECOFF.h Message-ID: <20110910010442.9E2732A6C12C@llvm.org> Author: gclayton Date: Fri Sep 9 20:04:42 2011 New Revision: 139448 URL: http://llvm.org/viewvc/llvm-project?rev=139448&view=rev Log: Quick fixes to the PE COFF file loader. Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=139448&r1=139447&r2=139448&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Fri Sep 9 20:04:42 2011 @@ -72,6 +72,46 @@ #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +// Section Flags +// The section flags in the Characteristics field of the section header indicate +// characteristics of the section. +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files. +#define IMAGE_SCN_CNT_CODE 0x00000020 // The section contains executable code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // The section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // The section contains uninitialized data. +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved for future use. +#define IMAGE_SCN_LNK_INFO 0x00000200 // The section contains comments or other information. The .drectve section has this type. This is valid for object files only. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // The section will not become part of the image. This is valid only for object files. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // The section contains COMDAT data. For more information, see section 5.5.6, ???COMDAT Sections (Object Only).??? This is valid only for object files. +#define IMAGE_SCN_GPREL 0x00008000 // The section contains data referenced through the global pointer (GP). +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 // For ARM machine types, the section contains Thumb code. Reserved for future use with other machine types. +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // Align data on a 1-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // Align data on a 2-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // Align data on a 4-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // Align data on an 8-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Align data on a 16-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // Align data on a 32-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // Align data on a 64-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // Align data on a 128-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // Align data on a 256-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // Align data on a 512-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // Align data on a 1024-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // Align data on a 2048-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // Align data on a 4096-byte boundary. Valid only for object files. +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // Align data on an 8192-byte boundary. Valid only for object files. +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // The section contains extended relocations. +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // The section can be discarded as needed. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // The section cannot be cached. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // The section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // The section can be shared in memory. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // The section can be executed as code. +#define IMAGE_SCN_MEM_READ 0x40000000 // The section can be read. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // The section can be written to. + using namespace lldb; using namespace lldb_private; @@ -162,12 +202,14 @@ uint32_t pe_signature = m_data.GetU32 (&offset); if (pe_signature != IMAGE_NT_SIGNATURE) return false; - } - if (ParseCOFFHeader(&offset)) - { - if (m_coff_header.hdrsize > 0) - ParseCOFFOptionalHeader(&offset); - ParseSectionHeaders (offset); + if (ParseCOFFHeader(&offset)) + { + if (m_coff_header.hdrsize > 0) + ParseCOFFOptionalHeader(&offset); + ParseSectionHeaders (offset); + } + StreamFile s(stdout, false);// REMOVE THIS LINE!!! + Dump(&s);// REMOVE THIS LINE!!! return true; } return false; @@ -334,7 +376,7 @@ m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr); m_coff_header_opt.image_size = m_data.GetU32(offset_ptr); m_coff_header_opt.header_size = m_data.GetU32(offset_ptr); - m_coff_header_opt.checksym = m_data.GetU32(offset_ptr); + m_coff_header_opt.checksum = m_data.GetU32(offset_ptr); m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr); m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr); m_coff_header_opt.stack_reserve_size = m_data.GetMaxU64 (offset_ptr, addr_byte_size); @@ -436,39 +478,57 @@ SectionList *sect_list = GetSectionList(); m_symtab_ap.reset(new Symtab(this)); Mutex::Locker symtab_locker (m_symtab_ap->GetMutex()); - DataExtractor stab_data; - DataExtractor stabstr_data; - static ConstString g_stab_sect_name(".stab"); - static ConstString g_stabstr_sect_name(".stabstr"); - const Section *stab_section = sect_list->FindSectionByName (g_stab_sect_name).get(); - if (stab_section == NULL) - return m_symtab_ap.get(); - const Section *stabstr_section = sect_list->FindSectionByName (g_stabstr_sect_name).get(); - if (stabstr_section == NULL) - return m_symtab_ap.get(); - uint32_t offset = 0; - if (stab_section->ReadSectionDataFromObjectFile (this, stab_data) && - stabstr_section->ReadSectionDataFromObjectFile (this, stabstr_data)) + + const uint32_t num_syms = m_coff_header.nsyms; + + if (num_syms > 0 && m_coff_header.symoff > 0) { - const uint32_t num_syms = stab_data.GetByteSize() / sizeof (coff_symbol_t); + const uint32_t symbol_size = sizeof(section_header_t); + const uint32_t addr_byte_size = GetAddressByteSize (); + const size_t symbol_data_size = num_syms * symbol_size; + // Include the 4 bytes string table size at the end of the symbols + DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4)); + DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size); + uint32_t offset = symbol_data_size; + const uint32_t strtab_size = symtab_data.GetU32 (&offset); + DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size)); + DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size); + + offset = 0; + std::string symbol_name; Symbol *symbols = m_symtab_ap->Resize (num_syms); for (uint32_t i=0; iGetSectionAtIndex(symbol.sect-1).get(), symbol.value); - symbols[i].GetMangled ().SetValue(symbol.name, symbol.name[0]=='_' && symbol.name[1] == 'Z'); + symbols[i].GetMangled ().SetValue (symbol_name.c_str(), symbol_name[0]=='_' && symbol_name[1] == 'Z'); symbols[i].SetValue(symbol_addr); if (symbol.naux > 0) @@ -495,14 +555,70 @@ std::string sect_name; GetSectionName (sect_name, m_sect_headers[idx]); ConstString const_sect_name (sect_name.c_str()); - + static ConstString g_code_sect_name (".code"); + static ConstString g_CODE_sect_name ("CODE"); + static ConstString g_data_sect_name (".data"); + static ConstString g_DATA_sect_name ("DATA"); + static ConstString g_bss_sect_name (".bss"); + static ConstString g_BSS_sect_name ("BSS"); + static ConstString g_debug_sect_name (".debug"); + static ConstString g_reloc_sect_name (".reloc"); + static ConstString g_stab_sect_name (".stab"); + static ConstString g_stabstr_sect_name (".stabstr"); + SectionType section_type = eSectionTypeOther; + if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE && + ((const_sect_name == g_code_sect_name) || (const_sect_name == g_CODE_sect_name))) + { + section_type = eSectionTypeCode; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA && + ((const_sect_name == g_data_sect_name) || (const_sect_name == g_DATA_sect_name))) + { + section_type = eSectionTypeData; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA && + ((const_sect_name == g_bss_sect_name) || (const_sect_name == g_BSS_sect_name))) + { + if (m_sect_headers[idx].size == 0) + section_type = eSectionTypeZeroFill; + else + section_type = eSectionTypeData; + } + else if (const_sect_name == g_debug_sect_name) + { + section_type = eSectionTypeDebug; + } + else if (const_sect_name == g_stabstr_sect_name) + { + section_type = eSectionTypeDataCString; + } + else if (const_sect_name == g_reloc_sect_name) + { + section_type = eSectionTypeOther; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_CODE) + { + section_type = eSectionTypeCode; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_INITIALIZED_DATA) + { + section_type = eSectionTypeData; + } + else if (m_sect_headers[idx].flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) + { + if (m_sect_headers[idx].size == 0) + section_type = eSectionTypeZeroFill; + else + section_type = eSectionTypeData; + } + // Use a segment ID of the segment index shifted left by 8 so they // never conflict with any of the sections. SectionSP section_sp (new Section (NULL, module, // Module to which this section belongs idx + 1, // Section ID is the 1 based segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible const_sect_name, // Name of this section - eSectionTypeCode, // This section is a container of other sections. + section_type, // This section is a container of other sections. m_sect_headers[idx].vmaddr, // File VM address == addresses as they are found in the object file m_sect_headers[idx].vmsize, // VM size in bytes of this section m_sect_headers[idx].offset, // Offset to the data for this section in the file @@ -659,7 +775,7 @@ s->Printf (" reserved1 = 0x%8.8x\n", header.reserved1); s->Printf (" image_size = 0x%8.8x\n", header.image_size); s->Printf (" header_size = 0x%8.8x\n", header.header_size); - s->Printf (" checksym = 0x%8.8x\n", header.checksym); + s->Printf (" checksum = 0x%8.8x\n", header.checksum); s->Printf (" subsystem = 0x%4.4x\n", header.subsystem); s->Printf (" dll_flags = 0x%4.4x\n", header.dll_flags); s->Printf (" stack_reserve_size = 0x%16.16llx\n", header.stack_reserve_size); @@ -671,7 +787,7 @@ uint32_t i; for (i=0; iPrintf (" data_dirs[%u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", + s->Printf (" data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", i, header.data_dirs[i].vmaddr, header.data_dirs[i].vmsize); @@ -689,10 +805,10 @@ GetSectionName(name, sh); s->Printf ("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x 0x%4.4x 0x%8.8x\n", name.c_str(), - sh.vmsize, sh.vmaddr, - sh.size, + sh.vmsize, sh.offset, + sh.size, sh.reloff, sh.lineoff, sh.nreloc, @@ -711,15 +827,15 @@ { s->PutCString ("Section Headers\n"); - s->PutCString ("IDX name vm size vm addr size offset reloff lineoff nrel nlin flags\n"); - s->PutCString ("==== ---------------- -------- -------- -------- -------- -------- -------- ---- ---- --------\n"); + s->PutCString ("IDX name vm addr vm size file off file size reloc off line off nreloc nline flags\n"); + s->PutCString ("==== ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------ ------ ----------\n"); uint32_t idx = 0; SectionHeaderCollIter pos, end = m_sect_headers.end(); for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) { - s->Printf ("[%2u]", idx); + s->Printf ("[%2u] ", idx); ObjectFilePECOFF::DumpSectionHeader(s, *pos); } } Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=139448&r1=139447&r2=139448&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Fri Sep 9 20:04:42 2011 @@ -173,7 +173,7 @@ uint32_t reserved1; uint32_t image_size; uint32_t header_size; - uint32_t checksym; + uint32_t checksum; uint16_t subsystem; uint16_t dll_flags; uint64_t stack_reserve_size; From johnny.chen at apple.com Fri Sep 9 20:19:02 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 10 Sep 2011 01:19:02 -0000 Subject: [Lldb-commits] [lldb] r139452 - /lldb/trunk/source/Interpreter/OptionGroupVariable.cpp Message-ID: <20110910011902.28EDF2A6C12C@llvm.org> Author: johnny Date: Fri Sep 9 20:19:01 2011 New Revision: 139452 URL: http://llvm.org/viewvc/llvm-project?rev=139452&view=rev Log: Convert OptionGroupVariable.cpp to use the arraysize() template function, as well. Modified: lldb/trunk/source/Interpreter/OptionGroupVariable.cpp Modified: lldb/trunk/source/Interpreter/OptionGroupVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupVariable.cpp?rev=139452&r1=139451&r2=139452&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupVariable.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupVariable.cpp Fri Sep 9 20:19:01 2011 @@ -15,6 +15,7 @@ // Project includes #include "lldb/Target/Target.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Utility/Utils.h" using namespace lldb; using namespace lldb_private; @@ -88,6 +89,7 @@ summary = ""; } +#define NUM_FRAME_OPTS 3 const OptionDefinition* OptionGroupVariable::GetDefinitions () @@ -99,16 +101,18 @@ // Skip the "--no-args", "--no-locals" and "--show-globals" // options if we are not showing frame specific options (globals only) - return &g_option_table[3]; + return &g_option_table[NUM_FRAME_OPTS]; } uint32_t OptionGroupVariable::GetNumDefinitions () { + // Count the "--no-args", "--no-locals" and "--show-globals" + // options if we are showing frame specific options. if (include_frame_options) - return 8; + return arraysize(g_option_table); else - return 5; + return arraysize(g_option_table) - NUM_FRAME_OPTS; } From johnny.chen at apple.com Sat Sep 10 01:22:46 2011 From: johnny.chen at apple.com (Johnny Chen) Date: Sat, 10 Sep 2011 06:22:46 -0000 Subject: [Lldb-commits] [lldb] r139467 - in /lldb/trunk: include/lldb/Interpreter/OptionGroupWatchpoint.h source/Interpreter/OptionGroupWatchpoint.cpp Message-ID: <20110910062246.323D22A6C12C@llvm.org> Author: johnny Date: Sat Sep 10 01:22:46 2011 New Revision: 139467 URL: http://llvm.org/viewvc/llvm-project?rev=139467&view=rev Log: A little bit of cleanup; set watch_mode to eWatchInvalid at the OptionParsingStarting() lifecycle point. Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h?rev=139467&r1=139466&r2=139467&view=diff ============================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h (original) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupWatchpoint.h Sat Sep 10 01:22:46 2011 @@ -46,6 +46,7 @@ OptionParsingStarting (CommandInterpreter &interpreter); typedef enum WatchMode { + eWatchInvalid, eWatchRead, eWatchWrite, eWatchReadWrite Modified: lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp?rev=139467&r1=139466&r2=139467&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp (original) +++ lldb/trunk/source/Interpreter/OptionGroupWatchpoint.cpp Sat Sep 10 01:22:46 2011 @@ -72,7 +72,7 @@ OptionGroupWatchpoint::OptionParsingStarting (CommandInterpreter &interpreter) { watch_variable = false; - watch_mode = eWatchRead; + watch_mode = eWatchInvalid; } From gclayton at apple.com Sat Sep 10 19:01:44 2011 From: gclayton at apple.com (Greg Clayton) Date: Sun, 11 Sep 2011 00:01:44 -0000 Subject: [Lldb-commits] [lldb] r139476 - /lldb/trunk/source/Interpreter/CommandInterpreter.cpp Message-ID: <20110911000144.9484B2A6C12C@llvm.org> Author: gclayton Date: Sat Sep 10 19:01:44 2011 New Revision: 139476 URL: http://llvm.org/viewvc/llvm-project?rev=139476&view=rev Log: Don't skip the application specific ~/.lldbinit file when the program name is "lldb". So currently when you startup any application and you have not specified that you would like to skip loading init files through the API or from "lldb" options, then LLDB will try and load: "~/.lldbinit-%s" where %s the basename of your program "~/.lldbinit" Then LLDB will load any program specified on the command line and then source the "./.llbinit" file for any temporary debug session specific commands. I want this feature because I have thread and frame formats that do ANSI color codes that I only want to load when running in a terminal which is when I am running the "lldb" command line program. Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=139476&r1=139475&r2=139476&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Sat Sep 10 19:01:44 2011 @@ -1793,38 +1793,45 @@ void CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) { - // Don't parse any .lldbinit files if we were asked not to - if (m_skip_lldbinit_files && m_skip_app_init_files) - return; - - const char *init_file_path = in_cwd ? "./.lldbinit" : "~/.lldbinit"; - - std::string app_specific_init; - - if (!m_skip_app_init_files) - { - FileSpec host_spec = Host::GetProgramFileSpec(); - const char *host_name = host_spec.GetFilename().AsCString(); - - if (host_name != NULL && strcmp (host_name, "lldb") != 0) - { - app_specific_init += init_file_path; - app_specific_init += "-"; - app_specific_init += host_name; - } - } - FileSpec init_file; - if (!app_specific_init.empty()) + if (in_cwd) { - init_file.SetFile (app_specific_init.c_str(), true); + // In the current working directory we don't load any program specific + // .lldbinit files, we only look for a "./.lldbinit" file. + if (m_skip_lldbinit_files) + return; + + init_file.SetFile ("./.lldbinit", true); } - - if (!m_skip_lldbinit_files && !init_file.Exists()) + else { - init_file.SetFile (init_file_path, true); - } + // If we aren't looking in the current working directory we are looking + // in the home directory. We will first see if there is an application + // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a + // "-" and the name of the program. If this file doesn't exist, we fall + // back to just the "~/.lldbinit" file. We also obey any requests to not + // load the init files. + const char *init_file_path = "~/.lldbinit"; + + if (m_skip_app_init_files == false) + { + FileSpec program_file_spec (Host::GetProgramFileSpec()); + const char *program_name = program_file_spec.GetFilename().AsCString(); + if (program_name) + { + char program_init_file_name[PATH_MAX]; + ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path, program_name); + init_file.SetFile (program_init_file_name, true); + if (!init_file.Exists()) + init_file.Clear(); + } + } + + if (!init_file && !m_skip_lldbinit_files) + init_file.SetFile (init_file_path, true); + } + // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details). From gclayton at apple.com Sat Sep 10 19:06:05 2011 From: gclayton at apple.com (Greg Clayton) Date: Sun, 11 Sep 2011 00:06:05 -0000 Subject: [Lldb-commits] [lldb] r139477 - /lldb/trunk/include/lldb/Core/UniqueCStringMap.h Message-ID: <20110911000605.F34AE2A6C12C@llvm.org> Author: gclayton Date: Sat Sep 10 19:06:05 2011 New Revision: 139477 URL: http://llvm.org/viewvc/llvm-project?rev=139477&view=rev Log: Added extra calls to the UniqueCStringMap to allow it to be used more efficiently when it contains a large number of items. Since the map is actually a vector of "const char *" and type T values, it will double in size every time you append to it. The extra added functions allow the collection to be sized to fit the data after all entries have been appended, and lookups by name or by regex have been built in to the class to allow efficient lookup. Modified: lldb/trunk/include/lldb/Core/UniqueCStringMap.h Modified: lldb/trunk/include/lldb/Core/UniqueCStringMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/UniqueCStringMap.h?rev=139477&r1=139476&r2=139477&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/UniqueCStringMap.h (original) +++ lldb/trunk/include/lldb/Core/UniqueCStringMap.h Sat Sep 10 19:06:05 2011 @@ -15,6 +15,8 @@ #include #include +#include "lldb/Core/RegularExpression.h" + namespace lldb_private { @@ -103,17 +105,36 @@ } //------------------------------------------------------------------ - // Get an entry by index. + // Get an entries by index in a variety of forms. // // The caller is responsible for ensuring that the collection does - // not change during while using the returned pointer. + // not change during while using the returned values. //------------------------------------------------------------------ - const T * - GetValueAtIndex (uint32_t idx) const + bool + GetValueAtIndex (uint32_t idx, T &value) const { if (idx < m_map.size()) - return &m_map[idx].value; - return NULL; + { + value = m_map[idx].value; + return true; + } + return false; + } + + // Use this function if you have simple types in your map that you + // can easily copy when accessing values by index. + T + GetValueAtIndexUnchecked (uint32_t idx) const + { + return m_map[idx].value; + } + + // Use this function if you have complex types in your map that you + // don't want to copy when accessing values by index. + const T & + GetValueRefAtIndexUnchecked (uint32_t idx) const + { + return m_map[idx].value; } const char * @@ -155,7 +176,7 @@ // not change during while using the returned pointer. //------------------------------------------------------------------ const Entry * - FindNextValueForName (const char *unique_cstr, const Entry *entry_ptr) const + FindNextValueForName (const Entry *entry_ptr) const { if (!m_map.empty()) { @@ -164,13 +185,46 @@ const Entry *next_entry = entry_ptr + 1; if (first_entry <= next_entry && next_entry < after_last_entry) { - if (next_entry->cstring == unique_cstr) + if (next_entry->cstring == entry_ptr->cstring) return next_entry; } } return NULL; } + size_t + GetValues (const char *unique_cstr, std::vector &values) const + { + const size_t start_size = values.size(); + + Entry search_entry (unique_cstr); + const_iterator pos, end = m_map.end(); + for (pos = std::lower_bound (m_map.begin(), end, search_entry); pos != end; ++pos) + { + if (pos->cstring == unique_cstr) + values.push_back (pos->value); + else + break; + } + + return values.size() - start_size; + } + + size_t + GetValues (const RegularExpression& regex, std::vector &values) const + { + const size_t start_size = values.size(); + + const_iterator pos, end = m_map.end(); + for (pos = m_map.begin(); pos != end; ++pos) + { + if (regex.Execute(pos->cstring)) + values.push_back (pos->value); + } + + return values.size() - start_size; + } + //------------------------------------------------------------------ // Get the total number of entries in this map. //------------------------------------------------------------------ @@ -219,6 +273,24 @@ { std::sort (m_map.begin(), m_map.end()); } + + //------------------------------------------------------------------ + // Since we are using a vector to contain our items it will always + // double its memory consumption as things are added to the vector, + // so if you intend to keep a UniqueCStringMap around and have + // a lot of entries in the map, you will want to call this function + // to create a new vector and copy _only_ the exact size needed as + // part of the finalization of the string map. + //------------------------------------------------------------------ + void + SizeToFit () + { + if (m_map.size() < m_map.capacity()) + { + collection temp (m_map.begin(), m_map.end()); + m_map.swap(temp); + } + } protected: typedef std::vector collection; From gclayton at apple.com Sat Sep 10 19:20:10 2011 From: gclayton at apple.com (Greg Clayton) Date: Sun, 11 Sep 2011 00:20:10 -0000 Subject: [Lldb-commits] [lldb] r139478 - in /lldb/trunk: include/lldb/Core/ConstString.h source/Core/ConstString.cpp source/Symbol/Symtab.cpp Message-ID: <20110911002010.2F2322A6C12C@llvm.org> Author: gclayton Date: Sat Sep 10 19:20:09 2011 New Revision: 139478 URL: http://llvm.org/viewvc/llvm-project?rev=139478&view=rev Log: Fixes for Symtab.cpp to take advantage of the new unique C string map changes that were just submitted. Modified: lldb/trunk/include/lldb/Core/ConstString.h lldb/trunk/source/Core/ConstString.cpp lldb/trunk/source/Symbol/Symtab.cpp Modified: lldb/trunk/include/lldb/Core/ConstString.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConstString.h?rev=139478&r1=139477&r2=139478&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ConstString.h (original) +++ lldb/trunk/include/lldb/Core/ConstString.h Sat Sep 10 19:20:09 2011 @@ -37,7 +37,11 @@ /// /// Initializes the string to an empty string. //------------------------------------------------------------------ - ConstString (); + ConstString (): + m_string (NULL) + { + } + //------------------------------------------------------------------ /// Copy constructor @@ -48,7 +52,10 @@ /// @param[in] rhs /// Another string object to copy. //------------------------------------------------------------------ - ConstString (const ConstString& rhs); + ConstString (const ConstString& rhs) : + m_string (rhs.m_string) + { + } //------------------------------------------------------------------ /// Construct with C String value @@ -99,7 +106,10 @@ /// greater than zero, the string will remain in the string pool /// until the last reference is released by other ConstString objects. //------------------------------------------------------------------ - ~ConstString (); + ~ConstString () + { + } + //---------------------------------------------------------------------- /// C string equality function object for CStrings contains in the @@ -405,7 +415,11 @@ /// @see ConstString::StaticMemorySize () //------------------------------------------------------------------ size_t - MemorySize () const; + MemorySize () const + { + return sizeof(ConstString); + } + //------------------------------------------------------------------ /// Get the size in bytes of the current global string pool. Modified: lldb/trunk/source/Core/ConstString.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConstString.cpp?rev=139478&r1=139477&r2=139478&view=diff ============================================================================== --- lldb/trunk/source/Core/ConstString.cpp (original) +++ lldb/trunk/source/Core/ConstString.cpp Sat Sep 10 19:20:09 2011 @@ -191,27 +191,6 @@ } //---------------------------------------------------------------------- -// Default constructor -// -// Initializes the string to an empty string. -//---------------------------------------------------------------------- -ConstString::ConstString () : - m_string (NULL) -{ -} - -//---------------------------------------------------------------------- -// Copy constructor -// -// Copies the string value in "rhs" and retains an extra reference -// to the string value in the string pool. -//---------------------------------------------------------------------- -ConstString::ConstString (const ConstString& rhs) : - m_string (rhs.m_string) -{ -} - -//---------------------------------------------------------------------- // Construct with C String value // // Constructs this object with a C string by looking to see if the @@ -244,18 +223,6 @@ { } -//---------------------------------------------------------------------- -// Destructor -// -// Decrements the reference count on the contained string, and if -// the resulting reference count is zero, then the string is removed -// from the string pool. If the reference count is still greater -// than zero, the string will remain in the string pool -//---------------------------------------------------------------------- -ConstString::~ConstString () -{ -} - bool ConstString::operator < (const ConstString& rhs) const { @@ -402,17 +369,6 @@ } //---------------------------------------------------------------------- -// Return the size in bytes that this object takes in memory. The -// resulting size will not include any of the C string values from -// the global string pool (see StaticMemorySize ()). -//---------------------------------------------------------------------- -size_t -ConstString::MemorySize() const -{ - return sizeof(ConstString); -} - -//---------------------------------------------------------------------- // Reports the the size in bytes of all shared C string values, // containers and reference count values as a byte size for the // entire string pool. Modified: lldb/trunk/source/Symbol/Symtab.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=139478&r1=139477&r2=139478&view=diff ============================================================================== --- lldb/trunk/source/Symbol/Symtab.cpp (original) +++ lldb/trunk/source/Symbol/Symtab.cpp Sat Sep 10 19:20:09 2011 @@ -462,20 +462,11 @@ Timer scoped_timer (__PRETTY_FUNCTION__, "%s", __PRETTY_FUNCTION__); if (symbol_name) { - const size_t old_size = indexes.size(); + const char *symbol_cstr = symbol_name.GetCString(); if (!m_name_indexes_computed) InitNameIndexes(); - const char *symbol_cstr = symbol_name.GetCString(); - const UniqueCStringMap::Entry *entry_ptr; - - for (entry_ptr = m_name_to_index.FindFirstValueForName (symbol_cstr); - entry_ptr!= NULL; - entry_ptr = m_name_to_index.FindNextValueForName (symbol_cstr, entry_ptr)) - { - indexes.push_back (entry_ptr->value); - } - return indexes.size() - old_size; + return m_name_to_index.GetValues (symbol_cstr, indexes); } return 0; } @@ -493,13 +484,13 @@ InitNameIndexes(); const char *symbol_cstr = symbol_name.GetCString(); - const UniqueCStringMap::Entry *entry_ptr; - for (entry_ptr = m_name_to_index.FindFirstValueForName (symbol_cstr); - entry_ptr!= NULL; - entry_ptr = m_name_to_index.FindNextValueForName (symbol_cstr, entry_ptr)) + + std::vector all_name_indexes; + const size_t name_match_count = m_name_to_index.GetValues (symbol_cstr, all_name_indexes); + for (size_t i=0; ivalue, symbol_debug_type, symbol_visibility)) - indexes.push_back (entry_ptr->value); + if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type, symbol_visibility)) + indexes.push_back (all_name_indexes[i]); } return indexes.size() - old_size; } From gclayton at apple.com Sun Sep 11 22:55:58 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 12 Sep 2011 03:55:58 -0000 Subject: [Lldb-commits] [lldb] r139487 - in /lldb/trunk: include/lldb/Core/ConstString.h source/Core/ConstString.cpp Message-ID: <20110912035558.F07D32A6C12C@llvm.org> Author: gclayton Date: Sun Sep 11 22:55:58 2011 New Revision: 139487 URL: http://llvm.org/viewvc/llvm-project?rev=139487&view=rev Log: Fixed up the comments in the headerdoc to match the current implementation of how ConstString objects work, and removed the duplicate and out of date comments that were in the cpp file. Modified: lldb/trunk/include/lldb/Core/ConstString.h lldb/trunk/source/Core/ConstString.cpp Modified: lldb/trunk/include/lldb/Core/ConstString.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConstString.h?rev=139487&r1=139486&r2=139487&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/ConstString.h (original) +++ lldb/trunk/include/lldb/Core/ConstString.h Sun Sep 11 22:55:58 2011 @@ -23,11 +23,15 @@ /// @class ConstString ConstString.h "lldb/Core/ConstString.h" /// @brief A uniqued constant string class. /// -/// Provides an efficient way to store strings as uniqued ref counted -/// strings. Since the strings are uniqued, finding strings that are -/// equal to one another is very fast (pointer compares). It also allows -/// for many common strings from many different sources to be shared to -/// keep the memory footprint low. +/// Provides an efficient way to store strings as uniqued strings. After +/// the strings are uniqued, finding strings that are equal to one +/// another is very fast as just the pointers need to be compared. It +/// also allows for many common strings from many different sources to +/// be shared to keep the memory footprint low. +/// +/// No reference counting is done on strings that are added to the +/// string pool, once strings are added they are in the string pool for +/// the life of the program. //---------------------------------------------------------------------- class ConstString { @@ -46,8 +50,7 @@ //------------------------------------------------------------------ /// Copy constructor /// - /// Copies the string value in \a rhs and retains an extra reference - /// to the string value in the string pool. + /// Copies the string value in \a rhs into this object. /// /// @param[in] rhs /// Another string object to copy. @@ -61,10 +64,8 @@ /// Construct with C String value /// /// Constructs this object with a C string by looking to see if the - /// C string already exists in the global string pool. If it does - /// exist, it retains an extra reference to the string in the string - /// pool. If it doesn't exist, it is added to the string pool with - /// a reference count of 1. + /// C string already exists in the global string pool. If it doesn't + /// exist, it is added to the string pool. /// /// @param[in] cstr /// A NULL terminated C string to add to the string pool. @@ -80,13 +81,12 @@ /// be created without the need to NULL terminate the string as it /// is passed into this function. /// - /// If the C string already exists in the global string pool, it - /// retains an extra reference to the string in the string - /// pool. If it doesn't exist, it is added to the string pool with - /// a reference count of 1. - /// /// @param[in] cstr - /// A NULL terminated C string to add to the string pool. + /// A pointer to the first character in the C string. The C + /// string can be NULL terminated in a buffer that contains + /// more characters than the length of the stirng, or the + /// string can be part of another string and a new substring + /// can be created. /// /// @param[in] max_cstr_len /// The max length of \a cstr. If the string length of \a cstr @@ -100,11 +100,8 @@ //------------------------------------------------------------------ /// Destructor /// - /// Decrements the reference count on the contained string, and if - /// the resulting reference count is zero, then the string is removed - /// from the global string pool. If the reference count is still - /// greater than zero, the string will remain in the string pool - /// until the last reference is released by other ConstString objects. + /// Since constant string values are currently not reference counted, + /// there isn't much to do here. //------------------------------------------------------------------ ~ConstString () { @@ -112,8 +109,8 @@ //---------------------------------------------------------------------- - /// C string equality function object for CStrings contains in the - /// same StringPool only. (binary predicate). + /// C string equality binary predicate function object for ConstString + /// objects. //---------------------------------------------------------------------- struct StringIsEqual { @@ -157,12 +154,7 @@ //------------------------------------------------------------------ /// Assignment operator /// - /// Assigns the string in this object with the value from \a rhs - /// and increments the reference count of that string. - /// - /// The previously contained string will be get its reference count - /// decremented and removed from the string pool if its reference - /// count reaches zero. + /// Assigns the string in this object with the value from \a rhs. /// /// @param[in] rhs /// Another string object to copy into this object. @@ -182,8 +174,8 @@ /// /// Returns true if this string is equal to the string in \a rhs. /// This operation is very fast as it results in a pointer - /// comparison since all strings are in a uniqued and reference - /// counted string pool. + /// comparison since all strings are in a uniqued in a global string + /// pool. /// /// @param[in] rhs /// Another string object to compare this object to. @@ -205,8 +197,8 @@ /// /// Returns true if this string is not equal to the string in \a rhs. /// This operation is very fast as it results in a pointer - /// comparison since all strings are in a uniqued and reference - /// counted string pool. + /// comparison since all strings are in a uniqued in a global string + /// pool. /// /// @param[in] rhs /// Another string object to compare this object to. @@ -244,12 +236,32 @@ return m_string; } + //------------------------------------------------------------------ + /// Get the string value as a llvm::StringRef + /// + /// @return + /// Returns a new llvm::StringRef object filled in with the + /// needed data. + //------------------------------------------------------------------ llvm::StringRef GetStringRef () const { return llvm::StringRef (m_string, GetLength()); } + //------------------------------------------------------------------ + /// Get the string value as a C string. + /// + /// Get the value of the contained string as a NULL terminated C + /// string value. Similar to the ConstString::AsCString() function, + /// yet this function will always return NULL if the string is not + /// valid. So this function is a direct accessor to the string + /// pointer value. + /// + /// @return + /// Returns NULL the string is invalid, otherwise the C string + /// value contained in this object. + //------------------------------------------------------------------ const char * GetCString () const { @@ -257,17 +269,24 @@ } + //------------------------------------------------------------------ + /// Get the length in bytes of string value. + /// + /// The string pool stores the length of the string, so we can avoid + /// calling strlen() on the pointer value with this function. + /// + /// @return + /// Returns the number of bytes that this string occupies in + /// memory, not including the NULL termination byte. + //------------------------------------------------------------------ size_t GetLength () const; + //------------------------------------------------------------------ /// Clear this object's state. /// /// Clear any contained string and reset the value to the an empty /// string value. - /// - /// The previously contained string will be get its reference count - /// decremented and removed from the string pool if its reference - /// count reaches zero. //------------------------------------------------------------------ void Clear () @@ -281,6 +300,11 @@ /// Compares the C string values contained in \a lhs and \a rhs and /// returns an integer result. /// + /// NOTE: only call this function when you want a true string + /// comparision. If you want string equality use the, use the == + /// operator as it is much more efficient. Also if you want string + /// inequality, use the != operator for the same reasons. + /// /// @param[in] lhs /// The Left Hand Side const ConstString object reference. /// @@ -316,9 +340,6 @@ //------------------------------------------------------------------ /// Dump the object debug description to a stream. /// - /// Dump the string value and the reference count to the stream \a - /// s. - /// /// @param[in] s /// The stream that will be used to dump the object description. //------------------------------------------------------------------ @@ -338,7 +359,6 @@ return m_string == NULL || m_string[0] == '\0'; } - //------------------------------------------------------------------ /// Set the C string value. /// @@ -346,9 +366,8 @@ /// string value in our global string pool. /// /// If the C string already exists in the global string pool, it - /// finds the current entry and retains an extra reference to the - /// string in the string pool. If it doesn't exist, it is added to - /// the string pool with a reference count of 1. + /// finds the current entry and returns the existing value. If it + /// doesn't exist, it is added to the string pool. /// /// @param[in] cstr /// A NULL terminated C string to add to the string pool. @@ -356,9 +375,47 @@ void SetCString (const char *cstr); + //------------------------------------------------------------------ + /// Set the C string value and its mangled counterpart. + /// + /// Object files and debug sybmols often use mangled string to + /// represent the linkage name for a symbol, function or global. + /// The string pool can efficiently store these values and their + /// counterparts so when we run into another instance of a mangled + /// name, we can avoid calling the name demangler over and over on + /// the same strings and then trying to unique them. + /// + /// @param[in] demangled + /// The demangled C string to correlate with the \a mangled + /// name. + /// + /// @param[in] mangled + /// The already uniqued mangled ConstString to correlate the + /// soon to be uniqued version of \a demangled. + //------------------------------------------------------------------ void - SetCStringWithMangledCounterpart (const char *demangled, const ConstString &mangled); + SetCStringWithMangledCounterpart (const char *demangled, + const ConstString &mangled); + //------------------------------------------------------------------ + /// Retrieve the mangled or demangled counterpart for a mangled + /// or demangled ConstString. + /// + /// Object files and debug sybmols often use mangled string to + /// represent the linkage name for a symbol, function or global. + /// The string pool can efficiently store these values and their + /// counterparts so when we run into another instance of a mangled + /// name, we can avoid calling the name demangler over and over on + /// the same strings and then trying to unique them. + /// + /// @param[in] counterpart + /// A reference to a ConstString object that might get filled in + /// with the demangled/mangled counterpart. + /// + /// @return + /// /b True if \a counterpart was filled in with the counterpart + /// /b false otherwise. + //------------------------------------------------------------------ bool GetMangledCounterpart (ConstString &counterpart) const; @@ -369,25 +426,17 @@ /// starting at the \a cstr string value in our global string pool. /// If trim is true, then \a cstr_len indicates a maximum length of /// the CString and if the actual length of the string is less, then - /// it will be trimmed. If trim is false, then this allows strings - /// with NULL characters to be added to the string pool. + /// it will be trimmed. /// /// If the C string already exists in the global string pool, it - /// retains an extra reference to the string in the string - /// pool. If it doesn't exist, it is added to the string pool with - /// a reference count of 1. + /// finds the current entry and returns the existing value. If it + /// doesn't exist, it is added to the string pool. /// /// @param[in] cstr /// A NULL terminated C string to add to the string pool. /// /// @param[in] cstr_len - /// The absolute length of the C string if \a trim is false, - /// or the maximum length of the C string if \a trim is true. - /// - /// @param[in] trim - /// If \b true, trim \a cstr to it's actual length before adding - /// it to the string pool. If \b false then cstr_len is the - /// actual length of the C string to add. + /// The maximum length of the C string. //------------------------------------------------------------------ void SetCStringWithLength (const char *cstr, size_t cstr_len); @@ -425,7 +474,7 @@ /// Get the size in bytes of the current global string pool. /// /// Reports the the size in bytes of all shared C string values, - /// containers and reference count values as a byte size for the + /// containers and any other values as a byte size for the /// entire string pool. /// /// @return Modified: lldb/trunk/source/Core/ConstString.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConstString.cpp?rev=139487&r1=139486&r2=139487&view=diff ============================================================================== --- lldb/trunk/source/Core/ConstString.cpp (original) +++ lldb/trunk/source/Core/ConstString.cpp Sun Sep 11 22:55:58 2011 @@ -14,21 +14,6 @@ using namespace lldb_private; -//---------------------------------------------------------------------- -// The global string pool is implemented as a hash_map that maps -// std::string objects to a uint32_t reference count. -// -// In debug builds the value that is stored in the ConstString objects is -// a C string that is owned by one of the std::string objects in the -// hash map. This was done for visibility purposes when debugging as -// gcc was often generating insufficient debug info for the -// iterator objects. -// -// In release builds, the value that is stored in the ConstString objects -// is the iterator into the ConstString::HashMap. This is much faster when -// it comes to modifying the reference count, and removing strings from -// the pool. -//---------------------------------------------------------------------- class Pool { public: @@ -147,7 +132,7 @@ //------------------------------------------------------------------ // Return the size in bytes that this object and any items in its - // collection of uniqued strings + reference count values takes in + // collection of uniqued strings + data count values takes in // memory. //------------------------------------------------------------------ size_t @@ -190,34 +175,11 @@ return string_pool; } -//---------------------------------------------------------------------- -// Construct with C String value -// -// Constructs this object with a C string by looking to see if the -// C string already exists in the global string pool. If it does -// exist, it retains an extra reference to the string in the string -// pool. If it doesn't exist, it is added to the string pool with -// a reference count of 1. -//---------------------------------------------------------------------- ConstString::ConstString (const char *cstr) : m_string (StringPool().GetConstCString (cstr)) { } -//---------------------------------------------------------------------- -// Construct with C String value with max length -// -// Constructs this object with a C string with a length. If -// the length of the string is greather than "cstr_len", the -// string length will be truncated. This allows substrings to be -// created without the need to NULL terminate the string as it -// is passed into this function. -// -// If the C string already exists in the global string pool, it -// retains an extra reference to the string in the string -// pool. If it doesn't exist, it is added to the string pool with -// a reference count of 1. -//---------------------------------------------------------------------- ConstString::ConstString (const char *cstr, size_t cstr_len) : m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len)) { @@ -240,9 +202,6 @@ return lhs_string_ref.data() == NULL; } -//---------------------------------------------------------------------- -// Stream the string value "str" to the stream "s" -//---------------------------------------------------------------------- Stream& lldb_private::operator << (Stream& s, const ConstString& str) { @@ -259,14 +218,6 @@ return StringPool().GetConstCStringLength (m_string); } -//---------------------------------------------------------------------- -// Compare two string objects. -// -// Returns: -// -1 if a < b -// 0 if a == b -// 1 if a > b -//---------------------------------------------------------------------- int ConstString::Compare (const ConstString& lhs, const ConstString& rhs) { @@ -288,12 +239,6 @@ return -1; // LHS is NULL but RHS isn't } -//---------------------------------------------------------------------- -// Dump the string value to the stream "s". If the contained string -// is empty, print "fail_value" to the stream instead. If -// "fail_value" is NULL, then nothing will be dumped to the -// stream. -//---------------------------------------------------------------------- void ConstString::Dump(Stream *s, const char *fail_value) const { @@ -302,9 +247,6 @@ s->PutCString (cstr); } -//---------------------------------------------------------------------- -// Dump extra debug information to the stream "s". -//---------------------------------------------------------------------- void ConstString::DumpDebug(Stream *s) const { @@ -315,15 +257,6 @@ s->Printf("%*p: ConstString, string = %s%s%s, length = %zu", (int)sizeof(void*) * 2, this, parens, cstr, parens, cstr_len); } -//---------------------------------------------------------------------- -// Set the string value in the object by uniquing the "cstr" string -// value in our global string pool. -// -// If the C string already exists in the global string pool, it -// retains an extra reference to the string in the string -// pool. If it doesn't exist, it is added to the string pool with -// a reference count of 1. -//---------------------------------------------------------------------- void ConstString::SetCString (const char *cstr) { @@ -343,19 +276,6 @@ return counterpart; } -//---------------------------------------------------------------------- -// Set the string value in the object by uniquing "cstr_len" bytes -// starting at the "cstr" string value in our global string pool. -// If trim is true, then "cstr_len" indicates a maximum length of -// the CString and if the actual length of the string is less, then -// it will be trimmed. If trim is false, then this allows strings -// with NULL characters ('\0') to be added to the string pool. -// -// If the C string already exists in the global string pool, it -// retains an extra reference to the string in the string -// pool. If it doesn't exist, it is added to the string pool with -// a reference count of 1. -//---------------------------------------------------------------------- void ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len) { @@ -368,11 +288,6 @@ m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len); } -//---------------------------------------------------------------------- -// Reports the the size in bytes of all shared C string values, -// containers and reference count values as a byte size for the -// entire string pool. -//---------------------------------------------------------------------- size_t ConstString::StaticMemorySize() { From gclayton at apple.com Sun Sep 11 23:00:42 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 12 Sep 2011 04:00:42 -0000 Subject: [Lldb-commits] [lldb] r139488 - in /lldb/trunk: include/lldb/Host/FileSpec.h source/Host/common/FileSpec.cpp Message-ID: <20110912040042.6A3962A6C12C@llvm.org> Author: gclayton Date: Sun Sep 11 23:00:42 2011 New Revision: 139488 URL: http://llvm.org/viewvc/llvm-project?rev=139488&view=rev Log: Changed to using an "operator bool" instead of an "operator void*" and avoid returning a pointer to the current object. In the new "operator bool" implementation, check the filename object first since many times we have FileSpec objects with a filename, yet no directory. Modified: lldb/trunk/include/lldb/Host/FileSpec.h lldb/trunk/source/Host/common/FileSpec.cpp Modified: lldb/trunk/include/lldb/Host/FileSpec.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=139488&r1=139487&r2=139488&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/FileSpec.h (original) +++ lldb/trunk/include/lldb/Host/FileSpec.h Sun Sep 11 23:00:42 2011 @@ -180,8 +180,7 @@ /// A pointer to this object if either the directory or filename /// is valid, NULL otherwise. //------------------------------------------------------------------ - operator - void* () const; + operator bool() const; //------------------------------------------------------------------ /// Logical NOT operator. Modified: lldb/trunk/source/Host/common/FileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=139488&r1=139487&r2=139488&view=diff ============================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp (original) +++ lldb/trunk/source/Host/common/FileSpec.cpp Sun Sep 11 23:00:42 2011 @@ -352,10 +352,9 @@ // if (file_spec) // {} //---------------------------------------------------------------------- -FileSpec::operator -void*() const +FileSpec::operator bool() const { - return (m_directory || m_filename) ? const_cast(this) : NULL; + return m_filename || m_directory; } //---------------------------------------------------------------------- From gclayton at apple.com Sun Sep 11 23:05:41 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 12 Sep 2011 04:05:41 -0000 Subject: [Lldb-commits] [lldb] r139489 - in /lldb/trunk/source: Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Plugins/SymbolFile/DWARF/LogChannelDWARF.h lldb-log.cpp Message-ID: <20110912040541.AD1132A6C12C@llvm.org> Author: gclayton Date: Sun Sep 11 23:05:41 2011 New Revision: 139489 URL: http://llvm.org/viewvc/llvm-project?rev=139489&view=rev Log: Fixed the logging output to be done consistently across all plug-ins. Added a new log category for DWARF called "aranges" to log the parsing of address ranges. Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h lldb/trunk/source/lldb-log.cpp Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp?rev=139489&r1=139488&r2=139489&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp Sun Sep 11 23:05:41 2011 @@ -151,21 +151,21 @@ void ProcessKDPLog::ListLogCategories (Stream *strm) { - strm->Printf("Logging categories for '%s':\n" - "\tall - turn on all available logging categories\n" - "\tasync - log asynchronous activity\n" - "\tbreak - log breakpoints\n" - "\tcommunication - log communication activity\n" - "\tdefault - enable the default set of logging categories for liblldb\n" - "\tpackets - log gdb remote packets\n" - "\tmemory - log memory reads and writes\n" - "\tdata-short - log memory bytes for memory reads and writes for short transactions only\n" - "\tdata-long - log memory bytes for memory reads and writes for all transactions\n" - "\tprocess - log process events and activities\n" - "\tthread - log thread events and activities\n" - "\tstep - log step related activities\n" - "\tverbose - enable verbose logging\n" - "\twatch - log watchpoint related activities\n", ProcessKDP::GetPluginNameStatic()); + strm->Printf ("Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " async - log asynchronous activity\n" + " break - log breakpoints\n" + " communication - log communication activity\n" + " default - enable the default set of logging categories for liblldb\n" + " packets - log gdb remote packets\n" + " memory - log memory reads and writes\n" + " data-short - log memory bytes for memory reads and writes for short transactions only\n" + " data-long - log memory bytes for memory reads and writes for all transactions\n" + " process - log process events and activities\n" + " thread - log thread events and activities\n" + " step - log step related activities\n" + " verbose - enable verbose logging\n" + " watch - log watchpoint related activities\n", ProcessKDP::GetPluginNameStatic()); } Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp?rev=139489&r1=139488&r2=139489&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Sun Sep 11 23:05:41 2011 @@ -151,21 +151,21 @@ void ProcessGDBRemoteLog::ListLogCategories (Stream *strm) { - strm->Printf("Logging categories for '%s':\n" - "\tall - turn on all available logging categories\n" - "\tasync - log asynchronous activity\n" - "\tbreak - log breakpoints\n" - "\tcommunication - log communication activity\n" - "\tdefault - enable the default set of logging categories for liblldb\n" - "\tpackets - log gdb remote packets\n" - "\tmemory - log memory reads and writes\n" - "\tdata-short - log memory bytes for memory reads and writes for short transactions only\n" - "\tdata-long - log memory bytes for memory reads and writes for all transactions\n" - "\tprocess - log process events and activities\n" - "\tthread - log thread events and activities\n" - "\tstep - log step related activities\n" - "\tverbose - enable verbose logging\n" - "\twatch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic()); + strm->Printf ("Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " async - log asynchronous activity\n" + " break - log breakpoints\n" + " communication - log communication activity\n" + " default - enable the default set of logging categories for liblldb\n" + " packets - log gdb remote packets\n" + " memory - log memory reads and writes\n" + " data-short - log memory bytes for memory reads and writes for short transactions only\n" + " data-long - log memory bytes for memory reads and writes for all transactions\n" + " process - log process events and activities\n" + " thread - log thread events and activities\n" + " step - log step related activities\n" + " verbose - enable verbose logging\n" + " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic()); } Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=139489&r1=139488&r2=139489&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Sun Sep 11 23:05:41 2011 @@ -108,6 +108,7 @@ else if (::strcasecmp (arg, "line") == 0 ) flag_bits &= ~DWARF_LOG_DEBUG_LINE; else if (::strcasecmp (arg, "pubnames") == 0 ) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES; else if (::strcasecmp (arg, "pubtypes") == 0 ) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES; + else if (::strcasecmp (arg, "aranges") == 0 ) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES; else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~DWARF_LOG_DEFAULT; else { @@ -149,6 +150,7 @@ else if (::strcasecmp (arg, "line") == 0 ) flag_bits |= DWARF_LOG_DEBUG_LINE; else if (::strcasecmp (arg, "pubnames") == 0 ) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES; else if (::strcasecmp (arg, "pubtypes") == 0 ) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES; + else if (::strcasecmp (arg, "aranges") == 0 ) flag_bits |= DWARF_LOG_DEBUG_ARANGES; else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= DWARF_LOG_DEFAULT; else { @@ -170,13 +172,13 @@ void LogChannelDWARF::ListCategories (Stream *strm) { - strm->Printf("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " info - log the parsing if .debug_info\n" - " line - log the parsing if .debug_line\n" - " pubnames - log the parsing if .debug_pubnames\n" - " pubtypes - log the parsing if .debug_pubtypes\n\n", - SymbolFileDWARF::GetPluginNameStatic()); + strm->Printf ("Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " info - log the parsing if .debug_info\n" + " line - log the parsing if .debug_line\n" + " pubnames - log the parsing if .debug_pubnames\n" + " pubtypes - log the parsing if .debug_pubtypes\n\n", + SymbolFileDWARF::GetPluginNameStatic()); } Log * Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h?rev=139489&r1=139488&r2=139489&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h Sun Sep 11 23:05:41 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LogChannelDWARF_h_ -#define liblldb_LogChannelDWARF_h_ +#ifndef SymbolFileDWARF_LogChannelDWARF_h_ +#define SymbolFileDWARF_LogChannelDWARF_h_ // C Includes // C++ Includes @@ -22,6 +22,7 @@ #define DWARF_LOG_DEBUG_LINE (1u << 2) #define DWARF_LOG_DEBUG_PUBNAMES (1u << 3) #define DWARF_LOG_DEBUG_PUBTYPES (1u << 4) +#define DWARF_LOG_DEBUG_ARANGES (1u << 5) #define DWARF_LOG_ALL (UINT32_MAX) #define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO) @@ -82,4 +83,4 @@ LogIf (uint32_t mask, const char *format, ...); }; -#endif // liblldb_LogChannelDWARF_h_ +#endif // SymbolFileDWARF_LogChannelDWARF_h_ Modified: lldb/trunk/source/lldb-log.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb-log.cpp?rev=139489&r1=139488&r2=139489&view=diff ============================================================================== --- lldb/trunk/source/lldb-log.cpp (original) +++ lldb/trunk/source/lldb-log.cpp Sun Sep 11 23:05:41 2011 @@ -225,22 +225,22 @@ lldb_private::ListLogCategories (Stream *strm) { strm->Printf("Logging categories for 'lldb':\n" - "\tall - turn on all available logging categories\n" - "\tapi - enable logging of API calls and return values\n" - "\tcommand - log command argument parsing\n" - "\tdefault - enable the default set of logging categories for liblldb\n" - "\tbreak - log breakpoints\n" - "\tevents - log broadcaster, listener and event queue activities\n" - "\texpr - log expressions\n" - "\tobject - log object construction/destruction for important objects\n" - "\tprocess - log process events and activities\n" - "\tthread - log thread events and activities\n" - "\tscript - log events about the script interpreter\n" - "\tdyld - log shared library related activities\n" - "\tstate - log private and public process state changes\n" - "\tstep - log step related activities\n" - "\tunwind - log stack unwind activities\n" - "\tverbose - enable verbose logging\n" - "\twatch - log watchpoint related activities\n" - "\ttypes - log type system related activities\n"); + " all - turn on all available logging categories\n" + " api - enable logging of API calls and return values\n" + " command - log command argument parsing\n" + " default - enable the default set of logging categories for liblldb\n" + " break - log breakpoints\n" + " events - log broadcaster, listener and event queue activities\n" + " expr - log expressions\n" + " object - log object construction/destruction for important objects\n" + " process - log process events and activities\n" + " thread - log thread events and activities\n" + " script - log events about the script interpreter\n" + " dyld - log shared library related activities\n" + " state - log private and public process state changes\n" + " step - log step related activities\n" + " unwind - log stack unwind activities\n" + " verbose - enable verbose logging\n" + " watch - log watchpoint related activities\n" + " types - log type system related activities\n"); } From gclayton at apple.com Sun Sep 11 23:20:39 2011 From: gclayton at apple.com (Greg Clayton) Date: Mon, 12 Sep 2011 04:20:39 -0000 Subject: [Lldb-commits] [lldb] r139490 - in /lldb/trunk/source/Plugins/SymbolFile/DWARF: DWARFAttribute.h DWARFDIECollection.h DWARFDebugAbbrev.h DWARFDebugArangeSet.h DWARFDebugInfoEntry.h DWARFDebugLine.h DWARFDebugMacinfo.h DWARFDebugMacinfoEntry.h DWARFDebugPubnames.h DWARFDebugPubnamesSet.h DWARFDebugRanges.h DWARFDefines.h DWARFFormValue.h DWARFLocationDescription.h DWARFLocationList.h SymbolFileDWARFDebugMap.h Message-ID: <20110912042039.3E5D12A6C12C@llvm.org> Author: gclayton Date: Sun Sep 11 23:20:38 2011 New Revision: 139490 URL: http://llvm.org/viewvc/llvm-project?rev=139490&view=rev Log: Fixed the header guards. Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFAttribute_h_ -#define liblldb_DWARFAttribute_h_ +#ifndef SymbolFileDWARF_DWARFAttribute_h_ +#define SymbolFileDWARF_DWARFAttribute_h_ #include "DWARFDefines.h" #include @@ -42,4 +42,4 @@ }; -#endif // liblldb_DWARFAttribute_h_ +#endif // SymbolFileDWARF_DWARFAttribute_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDIECollection.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDIECollection_h_ +#ifndef SymbolFileDWARF_DWARFDIECollection_h_ #define SymbolFileDWARF_DWARFDIECollection_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugAbbrev_h_ +#ifndef SymbolFileDWARF_DWARFDebugAbbrev_h_ #define SymbolFileDWARF_DWARFDebugAbbrev_h_ #include Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugArangeSet_h_ +#ifndef SymbolFileDWARF_DWARFDebugArangeSet_h_ #define SymbolFileDWARF_DWARFDebugArangeSet_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugInfoEntry_h_ -#define liblldb_DWARFDebugInfoEntry_h_ +#ifndef SymbolFileDWARF_DWARFDebugInfoEntry_h_ +#define SymbolFileDWARF_DWARFDebugInfoEntry_h_ #include "SymbolFileDWARF.h" @@ -332,4 +332,4 @@ const DWARFAbbreviationDeclaration* m_abbrevDecl; }; -#endif // liblldb_DWARFDebugInfoEntry_h_ +#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugLine_h_ -#define liblldb_DWARFDebugLine_h_ +#ifndef SymbolFileDWARF_DWARFDebugLine_h_ +#define SymbolFileDWARF_DWARFDebugLine_h_ #include #include @@ -119,7 +119,7 @@ dw_addr_t address; // The program-counter value corresponding to a machine instruction generated by the compiler. uint32_t line; // An unsigned integer indicating a source line number. Lines are numbered beginning at 1. The compiler may emit the value 0 in cases where an instruction cannot be attributed to any source line. - uint16_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the ??????left edge?????? of the line. + uint16_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered beginning at 1. The value 0 is reserved to indicate that a statement begins at the 'left edge' of the line. uint16_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine instruction. uint8_t is_stmt:1, // A boolean indicating that the current instruction is the beginning of a statement. basic_block:1, // A boolean indicating that the current instruction is the beginning of a basic block. @@ -222,4 +222,4 @@ LineTableMap m_lineTableMap; }; -#endif // liblldb_DWARFDebugLine_h_ +#endif // SymbolFileDWARF_DWARFDebugLine_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugLine_h_ +#ifndef SymbolFileDWARF_DWARFDebugLine_h_ #define SymbolFileDWARF_DWARFDebugLine_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugMacinfoEntry_h_ +#ifndef SymbolFileDWARF_DWARFDebugMacinfoEntry_h_ #define SymbolFileDWARF_DWARFDebugMacinfoEntry_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugPubnames_h_ +#ifndef SymbolFileDWARF_DWARFDebugPubnames_h_ #define SymbolFileDWARF_DWARFDebugPubnames_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugPubnamesSet_h_ +#ifndef SymbolFileDWARF_DWARFDebugPubnamesSet_h_ #define SymbolFileDWARF_DWARFDebugPubnamesSet_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDebugRanges_h_ -#define liblldb_DWARFDebugRanges_h_ +#ifndef SymbolFileDWARF_DWARFDebugRanges_h_ +#define SymbolFileDWARF_DWARFDebugRanges_h_ #include "SymbolFileDWARF.h" #include @@ -86,4 +86,4 @@ }; -#endif // liblldb_DWARFDebugRanges_h_ +#endif // SymbolFileDWARF_DWARFDebugRanges_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDefines.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFDefines_h_ -#define liblldb_DWARFDefines_h_ +#ifndef SymbolFileDWARF_DWARFDefines_h_ +#define SymbolFileDWARF_DWARFDefines_h_ #include #include @@ -113,4 +113,4 @@ } // namespace lldb_private -#endif // liblldb_DWARFDefines_h_ +#endif // SymbolFileDWARF_DWARFDefines_h_ Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h Sun Sep 11 23:20:38 2011 @@ -6,14 +6,9 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// - -// -//===----------------------------------------------------------------------===// - #ifndef liblldb_DWARFFormValue_h_ - #define SymbolFileDWARF_DWARFFormValue_h_ +#ifndef SymbolFileDWARF_DWARFFormValue_h_ +#define SymbolFileDWARF_DWARFFormValue_h_ #include "SymbolFileDWARF.h" #include // for NULL Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFLocationDescription_h_ +#ifndef SymbolFileDWARF_DWARFLocationDescription_h_ #define SymbolFileDWARF_DWARFLocationDescription_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h Sun Sep 11 23:20:38 2011 @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_DWARFLocationList_h_ +#ifndef SymbolFileDWARF_DWARFLocationList_h_ #define SymbolFileDWARF_DWARFLocationList_h_ #include "SymbolFileDWARF.h" Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=139490&r1=139489&r2=139490&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Sun Sep 11 23:20:38 2011 @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_SymbolFileDWARFDebugMap_h_ -#define liblldb_SymbolFileDWARFDebugMap_h_ +#ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ +#define SymbolFileDWARF_SymbolFileDWARFDebugMap_h_ #include @@ -219,4 +219,4 @@ UniqueDWARFASTTypeMap m_unique_ast_type_map; }; -#endif // #ifndef liblldb_SymbolFileDWARFDebugMap_h_ +#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
    Show all thread registers.
    Select a different stack frame by index for the current thread.
    - (lldb) register read + (lldb) frame select 12
    - (gdb) info all-registers + (gdb) frame 12
    Show the values for the thread registers name "rax", "rsp" and "rbp".
    Select the stack frame that called the current stack frame.
    - (lldb) register read rax rsp rbp + (lldb) up
    + (lldb) frame select --relative=1
    - (gdb) info all-registers rax rsp rbp + (gdb) up +
    Select the stack frame that is called by the current stack frame.
    + (lldb) down
    + (lldb) frame select --relative=-1
    + (lldb) frame select -r-1
    +
    + (gdb) down +
    Select a different stack frame using a relative offset.
    + (lldb) frame select --relative 2
    + (lldb) frame select -r2
    +
    + (lldb) frame select --relative -3
    + (lldb) frame select -r-3
    +
    + (gdb) up 2
    + (gdb) down 3
    +
    Show the general purpose registers for the current thread.
    + (lldb) register read
    +
    + (gdb) info registers
    +
    Show the general purpose registers for the current thread formatted as unsigned decimal. LLDB tries to use + the same format characters as printf when possible.
    + (lldb) register read --format i
    + (lldb) register read -f i
    +
    +
    Show all registers in all register sets for the current thread.
    + (lldb) register read --all
    + (lldb) register read -a
    +
    + (gdb) info all-registers
    +
    Show the values for the registers named "rax", "rsp" and "rbp" in the current thread.
    + (lldb) register read rax rsp rbp
    +
    + (gdb) info all-registers rax rsp rbp
    +
    Show the values for the register named "rax" in the current thread formatted as binary.
    + (lldb) register read --format binary rax
    + (lldb) register read -f b rax
    +
    + (gdb) p/t $rax
    (lldb) memory read --size 4 --format x --count 4 0xbffff3c0
    (lldb) memory read -s4 -fx -c4 0xbffff3c0
    - (lldb) x -s4 -fx -c4 0xbffff3c0 + (lldb) x -s4 -fx -c4 0xbffff3c0
    - (gdb) x/4xw 0xbffff3c0 + (gdb) x/4xw 0xbffff3c0