diff options
Diffstat (limited to 'source/Core')
71 files changed, 2048 insertions, 9138 deletions
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp index e2ccf9d72216..91229a9b18eb 100644 --- a/source/Core/Address.cpp +++ b/source/Core/Address.cpp @@ -9,23 +9,53 @@ #include "lldb/Core/Address.h" -// C Includes -// C++ Includes -#include "llvm/ADT/Triple.h" - -// Other libraries and framework includes -// Project includes +#include "lldb/Core/ArchSpec.h" // for ArchSpec +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Core/Section.h" #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Declaration.h" // for Declaration +#include "lldb/Symbol/LineEntry.h" // for LineEntry #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" // for Symbol +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Symtab.h" // for Symtab +#include "lldb/Symbol/Type.h" // for Type #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextScope #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Endian.h" // for InlHostByteOrder +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" // for StreamString + +#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <cstdint> // for uint8_t, uint32_t +#include <memory> // for shared_ptr, operator!= +#include <vector> // for vector + +#include <assert.h> // for assert +#include <inttypes.h> // for PRIu64, PRIx64 +#include <string.h> // for size_t, strlen + +namespace lldb_private { +class CompileUnit; +} +namespace lldb_private { +class Function; +} using namespace lldb; using namespace lldb_private; @@ -143,15 +173,15 @@ static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address, if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) { DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size); - data.Dump(strm, - 0, // Start offset in "data" - eFormatHex, // Print as characters - buf.size(), // Size of item - 1, // Items count - UINT32_MAX, // num per line - LLDB_INVALID_ADDRESS, // base address - 0, // bitfield bit size - 0); // bitfield bit offset + DumpDataExtractor(data, strm, + 0, // Start offset in "data" + eFormatHex, // Print as characters + buf.size(), // Size of item + 1, // Items count + UINT32_MAX, // num per line + LLDB_INVALID_ADDRESS, // base address + 0, // bitfield bit size + 0); // bitfield bit offset return true; } @@ -181,16 +211,16 @@ static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope, if (len > bytes_read) len = bytes_read; - data.Dump(strm, - 0, // Start offset in "data" - eFormatChar, // Print as characters - 1, // Size of item (1 byte for a char!) - len, // How many bytes to print? - UINT32_MAX, // num per line - LLDB_INVALID_ADDRESS, // base address - 0, // bitfield bit size + DumpDataExtractor(data, strm, + 0, // Start offset in "data" + eFormatChar, // Print as characters + 1, // Size of item (1 byte for a char!) + len, // How many bytes to print? + UINT32_MAX, // num per line + LLDB_INVALID_ADDRESS, // base address + 0, // bitfield bit size - 0); // bitfield bit offset + 0); // bitfield bit offset total_len += bytes_read; diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp index e03d721b566d..c1507797b374 100644 --- a/source/Core/AddressRange.cpp +++ b/source/Core/AddressRange.cpp @@ -8,10 +8,23 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/AddressRange.h" +#include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Module.h" -#include "lldb/Core/Stream.h" -#include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS + +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <memory> // for shared_ptr + +#include <inttypes.h> // for PRIx64 + +namespace lldb_private { +class SectionList; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/AddressResolver.cpp b/source/Core/AddressResolver.cpp index 40f4d55340ec..8d7cc9f6a428 100644 --- a/source/Core/AddressResolver.cpp +++ b/source/Core/AddressResolver.cpp @@ -9,16 +9,11 @@ #include "lldb/Core/AddressResolver.h" -// Project includes - -#include "lldb/Core/Address.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/Target.h" + +namespace lldb_private { +class ModuleList; +} using namespace lldb_private; diff --git a/source/Core/AddressResolverFileLine.cpp b/source/Core/AddressResolverFileLine.cpp index 939cf45f3e88..798a9b50079e 100644 --- a/source/Core/AddressResolverFileLine.cpp +++ b/source/Core/AddressResolverFileLine.cpp @@ -9,11 +9,21 @@ #include "lldb/Core/AddressResolverFileLine.h" -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineEntry.h" // for LineEntry #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIB... +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" // for SymbolContextItem::eSymbolCon... +#include "lldb/lldb-types.h" // for addr_t + +#include <inttypes.h> // for PRIx64 +#include <vector> // for vector using namespace lldb; using namespace lldb_private; diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp index d9b6dad5e4e3..9935362e0e98 100644 --- a/source/Core/AddressResolverName.cpp +++ b/source/Core/AddressResolverName.cpp @@ -9,16 +9,25 @@ #include "lldb/Core/AddressResolverName.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" +#include "lldb/Core/Address.h" // for Address, operator== +#include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/Module.h" -#include "lldb/Core/StreamString.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIB... +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/lldb-enumerations.h" // for SymbolType::eSymbolTypeCode +#include "lldb/lldb-forward.h" // for ModuleSP +#include "lldb/lldb-types.h" // for addr_t +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <memory> // for shared_ptr +#include <string> // for string +#include <vector> // for vector + +#include <stdint.h> // for uint32_t using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index cf7afb83dabd..60ee237aa0f5 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -9,31 +9,30 @@ #include "lldb/Core/ArchSpec.h" -// C Includes -// C++ Includes -#include <cerrno> -#include <cstdio> -#include <string> +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/NameMatches.h" +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StringList.h" +#include "lldb/lldb-defines.h" // for LLDB_INVALID_C... +#include "lldb/lldb-forward.h" // for RegisterContextSP + +#include "Plugins/Process/Utility/ARMDefines.h" +#include "Plugins/Process/Utility/InstructionUtils.h" -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Twine.h" // for Twine #include "llvm/Support/COFF.h" +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH #include "llvm/Support/ELF.h" #include "llvm/Support/Host.h" +#include "llvm/Support/MachO.h" // for CPUType::CPU_T... -// Project includes -#include "Plugins/Process/Utility/ARMDefines.h" -#include "Plugins/Process/Utility/InstructionUtils.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/StringList.h" -#include "lldb/Host/Endian.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Target/Platform.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/NameMatches.h" -#include "lldb/Utility/SafeMachO.h" +#include <memory> // for shared_ptr +#include <string> +#include <tuple> // for tie, tuple using namespace lldb; using namespace lldb_private; @@ -259,7 +258,7 @@ struct ArchDefinition { size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) { if (!name.empty()) { for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { - if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name)) + if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, name)) matches.AppendString(g_core_definitions[i].name); } } else { @@ -657,7 +656,7 @@ void ArchSpec::SetFlags(std::string elf_abi) { SetFlags(flag); } -std::string ArchSpec::GetClangTargetCPU() { +std::string ArchSpec::GetClangTargetCPU() const { std::string cpu; const llvm::Triple::ArchType machine = GetMachine(); @@ -1380,7 +1379,7 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2, if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= ArchSpec::kCore_mips32el_last) return true; - try_inverse = false; + try_inverse = true; } break; diff --git a/source/Core/Baton.cpp b/source/Core/Baton.cpp deleted file mode 100644 index 998a5dffca9c..000000000000 --- a/source/Core/Baton.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//===-- Baton.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/Baton.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Stream.h" - -using namespace lldb; -using namespace lldb_private; - -void UntypedBaton::GetDescription(Stream *s, - lldb::DescriptionLevel level) const {} diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp index d2cca7a2a654..7a4932c4987e 100644 --- a/source/Core/Broadcaster.cpp +++ b/source/Core/Broadcaster.cpp @@ -9,21 +9,26 @@ #include "lldb/Core/Broadcaster.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Event.h" #include "lldb/Core/Listener.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAnyCategoriesSet, Get... +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" + +#include <algorithm> // for find_if +#include <memory> // for make_shared +#include <type_traits> // for move + +#include <assert.h> // for assert +#include <stddef.h> // for size_t using namespace lldb; using namespace lldb_private; Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) - : m_broadcaster_sp(new BroadcasterImpl(*this)), m_manager_sp(manager_sp), - m_broadcaster_name(name) { + : m_broadcaster_sp(std::make_shared<BroadcasterImpl>(*this)), + m_manager_sp(manager_sp), m_broadcaster_name(name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) log->Printf("%p Broadcaster::Broadcaster(\"%s\")", @@ -242,19 +247,19 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, void Broadcaster::BroadcasterImpl::BroadcastEvent(uint32_t event_type, EventData *event_data) { - EventSP event_sp(new Event(event_type, event_data)); + auto event_sp = std::make_shared<Event>(event_type, event_data); PrivateBroadcastEvent(event_sp, false); } void Broadcaster::BroadcasterImpl::BroadcastEvent( uint32_t event_type, const lldb::EventDataSP &event_data_sp) { - EventSP event_sp(new Event(event_type, event_data_sp)); + auto event_sp = std::make_shared<Event>(event_type, event_data_sp); PrivateBroadcastEvent(event_sp, false); } void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique( uint32_t event_type, EventData *event_data) { - EventSP event_sp(new Event(event_type, event_data)); + auto event_sp = std::make_shared<Event>(event_type, event_data); PrivateBroadcastEvent(event_sp, true); } @@ -329,7 +334,7 @@ operator=(const BroadcastEventSpec &rhs) = default; BroadcasterManager::BroadcasterManager() : m_manager_mutex() {} lldb::BroadcasterManagerSP BroadcasterManager::MakeBroadcasterManager() { - return BroadcasterManagerSP(new BroadcasterManager()); + return lldb::BroadcasterManagerSP(new BroadcasterManager()); } uint32_t BroadcasterManager::RegisterListenerForEvents( diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt index 2bbe7455418a..7dcec050d866 100644 --- a/source/Core/CMakeLists.txt +++ b/source/Core/CMakeLists.txt @@ -5,30 +5,20 @@ add_lldb_library(lldbCore AddressResolverFileLine.cpp AddressResolverName.cpp ArchSpec.cpp - Baton.cpp Broadcaster.cpp Communication.cpp Connection.cpp - ConstString.cpp - DataBufferHeap.cpp - DataBufferMemoryMap.cpp - DataEncoder.cpp - DataExtractor.cpp Debugger.cpp Disassembler.cpp + DumpDataExtractor.cpp DynamicLoader.cpp EmulateInstruction.cpp - Error.cpp Event.cpp - FastDemangle.cpp FileLineResolver.cpp FileSpecList.cpp FormatEntity.cpp - History.cpp IOHandler.cpp Listener.cpp - Log.cpp - Logging.cpp Mangled.cpp Module.cpp ModuleChild.cpp @@ -36,24 +26,16 @@ add_lldb_library(lldbCore Opcode.cpp PluginManager.cpp RegisterValue.cpp - RegularExpression.cpp Scalar.cpp SearchFilter.cpp Section.cpp SourceManager.cpp State.cpp - Stream.cpp StreamAsynchronousIO.cpp - StreamCallback.cpp StreamFile.cpp - StreamGDBRemote.cpp - StreamString.cpp - StringList.cpp StructuredData.cpp Timer.cpp - UserID.cpp UserSettingsController.cpp - UUID.cpp Value.cpp ValueObject.cpp ValueObjectCast.cpp @@ -68,6 +50,27 @@ add_lldb_library(lldbCore ValueObjectRegister.cpp ValueObjectSyntheticFilter.cpp ValueObjectVariable.cpp - VMRange.cpp + + LINK_LIBS + clangAST + lldbBreakpoint + lldbDataFormatters + lldbExpression + lldbHost + lldbInterpreter + lldbSymbol + lldbTarget + lldbUtility + lldbPluginProcessUtility + lldbPluginCPlusPlusLanguage + lldbPluginObjCLanguage + lldbPluginObjectFileJIT + + LINK_COMPONENTS + Support + Demangle ) +# Needed to properly resolve references in a debug build. +# TODO: Remove once we have better layering +set_target_properties(lldbCore PROPERTIES LINK_INTERFACE_MULTIPLICITY 4) diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp index 3d3abea62489..a543858582ef 100644 --- a/source/Core/Communication.cpp +++ b/source/Core/Communication.cpp @@ -7,21 +7,30 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -#include <cstring> - -// Other libraries and framework includes -// Project includes #include "lldb/Core/Communication.h" + #include "lldb/Core/Connection.h" #include "lldb/Core/Event.h" #include "lldb/Core/Listener.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Timer.h" -#include "lldb/Host/Host.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/ThreadLauncher.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for LogIfAnyCategoriesSet, LIBLLDB... + +#include "llvm/ADT/None.h" // for None +#include "llvm/ADT/Optional.h" // for Optional +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <algorithm> // for min +#include <chrono> // for duration, seconds +#include <cstring> +#include <memory> // for shared_ptr + +#include <errno.h> // for EIO +#include <inttypes.h> // for PRIu64 +#include <stdio.h> // for snprintf using namespace lldb; using namespace lldb_private; @@ -115,12 +124,11 @@ bool Communication::HasConnection() const { size_t Communication::Read(void *dst, size_t dst_len, const Timeout<std::micro> &timeout, ConnectionStatus &status, Error *error_ptr) { - lldb_private::LogIfAnyCategoriesSet( - LIBLLDB_LOG_COMMUNICATION, - "%p Communication::Read (dst = %p, dst_len = %" PRIu64 - ", timeout = %u usec) connection = %p", - this, dst, (uint64_t)dst_len, timeout ? timeout->count() : -1, - m_connection_sp.get()); + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION); + LLDB_LOG( + log, + "this = {0}, dst = {1}, dst_len = {2}, timeout = {3}, connection = {4}", + this, dst, dst_len, timeout, m_connection_sp.get()); if (m_read_thread_enabled) { // We have a dedicated read thread that is getting data for us @@ -322,10 +330,9 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { comm->Disconnect(); done = true; } - if (log) - error.LogIfError( - log, "%p Communication::ReadFromConnection () => status = %s", p, - Communication::ConnectionStatusAsCString(status)); + if (error.Fail()) + LLDB_LOG(log, "error: {0}, status = {1}", error, + Communication::ConnectionStatusAsCString(status)); break; case eConnectionStatusInterrupted: // Synchronization signal from // SynchronizeWithReadThread() @@ -340,10 +347,9 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { done = true; LLVM_FALLTHROUGH; case eConnectionStatusTimedOut: // Request timed out - if (log) - error.LogIfError( - log, "%p Communication::ReadFromConnection () => status = %s", p, - Communication::ConnectionStatusAsCString(status)); + if (error.Fail()) + LLDB_LOG(log, "error: {0}, status = {1}", error, + Communication::ConnectionStatusAsCString(status)); break; } } diff --git a/source/Core/Connection.cpp b/source/Core/Connection.cpp index 1ae046b8a018..60d1221c160c 100644 --- a/source/Core/Connection.cpp +++ b/source/Core/Connection.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Connection.h" #if defined(_WIN32) @@ -19,6 +15,8 @@ #include "lldb/Host/ConnectionFileDescriptor.h" +#include <string.h> // for strstr + using namespace lldb_private; Connection::Connection() {} diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp deleted file mode 100644 index 21b4d3d76f1c..000000000000 --- a/source/Core/ConstString.cpp +++ /dev/null @@ -1,336 +0,0 @@ -//===-- ConstString.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/ConstString.h" - -// C Includes -// C++ Includes -#include <array> -#include <mutex> - -// Other libraries and framework includes -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/RWMutex.h" - -// Project includes -#include "lldb/Core/Stream.h" - -using namespace lldb_private; - -class Pool { -public: - typedef const char *StringPoolValueType; - typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> - StringPool; - typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType; - - static StringPoolEntryType & - GetStringMapEntryFromKeyData(const char *keyData) { - char *ptr = const_cast<char *>(keyData) - sizeof(StringPoolEntryType); - return *reinterpret_cast<StringPoolEntryType *>(ptr); - } - - size_t GetConstCStringLength(const char *ccstr) const { - if (ccstr != nullptr) { - const uint8_t h = hash(llvm::StringRef(ccstr)); - llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); - const StringPoolEntryType &entry = GetStringMapEntryFromKeyData(ccstr); - return entry.getKey().size(); - } - return 0; - } - - StringPoolValueType GetMangledCounterpart(const char *ccstr) const { - if (ccstr != nullptr) { - const uint8_t h = hash(llvm::StringRef(ccstr)); - llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); - return GetStringMapEntryFromKeyData(ccstr).getValue(); - } - return nullptr; - } - - bool SetMangledCounterparts(const char *key_ccstr, const char *value_ccstr) { - if (key_ccstr != nullptr && value_ccstr != nullptr) { - { - const uint8_t h = hash(llvm::StringRef(key_ccstr)); - llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); - GetStringMapEntryFromKeyData(key_ccstr).setValue(value_ccstr); - } - { - const uint8_t h = hash(llvm::StringRef(value_ccstr)); - llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); - GetStringMapEntryFromKeyData(value_ccstr).setValue(key_ccstr); - } - return true; - } - return false; - } - - const char *GetConstCString(const char *cstr) { - if (cstr != nullptr) - return GetConstCStringWithLength(cstr, strlen(cstr)); - return nullptr; - } - - const char *GetConstCStringWithLength(const char *cstr, size_t cstr_len) { - if (cstr != nullptr) - return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len)); - return nullptr; - } - - const char *GetConstCStringWithStringRef(const llvm::StringRef &string_ref) { - if (string_ref.data()) { - const uint8_t h = hash(string_ref); - - { - llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); - auto it = m_string_pools[h].m_string_map.find(string_ref); - if (it != m_string_pools[h].m_string_map.end()) - return it->getKeyData(); - } - - llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(string_ref, nullptr)) - .first; - return entry.getKeyData(); - } - return nullptr; - } - - const char * - GetConstCStringAndSetMangledCounterPart(const char *demangled_cstr, - const char *mangled_ccstr) { - if (demangled_cstr != nullptr) { - const char *demangled_ccstr = nullptr; - - { - llvm::StringRef string_ref(demangled_cstr); - const uint8_t h = hash(string_ref); - llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); - - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(string_ref, mangled_ccstr)) - .first; - - // Extract the const version of the demangled_cstr - demangled_ccstr = entry.getKeyData(); - } - - { - // Now assign the demangled const string as the counterpart of the - // mangled const string... - const uint8_t h = hash(llvm::StringRef(mangled_ccstr)); - llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); - GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr); - } - - // Return the constant demangled C string - return demangled_ccstr; - } - return nullptr; - } - - const char *GetConstTrimmedCStringWithLength(const char *cstr, - size_t cstr_len) { - if (cstr != nullptr) { - const size_t trimmed_len = std::min<size_t>(strlen(cstr), cstr_len); - return GetConstCStringWithLength(cstr, trimmed_len); - } - return nullptr; - } - - //------------------------------------------------------------------ - // Return the size in bytes that this object and any items in its - // collection of uniqued strings + data count values takes in - // memory. - //------------------------------------------------------------------ - size_t MemorySize() const { - size_t mem_size = sizeof(Pool); - for (const auto &pool : m_string_pools) { - llvm::sys::SmartScopedReader<false> rlock(pool.m_mutex); - for (const auto &entry : pool.m_string_map) - mem_size += sizeof(StringPoolEntryType) + entry.getKey().size(); - } - return mem_size; - } - -protected: - uint8_t hash(const llvm::StringRef &s) const { - uint32_t h = llvm::HashString(s); - return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff; - } - - struct PoolEntry { - mutable llvm::sys::SmartRWMutex<false> m_mutex; - StringPool m_string_map; - }; - - std::array<PoolEntry, 256> m_string_pools; -}; - -//---------------------------------------------------------------------- -// Frameworks and dylibs aren't supposed to have global C++ -// initializers so we hide the string pool in a static function so -// that it will get initialized on the first call to this static -// function. -// -// Note, for now we make the string pool a pointer to the pool, because -// we can't guarantee that some objects won't get destroyed after the -// global destructor chain is run, and trying to make sure no destructors -// touch ConstStrings is difficult. So we leak the pool instead. -//---------------------------------------------------------------------- -static Pool &StringPool() { - static std::once_flag g_pool_initialization_flag; - static Pool *g_string_pool = nullptr; - - std::call_once(g_pool_initialization_flag, - []() { g_string_pool = new Pool(); }); - - return *g_string_pool; -} - -ConstString::ConstString(const char *cstr) - : m_string(StringPool().GetConstCString(cstr)) {} - -ConstString::ConstString(const char *cstr, size_t cstr_len) - : m_string(StringPool().GetConstCStringWithLength(cstr, cstr_len)) {} - -ConstString::ConstString(const llvm::StringRef &s) - : m_string(StringPool().GetConstCStringWithLength(s.data(), s.size())) {} - -bool ConstString::operator<(const ConstString &rhs) const { - if (m_string == rhs.m_string) - return false; - - llvm::StringRef lhs_string_ref(m_string, - StringPool().GetConstCStringLength(m_string)); - llvm::StringRef rhs_string_ref( - rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string)); - - // If both have valid C strings, then return the comparison - if (lhs_string_ref.data() && rhs_string_ref.data()) - return lhs_string_ref < rhs_string_ref; - - // Else one of them was nullptr, so if LHS is nullptr then it is less than - return lhs_string_ref.data() == nullptr; -} - -Stream &lldb_private::operator<<(Stream &s, const ConstString &str) { - const char *cstr = str.GetCString(); - if (cstr != nullptr) - s << cstr; - - return s; -} - -size_t ConstString::GetLength() const { - return StringPool().GetConstCStringLength(m_string); -} - -bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs, - const bool case_sensitive) { - if (lhs.m_string == rhs.m_string) - return true; - - // Since the pointers weren't equal, and identical ConstStrings always have - // identical pointers, - // the result must be false for case sensitive equality test. - if (case_sensitive) - return false; - - // perform case insensitive equality test - llvm::StringRef lhs_string_ref( - lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string)); - llvm::StringRef rhs_string_ref( - rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string)); - return lhs_string_ref.equals_lower(rhs_string_ref); -} - -int ConstString::Compare(const ConstString &lhs, const ConstString &rhs, - const bool case_sensitive) { - // If the iterators are the same, this is the same string - const char *lhs_cstr = lhs.m_string; - const char *rhs_cstr = rhs.m_string; - if (lhs_cstr == rhs_cstr) - return 0; - if (lhs_cstr && rhs_cstr) { - llvm::StringRef lhs_string_ref( - lhs_cstr, StringPool().GetConstCStringLength(lhs_cstr)); - llvm::StringRef rhs_string_ref( - rhs_cstr, StringPool().GetConstCStringLength(rhs_cstr)); - - if (case_sensitive) { - return lhs_string_ref.compare(rhs_string_ref); - } else { - return lhs_string_ref.compare_lower(rhs_string_ref); - } - } - - if (lhs_cstr) - return +1; // LHS isn't nullptr but RHS is - else - return -1; // LHS is nullptr but RHS isn't -} - -void ConstString::Dump(Stream *s, const char *fail_value) const { - if (s != nullptr) { - const char *cstr = AsCString(fail_value); - if (cstr != nullptr) - s->PutCString(cstr); - } -} - -void ConstString::DumpDebug(Stream *s) const { - const char *cstr = GetCString(); - size_t cstr_len = GetLength(); - // Only print the parens if we have a non-nullptr string - const char *parens = cstr ? "\"" : ""; - s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64, - static_cast<int>(sizeof(void *) * 2), - static_cast<const void *>(this), parens, cstr, parens, - static_cast<uint64_t>(cstr_len)); -} - -void ConstString::SetCString(const char *cstr) { - m_string = StringPool().GetConstCString(cstr); -} - -void ConstString::SetString(const llvm::StringRef &s) { - m_string = StringPool().GetConstCStringWithLength(s.data(), s.size()); -} - -void ConstString::SetCStringWithMangledCounterpart(const char *demangled, - const ConstString &mangled) { - m_string = StringPool().GetConstCStringAndSetMangledCounterPart( - demangled, mangled.m_string); -} - -bool ConstString::GetMangledCounterpart(ConstString &counterpart) const { - counterpart.m_string = StringPool().GetMangledCounterpart(m_string); - return (bool)counterpart; -} - -void ConstString::SetCStringWithLength(const char *cstr, size_t cstr_len) { - m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len); -} - -void ConstString::SetTrimmedCStringWithLength(const char *cstr, - size_t cstr_len) { - m_string = StringPool().GetConstTrimmedCStringWithLength(cstr, cstr_len); -} - -size_t ConstString::StaticMemorySize() { - // Get the size of the static string pool - return StringPool().MemorySize(); -} diff --git a/source/Core/DataBufferHeap.cpp b/source/Core/DataBufferHeap.cpp deleted file mode 100644 index cdd37bfdf0fc..000000000000 --- a/source/Core/DataBufferHeap.cpp +++ /dev/null @@ -1,94 +0,0 @@ -//===-- DataBufferHeap.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/DataBufferHeap.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Default constructor -//---------------------------------------------------------------------- -DataBufferHeap::DataBufferHeap() : m_data() {} - -//---------------------------------------------------------------------- -// Initialize this class with "n" characters and fill the buffer -// with "ch". -//---------------------------------------------------------------------- -DataBufferHeap::DataBufferHeap(lldb::offset_t n, uint8_t ch) : m_data() { - if (n < m_data.max_size()) - m_data.assign(n, ch); -} - -//---------------------------------------------------------------------- -// Initialize this class with a copy of the "n" bytes from the "bytes" -// buffer. -//---------------------------------------------------------------------- -DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len) - : m_data() { - CopyData(src, src_len); -} - -//---------------------------------------------------------------------- -// Virtual destructor since this class inherits from a pure virtual -// base class. -//---------------------------------------------------------------------- -DataBufferHeap::~DataBufferHeap() = default; - -//---------------------------------------------------------------------- -// Return a pointer to the bytes owned by this object, or nullptr if -// the object contains no bytes. -//---------------------------------------------------------------------- -uint8_t *DataBufferHeap::GetBytes() { - return (m_data.empty() ? nullptr : m_data.data()); -} - -//---------------------------------------------------------------------- -// Return a const pointer to the bytes owned by this object, or nullptr -// if the object contains no bytes. -//---------------------------------------------------------------------- -const uint8_t *DataBufferHeap::GetBytes() const { - return (m_data.empty() ? nullptr : m_data.data()); -} - -//---------------------------------------------------------------------- -// Return the number of bytes this object currently contains. -//---------------------------------------------------------------------- -uint64_t DataBufferHeap::GetByteSize() const { return m_data.size(); } - -//---------------------------------------------------------------------- -// Sets the number of bytes that this object should be able to -// contain. This can be used prior to copying data into the buffer. -//---------------------------------------------------------------------- -uint64_t DataBufferHeap::SetByteSize(uint64_t new_size) { - m_data.resize(new_size); - return m_data.size(); -} - -void DataBufferHeap::CopyData(const void *src, uint64_t src_len) { - const uint8_t *src_u8 = (const uint8_t *)src; - if (src && src_len > 0) - m_data.assign(src_u8, src_u8 + src_len); - else - m_data.clear(); -} - -void DataBufferHeap::AppendData(const void *src, uint64_t src_len) { - m_data.insert(m_data.end(), (const uint8_t *)src, - (const uint8_t *)src + src_len); -} - -void DataBufferHeap::Clear() { - buffer_t empty; - m_data.swap(empty); -} diff --git a/source/Core/DataBufferMemoryMap.cpp b/source/Core/DataBufferMemoryMap.cpp deleted file mode 100644 index 70e8a394f69e..000000000000 --- a/source/Core/DataBufferMemoryMap.cpp +++ /dev/null @@ -1,307 +0,0 @@ -//===-- DataBufferMemoryMap.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 -#include <fcntl.h> -#include <sys/stat.h> -#ifdef _WIN32 -#include "lldb/Host/windows/windows.h" -#else -#include <sys/mman.h> - -#define MAP_EXTRA_HOST_READ_FLAGS 0 - -#if defined(__APPLE__) -//---------------------------------------------------------------------- -// Newer versions of MacOSX have a flag that will allow us to read from -// binaries whose code signature is invalid without crashing by using -// the MAP_RESILIENT_CODESIGN flag. Also if a file from removable media -// is mapped we can avoid crashing and return zeroes to any pages we try -// to read if the media becomes unavailable by using the -// MAP_RESILIENT_MEDIA flag. -//---------------------------------------------------------------------- -#if defined(MAP_RESILIENT_CODESIGN) -#undef MAP_EXTRA_HOST_READ_FLAGS -#if defined(MAP_RESILIENT_MEDIA) -#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA -#else -#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN -#endif -#endif // #if defined(MAP_RESILIENT_CODESIGN) -#endif // #if defined (__APPLE__) - -#endif // #else #ifdef _WIN32 -// C++ Includes -#include <cerrno> -#include <climits> - -// Other libraries and framework includes -#include "llvm/Support/MathExtras.h" - -// Project includes -#include "lldb/Core/DataBufferMemoryMap.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Host/File.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/HostInfo.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Default Constructor -//---------------------------------------------------------------------- -DataBufferMemoryMap::DataBufferMemoryMap() - : m_mmap_addr(nullptr), m_mmap_size(0), m_data(nullptr), m_size(0) {} - -//---------------------------------------------------------------------- -// Virtual destructor since this class inherits from a pure virtual -// base class. -//---------------------------------------------------------------------- -DataBufferMemoryMap::~DataBufferMemoryMap() { Clear(); } - -//---------------------------------------------------------------------- -// Return a pointer to the bytes owned by this object, or nullptr if -// the object contains no bytes. -//---------------------------------------------------------------------- -uint8_t *DataBufferMemoryMap::GetBytes() { return m_data; } - -//---------------------------------------------------------------------- -// Return a const pointer to the bytes owned by this object, or nullptr -// if the object contains no bytes. -//---------------------------------------------------------------------- -const uint8_t *DataBufferMemoryMap::GetBytes() const { return m_data; } - -//---------------------------------------------------------------------- -// Return the number of bytes this object currently contains. -//---------------------------------------------------------------------- -uint64_t DataBufferMemoryMap::GetByteSize() const { return m_size; } - -//---------------------------------------------------------------------- -// Reverts this object to an empty state by unmapping any memory -// that is currently owned. -//---------------------------------------------------------------------- -void DataBufferMemoryMap::Clear() { - if (m_mmap_addr != nullptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP)); - if (log) - log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size " - "= %" PRIu64 "", - (void *)m_mmap_addr, (uint64_t)m_mmap_size); -#ifdef _WIN32 - UnmapViewOfFile(m_mmap_addr); -#else - ::munmap((void *)m_mmap_addr, m_mmap_size); -#endif - m_mmap_addr = nullptr; - m_mmap_size = 0; - m_data = nullptr; - m_size = 0; - } -} - -//---------------------------------------------------------------------- -// Memory map "length" bytes from "file" starting "offset" -// bytes into the file. If "length" is set to SIZE_MAX, then -// map as many bytes as possible. -// -// Returns the number of bytes mapped starting from the requested -// offset. -//---------------------------------------------------------------------- -size_t DataBufferMemoryMap::MemoryMapFromFileSpec(const FileSpec *filespec, - lldb::offset_t offset, - size_t length, - bool writeable) { - if (filespec != nullptr) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP)); - if (log) { - log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", " - "offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i", - filespec->GetPath().c_str(), offset, (uint64_t)length, - writeable); - } - char path[PATH_MAX]; - if (filespec->GetPath(path, sizeof(path))) { - uint32_t options = File::eOpenOptionRead; - if (writeable) - options |= File::eOpenOptionWrite; - - File file; - Error error(file.Open(path, options)); - if (error.Success()) { - const bool fd_is_file = true; - return MemoryMapFromFileDescriptor(file.GetDescriptor(), offset, length, - writeable, fd_is_file); - } - } - } - // We should only get here if there was an error - Clear(); - return 0; -} - -#ifdef _WIN32 -static size_t win32memmapalignment = 0; -void LoadWin32MemMapAlignment() { - SYSTEM_INFO data; - GetSystemInfo(&data); - win32memmapalignment = data.dwAllocationGranularity; -} -#endif - -//---------------------------------------------------------------------- -// The file descriptor FD is assumed to already be opened as read only -// and the STAT structure is assumed to a valid pointer and already -// containing valid data from a call to stat(). -// -// Memory map FILE_LENGTH bytes in FILE starting FILE_OFFSET bytes into -// the file. If FILE_LENGTH is set to SIZE_MAX, then map as many bytes -// as possible. -// -// RETURNS -// Number of bytes mapped starting from the requested offset. -//---------------------------------------------------------------------- -size_t DataBufferMemoryMap::MemoryMapFromFileDescriptor(int fd, - lldb::offset_t offset, - size_t length, - bool writeable, - bool fd_is_file) { - Clear(); - if (fd >= 0) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP | - LIBLLDB_LOG_VERBOSE)); - if (log) { - log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, " - "offset=0x%" PRIx64 ", length=0x%" PRIx64 - ", writeable=%i, fd_is_file=%i)", - fd, offset, (uint64_t)length, writeable, fd_is_file); - } -#ifdef _WIN32 - HANDLE handle = (HANDLE)_get_osfhandle(fd); - DWORD file_size_low, file_size_high; - file_size_low = GetFileSize(handle, &file_size_high); - const lldb::offset_t file_size = - llvm::Make_64(file_size_high, file_size_low); - const lldb::offset_t max_bytes_available = file_size - offset; - const size_t max_bytes_mappable = - (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available); - if (length == SIZE_MAX || length > max_bytes_mappable) { - // Cap the length if too much data was requested - length = max_bytes_mappable; - } - - if (length > 0) { - HANDLE fileMapping = CreateFileMapping( - handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, - file_size_high, file_size_low, nullptr); - if (fileMapping != nullptr) { - if (win32memmapalignment == 0) - LoadWin32MemMapAlignment(); - lldb::offset_t realoffset = offset; - lldb::offset_t delta = 0; - if (realoffset % win32memmapalignment != 0) { - realoffset = realoffset / win32memmapalignment * win32memmapalignment; - delta = offset - realoffset; - } - - LPVOID data = MapViewOfFile(fileMapping, - writeable ? FILE_MAP_WRITE : FILE_MAP_READ, - 0, realoffset, length + delta); - m_mmap_addr = (uint8_t *)data; - if (!data) { - Error error; - error.SetErrorToErrno(); - } else { - m_data = m_mmap_addr + delta; - m_size = length; - } - CloseHandle(fileMapping); - } - } -#else - struct stat stat; - if (::fstat(fd, &stat) == 0) { - if (S_ISREG(stat.st_mode) && - (stat.st_size > static_cast<off_t>(offset))) { - const size_t max_bytes_available = stat.st_size - offset; - if (length == SIZE_MAX) { - length = max_bytes_available; - } else if (length > max_bytes_available) { - // Cap the length if too much data was requested - length = max_bytes_available; - } - - if (length > 0) { - int prot = PROT_READ; - int flags = MAP_PRIVATE; - if (writeable) - prot |= PROT_WRITE; - else - flags |= MAP_EXTRA_HOST_READ_FLAGS; - - if (fd_is_file) - flags |= MAP_FILE; - - m_mmap_addr = - (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset); - Error error; - - if (m_mmap_addr == (void *)-1) { - error.SetErrorToErrno(); - if (error.GetError() == EINVAL) { - // We may still have a shot at memory mapping if we align things - // correctly - size_t page_offset = offset % HostInfo::GetPageSize(); - if (page_offset != 0) { - m_mmap_addr = - (uint8_t *)::mmap(nullptr, length + page_offset, prot, - flags, fd, offset - page_offset); - if (m_mmap_addr == (void *)-1) { - // Failed to map file - m_mmap_addr = nullptr; - } else if (m_mmap_addr != nullptr) { - // We recovered and were able to memory map - // after we aligned things to page boundaries - - // Save the actual mmap'ed size - m_mmap_size = length + page_offset; - // Our data is at an offset into the mapped data - m_data = m_mmap_addr + page_offset; - // Our pretend size is the size that was requested - m_size = length; - } - } - } - if (error.GetError() == ENOMEM) { - error.SetErrorStringWithFormat("could not allocate %" PRId64 - " bytes of memory to mmap in file", - (uint64_t)length); - } - } else { - // We were able to map the requested data in one chunk - // where our mmap and actual data are the same. - m_mmap_size = length; - m_data = m_mmap_addr; - m_size = length; - } - - if (log) { - log->Printf( - "DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = " - "%p, m_mmap_size = %" PRIu64 ", error = %s", - (void *)m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString()); - } - } - } - } -#endif - } - return GetByteSize(); -} diff --git a/source/Core/DataEncoder.cpp b/source/Core/DataEncoder.cpp deleted file mode 100644 index 334043651576..000000000000 --- a/source/Core/DataEncoder.cpp +++ /dev/null @@ -1,286 +0,0 @@ -//===-- DataEncoder.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/DataEncoder.h" - -// C Includes -// C++ Includes -#include <cassert> -#include <cstddef> - -// Other libraries and framework includes -#include "llvm/Support/MathExtras.h" - -// Project includes -#include "lldb/Core/DataBuffer.h" -#include "lldb/Host/Endian.h" - -using namespace lldb; -using namespace lldb_private; - -static inline void WriteInt16(unsigned char *ptr, unsigned offset, - uint16_t value) { - *(uint16_t *)(ptr + offset) = value; -} - -static inline void WriteInt32(unsigned char *ptr, unsigned offset, - uint32_t value) { - *(uint32_t *)(ptr + offset) = value; -} - -static inline void WriteInt64(unsigned char *ptr, unsigned offset, - uint64_t value) { - *(uint64_t *)(ptr + offset) = value; -} - -static inline void WriteSwappedInt16(unsigned char *ptr, unsigned offset, - uint16_t value) { - *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value); -} - -static inline void WriteSwappedInt32(unsigned char *ptr, unsigned offset, - uint32_t value) { - *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value); -} - -static inline void WriteSwappedInt64(unsigned char *ptr, unsigned offset, - uint64_t value) { - *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value); -} - -//---------------------------------------------------------------------- -// Default constructor. -//---------------------------------------------------------------------- -DataEncoder::DataEncoder() - : m_start(nullptr), m_end(nullptr), - m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), - m_data_sp() {} - -//---------------------------------------------------------------------- -// This constructor allows us to use data that is owned by someone else. -// The data must stay around as long as this object is valid. -//---------------------------------------------------------------------- -DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian, - uint8_t addr_size) - : m_start((uint8_t *)data), m_end((uint8_t *)data + length), - m_byte_order(endian), m_addr_size(addr_size), m_data_sp() {} - -//---------------------------------------------------------------------- -// Make a shared pointer reference to the shared data in "data_sp" and -// set the endian swapping setting to "swap", and the address size to -// "addr_size". The shared data reference will ensure the data lives -// as long as any DataEncoder objects exist that have a reference to -// this data. -//---------------------------------------------------------------------- -DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian, - uint8_t addr_size) - : m_start(nullptr), m_end(nullptr), m_byte_order(endian), - m_addr_size(addr_size), m_data_sp() { - SetData(data_sp); -} - -DataEncoder::~DataEncoder() = default; - -//------------------------------------------------------------------ -// Clears the object contents back to a default invalid state, and -// release any references to shared data that this object may -// contain. -//------------------------------------------------------------------ -void DataEncoder::Clear() { - m_start = nullptr; - m_end = nullptr; - m_byte_order = endian::InlHostByteOrder(); - m_addr_size = sizeof(void *); - m_data_sp.reset(); -} - -//------------------------------------------------------------------ -// If this object contains shared data, this function returns the -// offset into that shared data. Else zero is returned. -//------------------------------------------------------------------ -size_t DataEncoder::GetSharedDataOffset() const { - if (m_start != nullptr) { - const DataBuffer *data = m_data_sp.get(); - if (data != nullptr) { - const uint8_t *data_bytes = data->GetBytes(); - if (data_bytes != nullptr) { - assert(m_start >= data_bytes); - return m_start - data_bytes; - } - } - } - return 0; -} - -//---------------------------------------------------------------------- -// 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 -// long. The data is externally owned must be around at least as -// long as this object points to the data. No copy of the data is -// made, this object just refers to this data and can extract from -// it. If this object refers to any shared data upon entry, the -// reference to that data will be released. Is SWAP is set to true, -// any data extracted will be endian swapped. -//---------------------------------------------------------------------- -uint32_t DataEncoder::SetData(void *bytes, uint32_t length, ByteOrder endian) { - m_byte_order = endian; - m_data_sp.reset(); - if (bytes == nullptr || length == 0) { - m_start = nullptr; - m_end = nullptr; - } else { - m_start = (uint8_t *)bytes; - m_end = m_start + length; - } - return GetByteSize(); -} - -//---------------------------------------------------------------------- -// Assign the data for this object to be a subrange of the shared -// data in "data_sp" starting "data_offset" bytes into "data_sp" -// and ending "data_length" bytes later. If "data_offset" is not -// a valid offset into "data_sp", then this object will contain no -// bytes. If "data_offset" is within "data_sp" yet "data_length" is -// too large, the length will be capped at the number of bytes -// remaining in "data_sp". A ref counted pointer to the data in -// "data_sp" will be made in this object IF the number of bytes this -// object refers to in greater than zero (if at least one byte was -// available starting at "data_offset") to ensure the data stays -// around as long as it is needed. The address size and endian swap -// settings will remain unchanged from their current settings. -//---------------------------------------------------------------------- -uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset, - uint32_t data_length) { - m_start = m_end = nullptr; - - if (data_length > 0) { - m_data_sp = data_sp; - if (data_sp) { - const size_t data_size = data_sp->GetByteSize(); - if (data_offset < data_size) { - m_start = data_sp->GetBytes() + data_offset; - const size_t bytes_left = data_size - data_offset; - // Cap the length of we asked for too many - if (data_length <= bytes_left) - m_end = m_start + data_length; // We got all the bytes we wanted - else - m_end = m_start + bytes_left; // Not all the bytes requested were - // available in the shared data - } - } - } - - uint32_t new_size = GetByteSize(); - - // Don't hold a shared pointer to the data buffer if we don't share - // any valid bytes in the shared buffer. - if (new_size == 0) - m_data_sp.reset(); - - return new_size; -} - -//---------------------------------------------------------------------- -// Extract a single unsigned char from the binary data and update -// the offset pointed to by "offset_ptr". -// -// RETURNS the byte that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) { - if (ValidOffset(offset)) { - m_start[offset] = value; - return offset + 1; - } - return UINT32_MAX; -} - -uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) { - if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != endian::InlHostByteOrder()) - WriteSwappedInt16(m_start, offset, value); - else - WriteInt16(m_start, offset, value); - - return offset + sizeof(value); - } - return UINT32_MAX; -} - -uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) { - if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != endian::InlHostByteOrder()) - WriteSwappedInt32(m_start, offset, value); - else - WriteInt32(m_start, offset, value); - - return offset + sizeof(value); - } - return UINT32_MAX; -} - -uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) { - if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != endian::InlHostByteOrder()) - WriteSwappedInt64(m_start, offset, value); - else - WriteInt64(m_start, offset, value); - - return offset + sizeof(value); - } - return UINT32_MAX; -} - -//---------------------------------------------------------------------- -// Extract a single integer value from the data and update the offset -// pointed to by "offset_ptr". The size of the extracted integer -// is specified by the "byte_size" argument. "byte_size" should have -// a value >= 1 and <= 8 since the return value is only 64 bits -// wide. Any "byte_size" values less than 1 or greater than 8 will -// result in nothing being extracted, and zero being returned. -// -// RETURNS the integer value that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint32_t DataEncoder::PutMaxU64(uint32_t offset, uint32_t byte_size, - uint64_t value) { - switch (byte_size) { - case 1: - return PutU8(offset, value); - case 2: - return PutU16(offset, value); - case 4: - return PutU32(offset, value); - case 8: - return PutU64(offset, value); - default: - llvm_unreachable("GetMax64 unhandled case!"); - } - return UINT32_MAX; -} - -uint32_t DataEncoder::PutData(uint32_t offset, const void *src, - uint32_t src_len) { - if (src == nullptr || src_len == 0) - return offset; - - if (ValidOffsetForDataOfSize(offset, src_len)) { - memcpy(m_start + offset, src, src_len); - return offset + src_len; - } - return UINT32_MAX; -} - -uint32_t DataEncoder::PutAddress(uint32_t offset, lldb::addr_t addr) { - return PutMaxU64(offset, GetAddressByteSize(), addr); -} - -uint32_t DataEncoder::PutCString(uint32_t offset, const char *cstr) { - if (cstr != nullptr) - return PutData(offset, cstr, strlen(cstr) + 1); - return UINT32_MAX; -} diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp deleted file mode 100644 index fbc6e80bea07..000000000000 --- a/source/Core/DataExtractor.cpp +++ /dev/null @@ -1,2143 +0,0 @@ -//===-- DataExtractor.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 -#include <bitset> -#include <cassert> -#include <cmath> -#include <cstddef> -#include <sstream> -#include <string> - -// Other libraries and framework includes -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/APInt.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/MD5.h" -#include "llvm/Support/MathExtras.h" - -#include "clang/AST/ASTContext.h" - -// Project includes -#include "lldb/Core/DataBuffer.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Disassembler.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/UUID.h" -#include "lldb/Core/dwarf.h" -#include "lldb/Host/Endian.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ExecutionContextScope.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/Target.h" - -using namespace lldb; -using namespace lldb_private; - -static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) { - uint16_t value; - memcpy(&value, ptr + offset, 2); - return value; -} - -static inline uint32_t ReadInt32(const unsigned char *ptr, - offset_t offset = 0) { - uint32_t value; - memcpy(&value, ptr + offset, 4); - return value; -} - -static inline uint64_t ReadInt64(const unsigned char *ptr, - offset_t offset = 0) { - uint64_t value; - memcpy(&value, ptr + offset, 8); - return value; -} - -static inline uint16_t ReadInt16(const void *ptr) { - uint16_t value; - memcpy(&value, ptr, 2); - return value; -} - -static inline uint16_t ReadSwapInt16(const unsigned char *ptr, - offset_t offset) { - uint16_t value; - memcpy(&value, ptr + offset, 2); - return llvm::ByteSwap_16(value); -} - -static inline uint32_t ReadSwapInt32(const unsigned char *ptr, - offset_t offset) { - uint32_t value; - memcpy(&value, ptr + offset, 4); - return llvm::ByteSwap_32(value); -} - -static inline uint64_t ReadSwapInt64(const unsigned char *ptr, - offset_t offset) { - uint64_t value; - memcpy(&value, ptr + offset, 8); - return llvm::ByteSwap_64(value); -} - -static inline uint16_t ReadSwapInt16(const void *ptr) { - uint16_t value; - memcpy(&value, ptr, 2); - return llvm::ByteSwap_16(value); -} - -static inline uint32_t ReadSwapInt32(const void *ptr) { - uint32_t value; - memcpy(&value, ptr, 4); - return llvm::ByteSwap_32(value); -} - -static inline uint64_t ReadSwapInt64(const void *ptr) { - uint64_t value; - memcpy(&value, ptr, 8); - return llvm::ByteSwap_64(value); -} - -#define NON_PRINTABLE_CHAR '.' - -DataExtractor::DataExtractor() - : m_start(nullptr), m_end(nullptr), - m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)), - m_data_sp(), m_target_byte_size(1) {} - -//---------------------------------------------------------------------- -// This constructor allows us to use data that is owned by someone else. -// The data must stay around as long as this object is valid. -//---------------------------------------------------------------------- -DataExtractor::DataExtractor(const void *data, offset_t length, - ByteOrder endian, uint32_t addr_size, - uint32_t target_byte_size /*=1*/) - : m_start(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data))), - m_end(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data)) + - length), - m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), - m_target_byte_size(target_byte_size) { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(addr_size == 4 || addr_size == 8); -#endif -} - -//---------------------------------------------------------------------- -// Make a shared pointer reference to the shared data in "data_sp" and -// set the endian swapping setting to "swap", and the address size to -// "addr_size". The shared data reference will ensure the data lives -// as long as any DataExtractor objects exist that have a reference to -// this data. -//---------------------------------------------------------------------- -DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, - uint32_t addr_size, - uint32_t target_byte_size /*=1*/) - : m_start(nullptr), m_end(nullptr), m_byte_order(endian), - m_addr_size(addr_size), m_data_sp(), - m_target_byte_size(target_byte_size) { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(addr_size == 4 || addr_size == 8); -#endif - SetData(data_sp); -} - -//---------------------------------------------------------------------- -// Initialize this object with a subset of the data bytes in "data". -// If "data" contains shared data, then a reference to this shared -// data will added and the shared data will stay around as long -// as any object contains a reference to that data. The endian -// swap and address size settings are copied from "data". -//---------------------------------------------------------------------- -DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, - offset_t length, uint32_t target_byte_size /*=1*/) - : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order), - m_addr_size(data.m_addr_size), m_data_sp(), - m_target_byte_size(target_byte_size) { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif - if (data.ValidOffset(offset)) { - offset_t bytes_available = data.GetByteSize() - offset; - if (length > bytes_available) - length = bytes_available; - SetData(data, offset, length); - } -} - -DataExtractor::DataExtractor(const DataExtractor &rhs) - : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order), - m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp), - m_target_byte_size(rhs.m_target_byte_size) { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif -} - -//---------------------------------------------------------------------- -// Assignment operator -//---------------------------------------------------------------------- -const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) { - if (this != &rhs) { - m_start = rhs.m_start; - m_end = rhs.m_end; - m_byte_order = rhs.m_byte_order; - m_addr_size = rhs.m_addr_size; - m_data_sp = rhs.m_data_sp; - } - return *this; -} - -DataExtractor::~DataExtractor() = default; - -//------------------------------------------------------------------ -// Clears the object contents back to a default invalid state, and -// release any references to shared data that this object may -// contain. -//------------------------------------------------------------------ -void DataExtractor::Clear() { - m_start = nullptr; - m_end = nullptr; - m_byte_order = endian::InlHostByteOrder(); - m_addr_size = sizeof(void *); - m_data_sp.reset(); -} - -//------------------------------------------------------------------ -// If this object contains shared data, this function returns the -// offset into that shared data. Else zero is returned. -//------------------------------------------------------------------ -size_t DataExtractor::GetSharedDataOffset() const { - if (m_start != nullptr) { - const DataBuffer *data = m_data_sp.get(); - if (data != nullptr) { - const uint8_t *data_bytes = data->GetBytes(); - if (data_bytes != nullptr) { - assert(m_start >= data_bytes); - return m_start - data_bytes; - } - } - } - return 0; -} - -//---------------------------------------------------------------------- -// 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 -// long. The data is externally owned must be around at least as -// long as this object points to the data. No copy of the data is -// made, this object just refers to this data and can extract from -// it. If this object refers to any shared data upon entry, the -// reference to that data will be released. Is SWAP is set to true, -// any data extracted will be endian swapped. -//---------------------------------------------------------------------- -lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length, - ByteOrder endian) { - m_byte_order = endian; - m_data_sp.reset(); - if (bytes == nullptr || length == 0) { - m_start = nullptr; - m_end = nullptr; - } else { - m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes)); - m_end = m_start + length; - } - return GetByteSize(); -} - -//---------------------------------------------------------------------- -// Assign the data for this object to be a subrange in "data" -// starting "data_offset" bytes into "data" and ending "data_length" -// bytes later. If "data_offset" is not a valid offset into "data", -// then this object will contain no bytes. If "data_offset" is -// within "data" yet "data_length" is too large, the length will be -// capped at the number of bytes remaining in "data". If "data" -// contains a shared pointer to other data, then a ref counted -// pointer to that data will be made in this object. If "data" -// doesn't contain a shared pointer to data, then the bytes referred -// to in "data" will need to exist at least as long as this object -// refers to those bytes. The address size and endian swap settings -// are copied from the current values in "data". -//---------------------------------------------------------------------- -lldb::offset_t DataExtractor::SetData(const DataExtractor &data, - offset_t data_offset, - offset_t data_length) { - m_addr_size = data.m_addr_size; -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif - // If "data" contains shared pointer to data, then we can use that - if (data.m_data_sp) { - m_byte_order = data.m_byte_order; - return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset, - data_length); - } - - // We have a DataExtractor object that just has a pointer to bytes - if (data.ValidOffset(data_offset)) { - if (data_length > data.GetByteSize() - data_offset) - data_length = data.GetByteSize() - data_offset; - return SetData(data.GetDataStart() + data_offset, data_length, - data.GetByteOrder()); - } - return 0; -} - -//---------------------------------------------------------------------- -// Assign the data for this object to be a subrange of the shared -// data in "data_sp" starting "data_offset" bytes into "data_sp" -// and ending "data_length" bytes later. If "data_offset" is not -// a valid offset into "data_sp", then this object will contain no -// bytes. If "data_offset" is within "data_sp" yet "data_length" is -// too large, the length will be capped at the number of bytes -// remaining in "data_sp". A ref counted pointer to the data in -// "data_sp" will be made in this object IF the number of bytes this -// object refers to in greater than zero (if at least one byte was -// available starting at "data_offset") to ensure the data stays -// around as long as it is needed. The address size and endian swap -// settings will remain unchanged from their current settings. -//---------------------------------------------------------------------- -lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp, - offset_t data_offset, - offset_t data_length) { - m_start = m_end = nullptr; - - if (data_length > 0) { - m_data_sp = data_sp; - if (data_sp) { - const size_t data_size = data_sp->GetByteSize(); - if (data_offset < data_size) { - m_start = data_sp->GetBytes() + data_offset; - const size_t bytes_left = data_size - data_offset; - // Cap the length of we asked for too many - if (data_length <= bytes_left) - m_end = m_start + data_length; // We got all the bytes we wanted - else - m_end = m_start + bytes_left; // Not all the bytes requested were - // available in the shared data - } - } - } - - size_t new_size = GetByteSize(); - - // Don't hold a shared pointer to the data buffer if we don't share - // any valid bytes in the shared buffer. - if (new_size == 0) - m_data_sp.reset(); - - return new_size; -} - -//---------------------------------------------------------------------- -// Extract a single unsigned char from the binary data and update -// the offset pointed to by "offset_ptr". -// -// RETURNS the byte that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const { - const uint8_t *data = (const uint8_t *)GetData(offset_ptr, 1); - if (data) - return *data; - return 0; -} - -//---------------------------------------------------------------------- -// Extract "count" unsigned chars from the binary data and update the -// offset pointed to by "offset_ptr". The extracted data is copied into -// "dst". -// -// RETURNS the non-nullptr buffer pointer upon successful extraction of -// all the requested bytes, or nullptr when the data is not available in -// the buffer due to being out of bounds, or insufficient data. -//---------------------------------------------------------------------- -void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst, - uint32_t count) const { - const uint8_t *data = (const uint8_t *)GetData(offset_ptr, count); - if (data) { - // Copy the data into the buffer - memcpy(dst, data, count); - // Return a non-nullptr pointer to the converted data as an indicator of - // success - return dst; - } - return nullptr; -} - -//---------------------------------------------------------------------- -// Extract a single uint16_t from the data and update the offset -// pointed to by "offset_ptr". -// -// RETURNS the uint16_t that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint16_t DataExtractor::GetU16(offset_t *offset_ptr) const { - uint16_t val = 0; - const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val)); - if (data) { - if (m_byte_order != endian::InlHostByteOrder()) - val = ReadSwapInt16(data); - else - val = ReadInt16(data); - } - return val; -} - -uint16_t DataExtractor::GetU16_unchecked(offset_t *offset_ptr) const { - uint16_t val; - if (m_byte_order == endian::InlHostByteOrder()) - val = ReadInt16(m_start, *offset_ptr); - else - val = ReadSwapInt16(m_start, *offset_ptr); - *offset_ptr += sizeof(val); - return val; -} - -uint32_t DataExtractor::GetU32_unchecked(offset_t *offset_ptr) const { - uint32_t val; - if (m_byte_order == endian::InlHostByteOrder()) - val = ReadInt32(m_start, *offset_ptr); - else - val = ReadSwapInt32(m_start, *offset_ptr); - *offset_ptr += sizeof(val); - return val; -} - -uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const { - uint64_t val; - if (m_byte_order == endian::InlHostByteOrder()) - val = ReadInt64(m_start, *offset_ptr); - else - val = ReadSwapInt64(m_start, *offset_ptr); - *offset_ptr += sizeof(val); - return val; -} - -//---------------------------------------------------------------------- -// Extract "count" uint16_t values from the binary data and update -// the offset pointed to by "offset_ptr". The extracted data is -// copied into "dst". -// -// RETURNS the non-nullptr buffer pointer upon successful extraction of -// all the requested bytes, or nullptr when the data is not available -// in the buffer due to being out of bounds, or insufficient data. -//---------------------------------------------------------------------- -void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst, - uint32_t count) const { - const size_t src_size = sizeof(uint16_t) * count; - const uint16_t *src = (const uint16_t *)GetData(offset_ptr, src_size); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - uint16_t *dst_pos = (uint16_t *)void_dst; - uint16_t *dst_end = dst_pos + count; - const uint16_t *src_pos = src; - while (dst_pos < dst_end) { - *dst_pos = ReadSwapInt16(src_pos); - ++dst_pos; - ++src_pos; - } - } else { - memcpy(void_dst, src, src_size); - } - // Return a non-nullptr pointer to the converted data as an indicator of - // success - return void_dst; - } - return nullptr; -} - -//---------------------------------------------------------------------- -// Extract a single uint32_t from the data and update the offset -// pointed to by "offset_ptr". -// -// RETURNS the uint32_t that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const { - uint32_t val = 0; - const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val)); - if (data) { - if (m_byte_order != endian::InlHostByteOrder()) { - val = ReadSwapInt32(data); - } else { - memcpy(&val, data, 4); - } - } - return val; -} - -//---------------------------------------------------------------------- -// Extract "count" uint32_t values from the binary data and update -// the offset pointed to by "offset_ptr". The extracted data is -// copied into "dst". -// -// RETURNS the non-nullptr buffer pointer upon successful extraction of -// all the requested bytes, or nullptr when the data is not available -// in the buffer due to being out of bounds, or insufficient data. -//---------------------------------------------------------------------- -void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst, - uint32_t count) const { - const size_t src_size = sizeof(uint32_t) * count; - const uint32_t *src = (const uint32_t *)GetData(offset_ptr, src_size); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - uint32_t *dst_pos = (uint32_t *)void_dst; - uint32_t *dst_end = dst_pos + count; - const uint32_t *src_pos = src; - while (dst_pos < dst_end) { - *dst_pos = ReadSwapInt32(src_pos); - ++dst_pos; - ++src_pos; - } - } else { - memcpy(void_dst, src, src_size); - } - // Return a non-nullptr pointer to the converted data as an indicator of - // success - return void_dst; - } - return nullptr; -} - -//---------------------------------------------------------------------- -// Extract a single uint64_t from the data and update the offset -// pointed to by "offset_ptr". -// -// RETURNS the uint64_t that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const { - uint64_t val = 0; - const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val)); - if (data) { - if (m_byte_order != endian::InlHostByteOrder()) { - val = ReadSwapInt64(data); - } else { - memcpy(&val, data, 8); - } - } - return val; -} - -//---------------------------------------------------------------------- -// GetU64 -// -// Get multiple consecutive 64 bit values. Return true if the entire -// read succeeds and increment the offset pointed to by offset_ptr, else -// return false and leave the offset pointed to by offset_ptr unchanged. -//---------------------------------------------------------------------- -void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst, - uint32_t count) const { - const size_t src_size = sizeof(uint64_t) * count; - const uint64_t *src = (const uint64_t *)GetData(offset_ptr, src_size); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - uint64_t *dst_pos = (uint64_t *)void_dst; - uint64_t *dst_end = dst_pos + count; - const uint64_t *src_pos = src; - while (dst_pos < dst_end) { - *dst_pos = ReadSwapInt64(src_pos); - ++dst_pos; - ++src_pos; - } - } else { - memcpy(void_dst, src, src_size); - } - // Return a non-nullptr pointer to the converted data as an indicator of - // success - return void_dst; - } - return nullptr; -} - -//---------------------------------------------------------------------- -// Extract a single integer value from the data and update the offset -// pointed to by "offset_ptr". The size of the extracted integer -// is specified by the "byte_size" argument. "byte_size" should have -// a value between 1 and 4 since the return value is only 32 bits -// wide. Any "byte_size" values less than 1 or greater than 4 will -// result in nothing being extracted, and zero being returned. -// -// RETURNS the integer value that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr, - size_t byte_size) const { - switch (byte_size) { - case 1: - return GetU8(offset_ptr); - break; - case 2: - return GetU16(offset_ptr); - break; - case 4: - return GetU32(offset_ptr); - break; - default: - assert(false && "GetMaxU32 unhandled case!"); - break; - } - return 0; -} - -//---------------------------------------------------------------------- -// Extract a single integer value from the data and update the offset -// pointed to by "offset_ptr". The size of the extracted integer -// is specified by the "byte_size" argument. "byte_size" should have -// a value >= 1 and <= 8 since the return value is only 64 bits -// wide. Any "byte_size" values less than 1 or greater than 8 will -// result in nothing being extracted, and zero being returned. -// -// RETURNS the integer value that was extracted, or zero on failure. -//---------------------------------------------------------------------- -uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, size_t size) const { - switch (size) { - case 1: - return GetU8(offset_ptr); - break; - case 2: - return GetU16(offset_ptr); - break; - case 4: - return GetU32(offset_ptr); - break; - case 8: - return GetU64(offset_ptr); - break; - default: - assert(false && "GetMax64 unhandled case!"); - break; - } - return 0; -} - -uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr, - size_t size) const { - switch (size) { - case 1: - return GetU8_unchecked(offset_ptr); - break; - case 2: - return GetU16_unchecked(offset_ptr); - break; - case 4: - return GetU32_unchecked(offset_ptr); - break; - case 8: - return GetU64_unchecked(offset_ptr); - break; - default: - assert(false && "GetMax64 unhandled case!"); - break; - } - return 0; -} - -int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t size) const { - switch (size) { - case 1: - return (int8_t)GetU8(offset_ptr); - break; - case 2: - return (int16_t)GetU16(offset_ptr); - break; - case 4: - return (int32_t)GetU32(offset_ptr); - break; - case 8: - return (int64_t)GetU64(offset_ptr); - break; - default: - assert(false && "GetMax64 unhandled case!"); - break; - } - return 0; -} - -uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset) const { - uint64_t uval64 = GetMaxU64(offset_ptr, size); - if (bitfield_bit_size > 0) { - int32_t lsbcount = bitfield_bit_offset; - if (m_byte_order == eByteOrderBig) - lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; - if (lsbcount > 0) - uval64 >>= lsbcount; - uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1); - if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64) - return uval64; - uval64 &= bitfield_mask; - } - return uval64; -} - -int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset) const { - int64_t sval64 = GetMaxS64(offset_ptr, size); - if (bitfield_bit_size > 0) { - int32_t lsbcount = bitfield_bit_offset; - if (m_byte_order == eByteOrderBig) - lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; - if (lsbcount > 0) - sval64 >>= lsbcount; - uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1; - sval64 &= bitfield_mask; - // sign extend if needed - if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1))) - sval64 |= ~bitfield_mask; - } - return sval64; -} - -float DataExtractor::GetFloat(offset_t *offset_ptr) const { - typedef float float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = (const float_type *)GetData(offset_ptr, src_size); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = (const uint8_t *)src; - uint8_t *dst_data = (uint8_t *)&val; - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; -} - -double DataExtractor::GetDouble(offset_t *offset_ptr) const { - typedef double float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = (const float_type *)GetData(offset_ptr, src_size); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = (const uint8_t *)src; - uint8_t *dst_data = (uint8_t *)&val; - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; -} - -long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { - long double val = 0.0; -#if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) - *offset_ptr += CopyByteOrderedData(*offset_ptr, 10, &val, sizeof(val), - endian::InlHostByteOrder()); -#else - *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val, - sizeof(val), endian::InlHostByteOrder()); -#endif - return val; -} - -//------------------------------------------------------------------ -// Extract a single address from the data and update the offset -// pointed to by "offset_ptr". The size of the extracted address -// comes from the "this->m_addr_size" member variable and should be -// set correctly prior to extracting any address values. -// -// RETURNS the address that was extracted, or zero on failure. -//------------------------------------------------------------------ -uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif - return GetMaxU64(offset_ptr, m_addr_size); -} - -uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif - return GetMaxU64_unchecked(offset_ptr, m_addr_size); -} - -//------------------------------------------------------------------ -// Extract a single pointer from the data and update the offset -// pointed to by "offset_ptr". The size of the extracted pointer -// comes from the "this->m_addr_size" member variable and should be -// set correctly prior to extracting any pointer values. -// -// RETURNS the pointer that was extracted, or zero on failure. -//------------------------------------------------------------------ -uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const { -#ifdef LLDB_CONFIGURATION_DEBUG - assert(m_addr_size == 4 || m_addr_size == 8); -#endif - return GetMaxU64(offset_ptr, m_addr_size); -} - -//---------------------------------------------------------------------- -// GetDwarfEHPtr -// -// Used for calls when the value type is specified by a DWARF EH Frame -// pointer encoding. -//---------------------------------------------------------------------- - -uint64_t DataExtractor::GetGNUEHPointer( - offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, - lldb::addr_t text_addr, - lldb::addr_t data_addr) //, BSDRelocs *data_relocs) const -{ - if (eh_ptr_enc == DW_EH_PE_omit) - return ULLONG_MAX; // Value isn't in the buffer... - - uint64_t baseAddress = 0; - uint64_t addressValue = 0; - const uint32_t addr_size = GetAddressByteSize(); -#ifdef LLDB_CONFIGURATION_DEBUG - assert(addr_size == 4 || addr_size == 8); -#endif - - bool signExtendValue = false; - // Decode the base part or adjust our offset - switch (eh_ptr_enc & 0x70) { - case DW_EH_PE_pcrel: - signExtendValue = true; - baseAddress = *offset_ptr; - if (pc_rel_addr != LLDB_INVALID_ADDRESS) - baseAddress += pc_rel_addr; - // else - // Log::GlobalWarning ("PC relative pointer encoding found with - // invalid pc relative address."); - break; - - case DW_EH_PE_textrel: - signExtendValue = true; - if (text_addr != LLDB_INVALID_ADDRESS) - baseAddress = text_addr; - // else - // Log::GlobalWarning ("text relative pointer encoding being - // decoded with invalid text section address, setting base address - // to zero."); - break; - - case DW_EH_PE_datarel: - signExtendValue = true; - if (data_addr != LLDB_INVALID_ADDRESS) - baseAddress = data_addr; - // else - // Log::GlobalWarning ("data relative pointer encoding being - // decoded with invalid data section address, setting base address - // to zero."); - break; - - case DW_EH_PE_funcrel: - signExtendValue = true; - break; - - case DW_EH_PE_aligned: { - // SetPointerSize should be called prior to extracting these so the - // pointer size is cached - assert(addr_size != 0); - if (addr_size) { - // Align to a address size boundary first - uint32_t alignOffset = *offset_ptr % addr_size; - if (alignOffset) - offset_ptr += addr_size - alignOffset; - } - } break; - - default: - break; - } - - // Decode the value part - switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) { - case DW_EH_PE_absptr: { - addressValue = GetAddress(offset_ptr); - // if (data_relocs) - // addressValue = data_relocs->Relocate(*offset_ptr - - // addr_size, *this, addressValue); - } break; - case DW_EH_PE_uleb128: - addressValue = GetULEB128(offset_ptr); - break; - case DW_EH_PE_udata2: - addressValue = GetU16(offset_ptr); - break; - case DW_EH_PE_udata4: - addressValue = GetU32(offset_ptr); - break; - case DW_EH_PE_udata8: - addressValue = GetU64(offset_ptr); - break; - case DW_EH_PE_sleb128: - addressValue = GetSLEB128(offset_ptr); - break; - case DW_EH_PE_sdata2: - addressValue = (int16_t)GetU16(offset_ptr); - break; - case DW_EH_PE_sdata4: - addressValue = (int32_t)GetU32(offset_ptr); - break; - case DW_EH_PE_sdata8: - addressValue = (int64_t)GetU64(offset_ptr); - break; - default: - // Unhandled encoding type - assert(eh_ptr_enc); - break; - } - - // Since we promote everything to 64 bit, we may need to sign extend - if (signExtendValue && addr_size < sizeof(baseAddress)) { - uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull); - if (sign_bit & addressValue) { - uint64_t mask = ~sign_bit + 1; - addressValue |= mask; - } - } - return baseAddress + addressValue; -} - -size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length, - ByteOrder dst_byte_order, void *dst) const { - const uint8_t *src = PeekData(offset, length); - if (src) { - if (dst_byte_order != GetByteOrder()) { - // Validate that only a word- or register-sized dst is byte swapped - assert(length == 1 || length == 2 || length == 4 || length == 8 || - length == 10 || length == 16 || length == 32); - - for (uint32_t i = 0; i < length; ++i) - ((uint8_t *)dst)[i] = src[length - i - 1]; - } else - ::memcpy(dst, src, length); - return length; - } - return 0; -} - -// Extract data as it exists in target memory -lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length, - void *dst) const { - const uint8_t *src = PeekData(offset, length); - if (src) { - ::memcpy(dst, src, length); - return length; - } - return 0; -} - -// Extract data and swap if needed when doing the copy -lldb::offset_t -DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len, - void *dst_void_ptr, offset_t dst_len, - ByteOrder dst_byte_order) const { - // Validate the source info - if (!ValidOffsetForDataOfSize(src_offset, src_len)) - assert(ValidOffsetForDataOfSize(src_offset, src_len)); - assert(src_len > 0); - assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle); - - // Validate the destination info - assert(dst_void_ptr != nullptr); - assert(dst_len > 0); - assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle); - - // Validate that only a word- or register-sized dst is byte swapped - assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 || - dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 || - dst_len == 32); - - // Must have valid byte orders set in this object and for destination - if (!(dst_byte_order == eByteOrderBig || - dst_byte_order == eByteOrderLittle) || - !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle)) - return 0; - - uint8_t *dst = (uint8_t *)dst_void_ptr; - const uint8_t *src = (const uint8_t *)PeekData(src_offset, src_len); - if (src) { - if (dst_len >= src_len) { - // We are copying the entire value from src into dst. - // Calculate how many, if any, zeroes we need for the most - // significant bytes if "dst_len" is greater than "src_len"... - const size_t num_zeroes = dst_len - src_len; - if (dst_byte_order == eByteOrderBig) { - // Big endian, so we lead with zeroes... - if (num_zeroes > 0) - ::memset(dst, 0, num_zeroes); - // Then either copy or swap the rest - if (m_byte_order == eByteOrderBig) { - ::memcpy(dst + num_zeroes, src, src_len); - } else { - for (uint32_t i = 0; i < src_len; ++i) - dst[i + num_zeroes] = src[src_len - 1 - i]; - } - } else { - // Little endian destination, so we lead the value bytes - if (m_byte_order == eByteOrderBig) { - for (uint32_t i = 0; i < src_len; ++i) - dst[i] = src[src_len - 1 - i]; - } else { - ::memcpy(dst, src, src_len); - } - // And zero the rest... - if (num_zeroes > 0) - ::memset(dst + src_len, 0, num_zeroes); - } - return src_len; - } else { - // We are only copying some of the value from src into dst.. - - if (dst_byte_order == eByteOrderBig) { - // Big endian dst - if (m_byte_order == eByteOrderBig) { - // Big endian dst, with big endian src - ::memcpy(dst, src + (src_len - dst_len), dst_len); - } else { - // Big endian dst, with little endian src - for (uint32_t i = 0; i < dst_len; ++i) - dst[i] = src[dst_len - 1 - i]; - } - } else { - // Little endian dst - if (m_byte_order == eByteOrderBig) { - // Little endian dst, with big endian src - for (uint32_t i = 0; i < dst_len; ++i) - dst[i] = src[src_len - 1 - i]; - } else { - // Little endian dst, with big endian src - ::memcpy(dst, src, dst_len); - } - } - return dst_len; - } - } - return 0; -} - -//---------------------------------------------------------------------- -// Extracts a variable length NULL terminated C string from -// the data at the offset pointed to by "offset_ptr". The -// "offset_ptr" will be updated with the offset of the byte that -// follows the NULL terminator byte. -// -// If the offset pointed to by "offset_ptr" is out of bounds, or if -// "length" is non-zero and there aren't enough available -// bytes, nullptr will be returned and "offset_ptr" will not be -// updated. -//---------------------------------------------------------------------- -const char *DataExtractor::GetCStr(offset_t *offset_ptr) const { - const char *cstr = (const char *)PeekData(*offset_ptr, 1); - if (cstr) { - const char *cstr_end = cstr; - const char *end = (const char *)m_end; - while (cstr_end < end && *cstr_end) - ++cstr_end; - - // Now we are either at the end of the data or we point to the - // NULL C string terminator with cstr_end... - if (*cstr_end == '\0') { - // Advance the offset with one extra byte for the NULL terminator - *offset_ptr += (cstr_end - cstr + 1); - return cstr; - } - - // We reached the end of the data without finding a NULL C string - // terminator. Fall through and return nullptr otherwise anyone that - // would have used the result as a C string can wander into - // unknown memory... - } - return nullptr; -} - -//---------------------------------------------------------------------- -// Extracts a NULL terminated C string from the fixed length field of -// length "len" at the offset pointed to by "offset_ptr". -// The "offset_ptr" will be updated with the offset of the byte that -// follows the fixed length field. -// -// If the offset pointed to by "offset_ptr" is out of bounds, or if -// the offset plus the length of the field is out of bounds, or if the -// field does not contain a NULL terminator byte, nullptr will be returned -// and "offset_ptr" will not be updated. -//---------------------------------------------------------------------- -const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const { - const char *cstr = (const char *)PeekData(*offset_ptr, len); - if (cstr != nullptr) { - if (memchr(cstr, '\0', len) == nullptr) { - return nullptr; - } - *offset_ptr += len; - return cstr; - } - return nullptr; -} - -//------------------------------------------------------------------ -// Peeks at a string in the contained data. No verification is done -// to make sure the entire string lies within the bounds of this -// object's data, only "offset" is verified to be a valid offset. -// -// Returns a valid C string pointer if "offset" is a valid offset in -// this object's data, else nullptr is returned. -//------------------------------------------------------------------ -const char *DataExtractor::PeekCStr(offset_t offset) const { - return (const char *)PeekData(offset, 1); -} - -//---------------------------------------------------------------------- -// Extracts an unsigned LEB128 number from this object's data -// starting at the offset pointed to by "offset_ptr". The offset -// pointed to by "offset_ptr" will be updated with the offset of the -// byte following the last extracted byte. -// -// Returned the extracted integer value. -//---------------------------------------------------------------------- -uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const { - const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1); - if (src == nullptr) - return 0; - - const uint8_t *end = m_end; - - if (src < end) { - uint64_t result = *src++; - if (result >= 0x80) { - result &= 0x7f; - int shift = 7; - while (src < end) { - uint8_t byte = *src++; - result |= (uint64_t)(byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - } - *offset_ptr = src - m_start; - return result; - } - - return 0; -} - -//---------------------------------------------------------------------- -// Extracts an signed LEB128 number from this object's data -// starting at the offset pointed to by "offset_ptr". The offset -// pointed to by "offset_ptr" will be updated with the offset of the -// byte following the last extracted byte. -// -// Returned the extracted integer value. -//---------------------------------------------------------------------- -int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const { - const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1); - if (src == nullptr) - return 0; - - const uint8_t *end = m_end; - - if (src < end) { - int64_t result = 0; - int shift = 0; - int size = sizeof(int64_t) * 8; - - uint8_t byte = 0; - int bytecount = 0; - - while (src < end) { - bytecount++; - byte = *src++; - result |= (int64_t)(byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - - // Sign bit of byte is 2nd high order bit (0x40) - if (shift < size && (byte & 0x40)) - result |= -(1 << shift); - - *offset_ptr += bytecount; - return result; - } - return 0; -} - -//---------------------------------------------------------------------- -// Skips a ULEB128 number (signed or unsigned) from this object's -// data starting at the offset pointed to by "offset_ptr". The -// offset pointed to by "offset_ptr" will be updated with the offset -// of the byte following the last extracted byte. -// -// Returns the number of bytes consumed during the extraction. -//---------------------------------------------------------------------- -uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const { - uint32_t bytes_consumed = 0; - const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1); - if (src == nullptr) - return 0; - - const uint8_t *end = m_end; - - if (src < end) { - const uint8_t *src_pos = src; - while ((src_pos < end) && (*src_pos++ & 0x80)) - ++bytes_consumed; - *offset_ptr += src_pos - src; - } - return bytes_consumed; -} - -static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr, - lldb::offset_t byte_size, llvm::APInt &result) { - llvm::SmallVector<uint64_t, 2> uint64_array; - lldb::offset_t bytes_left = byte_size; - uint64_t u64; - const lldb::ByteOrder byte_order = data.GetByteOrder(); - if (byte_order == lldb::eByteOrderLittle) { - while (bytes_left > 0) { - if (bytes_left >= 8) { - u64 = data.GetU64(offset_ptr); - bytes_left -= 8; - } else { - u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); - bytes_left = 0; - } - uint64_array.push_back(u64); - } - result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); - return true; - } else if (byte_order == lldb::eByteOrderBig) { - lldb::offset_t be_offset = *offset_ptr + byte_size; - lldb::offset_t temp_offset; - while (bytes_left > 0) { - if (bytes_left >= 8) { - be_offset -= 8; - temp_offset = be_offset; - u64 = data.GetU64(&temp_offset); - bytes_left -= 8; - } else { - be_offset -= bytes_left; - temp_offset = be_offset; - u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); - bytes_left = 0; - } - uint64_array.push_back(u64); - } - *offset_ptr += byte_size; - result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); - return true; - } - return false; -} - -static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, - lldb::offset_t offset, lldb::offset_t byte_size, - bool is_signed, unsigned radix) { - llvm::APInt apint; - if (GetAPInt(data, &offset, byte_size, apint)) { - std::string apint_str(apint.toString(radix, is_signed)); - switch (radix) { - case 2: - s->Write("0b", 2); - break; - case 8: - s->Write("0", 1); - break; - case 10: - break; - } - s->Write(apint_str.c_str(), apint_str.size()); - } - return offset; -} - -static float half2float(uint16_t half) { - union { - float f; - uint32_t u; - } u; - int32_t v = (int16_t)half; - - if (0 == (v & 0x7c00)) { - u.u = v & 0x80007FFFU; - return u.f * ldexpf(1, 125); - } - - v <<= 13; - u.u = v | 0x70000000U; - return u.f * ldexpf(1, -112); -} - -lldb::offset_t DataExtractor::Dump( - Stream *s, offset_t start_offset, lldb::Format item_format, - size_t item_byte_size, size_t item_count, size_t num_per_line, - uint64_t base_addr, - uint32_t item_bit_size, // If zero, this is not a bitfield value, if - // non-zero, the value is a bitfield - uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the - // shift amount to apply to a bitfield - ExecutionContextScope *exe_scope) const { - if (s == nullptr) - return start_offset; - - if (item_format == eFormatPointer) { - if (item_byte_size != 4 && item_byte_size != 8) - item_byte_size = s->GetAddressByteSize(); - } - - offset_t offset = start_offset; - - if (item_format == eFormatInstruction) { - TargetSP target_sp; - if (exe_scope) - target_sp = exe_scope->CalculateTarget(); - if (target_sp) { - DisassemblerSP disassembler_sp(Disassembler::FindPlugin( - target_sp->GetArchitecture(), nullptr, nullptr)); - if (disassembler_sp) { - lldb::addr_t addr = base_addr + start_offset; - lldb_private::Address so_addr; - bool data_from_file = true; - if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { - data_from_file = false; - } else { - if (target_sp->GetSectionLoadList().IsEmpty() || - !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) - so_addr.SetRawAddress(addr); - } - - size_t bytes_consumed = disassembler_sp->DecodeInstructions( - so_addr, *this, start_offset, item_count, false, data_from_file); - - if (bytes_consumed) { - offset += bytes_consumed; - const bool show_address = base_addr != LLDB_INVALID_ADDRESS; - const bool show_bytes = true; - ExecutionContext exe_ctx; - exe_scope->CalculateExecutionContext(exe_ctx); - disassembler_sp->GetInstructionList().Dump(s, show_address, - show_bytes, &exe_ctx); - } - } - } else - s->Printf("invalid target"); - - return offset; - } - - if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && - item_byte_size > 8) - item_format = eFormatHex; - - lldb::offset_t line_start_offset = start_offset; - for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count) { - if ((count % num_per_line) == 0) { - if (count > 0) { - if (item_format == eFormatBytesWithASCII && - offset > line_start_offset) { - s->Printf("%*s", - static_cast<int>( - (num_per_line - (offset - line_start_offset)) * 3 + 2), - ""); - Dump(s, line_start_offset, eFormatCharPrintable, 1, - offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, - 0); - } - s->EOL(); - } - if (base_addr != LLDB_INVALID_ADDRESS) - s->Printf("0x%8.8" PRIx64 ": ", - (uint64_t)(base_addr + - (offset - start_offset) / m_target_byte_size)); - - line_start_offset = offset; - } else if (item_format != eFormatChar && - item_format != eFormatCharPrintable && - item_format != eFormatCharArray && count > 0) { - s->PutChar(' '); - } - - switch (item_format) { - case eFormatBoolean: - if (item_byte_size <= 8) - s->Printf("%s", GetMaxU64Bitfield(&offset, item_byte_size, - item_bit_size, item_bit_offset) - ? "true" - : "false"); - else { - s->Printf("error: unsupported byte size (%" PRIu64 - ") for boolean format", - (uint64_t)item_byte_size); - return offset; - } - break; - - case eFormatBinary: - if (item_byte_size <= 8) { - uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, - item_bit_size, item_bit_offset); - // Avoid std::bitset<64>::to_string() since it is missing in - // earlier C++ libraries - std::string binary_value(64, '0'); - std::bitset<64> bits(uval64); - for (uint32_t i = 0; i < 64; ++i) - if (bits[i]) - binary_value[64 - 1 - i] = '1'; - if (item_bit_size > 0) - s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); - else if (item_byte_size > 0 && item_byte_size <= 8) - s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); - } else { - const bool is_signed = false; - const unsigned radix = 2; - offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix); - } - break; - - case eFormatBytes: - case eFormatBytesWithASCII: - for (uint32_t i = 0; i < item_byte_size; ++i) { - s->Printf("%2.2x", GetU8(&offset)); - } - - // Put an extra space between the groups of bytes if more than one - // is being dumped in a group (item_byte_size is more than 1). - if (item_byte_size > 1) - s->PutChar(' '); - break; - - case eFormatChar: - case eFormatCharPrintable: - case eFormatCharArray: { - // If we are only printing one character surround it with single - // quotes - if (item_count == 1 && item_format == eFormatChar) - s->PutChar('\''); - - const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size, - item_bit_size, item_bit_offset); - if (isprint(ch)) - s->Printf("%c", (char)ch); - else if (item_format != eFormatCharPrintable) { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: - if (item_byte_size == 1) - s->Printf("\\x%2.2x", (uint8_t)ch); - else - s->Printf("%" PRIu64, ch); - break; - } - } else { - s->PutChar(NON_PRINTABLE_CHAR); - } - - // If we are only printing one character surround it with single quotes - if (item_count == 1 && item_format == eFormatChar) - s->PutChar('\''); - } break; - - case eFormatEnum: // Print enum value as a signed integer when we don't get - // the enum type - case eFormatDecimal: - if (item_byte_size <= 8) - s->Printf("%" PRId64, - GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset)); - else { - const bool is_signed = true; - const unsigned radix = 10; - offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix); - } - break; - - case eFormatUnsigned: - if (item_byte_size <= 8) - s->Printf("%" PRIu64, - GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset)); - else { - const bool is_signed = false; - const unsigned radix = 10; - offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix); - } - break; - - case eFormatOctal: - if (item_byte_size <= 8) - s->Printf("0%" PRIo64, - GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset)); - else { - const bool is_signed = false; - const unsigned radix = 8; - offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix); - } - break; - - case eFormatOSType: { - uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, - item_bit_size, item_bit_offset); - s->PutChar('\''); - for (uint32_t i = 0; i < item_byte_size; ++i) { - uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); - if (isprint(ch)) - s->Printf("%c", ch); - else { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: - s->Printf("\\x%2.2x", ch); - break; - } - } - } - s->PutChar('\''); - } break; - - case eFormatCString: { - const char *cstr = GetCStr(&offset); - - if (!cstr) { - s->Printf("NULL"); - offset = LLDB_INVALID_OFFSET; - } else { - s->PutChar('\"'); - - while (const char c = *cstr) { - if (isprint(c)) { - s->PutChar(c); - } else { - switch (c) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - default: - s->Printf("\\x%2.2x", c); - break; - } - } - - ++cstr; - } - - s->PutChar('\"'); - } - } break; - - case eFormatPointer: - s->Address(GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset), - sizeof(addr_t)); - break; - - case eFormatComplexInteger: { - size_t complex_int_byte_size = item_byte_size / 2; - - if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { - s->Printf("%" PRIu64, - GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); - s->Printf(" + %" PRIu64 "i", - GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); - } else { - s->Printf("error: unsupported byte size (%" PRIu64 - ") for complex integer format", - (uint64_t)item_byte_size); - return offset; - } - } break; - - case eFormatComplex: - if (sizeof(float) * 2 == item_byte_size) { - float f32_1 = GetFloat(&offset); - float f32_2 = GetFloat(&offset); - - s->Printf("%g + %gi", f32_1, f32_2); - break; - } else if (sizeof(double) * 2 == item_byte_size) { - double d64_1 = GetDouble(&offset); - double d64_2 = GetDouble(&offset); - - s->Printf("%lg + %lgi", d64_1, d64_2); - break; - } else if (sizeof(long double) * 2 == item_byte_size) { - long double ld64_1 = GetLongDouble(&offset); - long double ld64_2 = GetLongDouble(&offset); - s->Printf("%Lg + %Lgi", ld64_1, ld64_2); - break; - } else { - s->Printf("error: unsupported byte size (%" PRIu64 - ") for complex float format", - (uint64_t)item_byte_size); - return offset; - } - break; - - default: - case eFormatDefault: - case eFormatHex: - case eFormatHexUppercase: { - bool wantsuppercase = (item_format == eFormatHexUppercase); - switch (item_byte_size) { - case 1: - case 2: - case 4: - case 8: - s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, - (int)(2 * item_byte_size), (int)(2 * item_byte_size), - GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset)); - break; - default: { - assert(item_bit_size == 0 && item_bit_offset == 0); - const uint8_t *bytes = - (const uint8_t *)GetData(&offset, item_byte_size); - if (bytes) { - s->PutCString("0x"); - uint32_t idx; - if (m_byte_order == eByteOrderBig) { - for (idx = 0; idx < item_byte_size; ++idx) - s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); - } else { - for (idx = 0; idx < item_byte_size; ++idx) - s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", - bytes[item_byte_size - 1 - idx]); - } - } - } break; - } - } break; - - case eFormatFloat: { - TargetSP target_sp; - bool used_apfloat = false; - if (exe_scope) - target_sp = exe_scope->CalculateTarget(); - if (target_sp) { - ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); - if (clang_ast) { - clang::ASTContext *ast = clang_ast->getASTContext(); - if (ast) { - llvm::SmallVector<char, 256> sv; - // Show full precision when printing float values - const unsigned format_precision = 0; - const unsigned format_max_padding = 100; - size_t item_bit_size = item_byte_size * 8; - - if (item_bit_size == ast->getTypeSize(ast->FloatTy)) { - llvm::APInt apint(item_bit_size, - this->GetMaxU64(&offset, item_byte_size)); - llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy), - apint); - apfloat.toString(sv, format_precision, format_max_padding); - } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) { - llvm::APInt apint; - if (GetAPInt(*this, &offset, item_byte_size, apint)) { - llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy), - apint); - apfloat.toString(sv, format_precision, format_max_padding); - } - } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { - const auto &semantics = - ast->getFloatTypeSemantics(ast->LongDoubleTy); - const auto byte_size = - (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; - - llvm::APInt apint; - if (GetAPInt(*this, &offset, byte_size, apint)) { - llvm::APFloat apfloat(semantics, apint); - apfloat.toString(sv, format_precision, format_max_padding); - } - } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) { - llvm::APInt apint(item_bit_size, this->GetU16(&offset)); - llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy), - apint); - apfloat.toString(sv, format_precision, format_max_padding); - } - - if (!sv.empty()) { - s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); - used_apfloat = true; - } - } - } - } - - if (!used_apfloat) { - std::ostringstream ss; - if (item_byte_size == sizeof(float) || item_byte_size == 2) { - float f; - if (item_byte_size == 2) { - uint16_t half = this->GetU16(&offset); - f = half2float(half); - } else { - f = GetFloat(&offset); - } - ss.precision(std::numeric_limits<float>::digits10); - ss << f; - } else if (item_byte_size == sizeof(double)) { - ss.precision(std::numeric_limits<double>::digits10); - ss << GetDouble(&offset); - } else if (item_byte_size == sizeof(long double) || - item_byte_size == 10) { - ss.precision(std::numeric_limits<long double>::digits10); - ss << GetLongDouble(&offset); - } else { - s->Printf("error: unsupported byte size (%" PRIu64 - ") for float format", - (uint64_t)item_byte_size); - return offset; - } - ss.flush(); - s->Printf("%s", ss.str().c_str()); - } - } break; - - case eFormatUnicode16: - s->Printf("U+%4.4x", GetU16(&offset)); - break; - - case eFormatUnicode32: - s->Printf("U+0x%8.8x", GetU32(&offset)); - break; - - case eFormatAddressInfo: { - addr_t addr = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, - item_bit_offset); - s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), - (int)(2 * item_byte_size), addr); - if (exe_scope) { - TargetSP target_sp(exe_scope->CalculateTarget()); - lldb_private::Address so_addr; - if (target_sp) { - if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, - so_addr)) { - s->PutChar(' '); - so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, - Address::DumpStyleModuleWithFileAddress); - } else { - so_addr.SetOffset(addr); - so_addr.Dump(s, exe_scope, - Address::DumpStyleResolvedPointerDescription); - } - } - } - } break; - - case eFormatHexFloat: - if (sizeof(float) == item_byte_size) { - char float_cstr[256]; - llvm::APFloat ap_float(GetFloat(&offset)); - ap_float.convertToHexString(float_cstr, 0, false, - llvm::APFloat::rmNearestTiesToEven); - s->Printf("%s", float_cstr); - break; - } else if (sizeof(double) == item_byte_size) { - char float_cstr[256]; - llvm::APFloat ap_float(GetDouble(&offset)); - ap_float.convertToHexString(float_cstr, 0, false, - llvm::APFloat::rmNearestTiesToEven); - s->Printf("%s", float_cstr); - break; - } else { - s->Printf("error: unsupported byte size (%" PRIu64 - ") for hex float format", - (uint64_t)item_byte_size); - return offset; - } - break; - - // please keep the single-item formats below in sync with - // FormatManager::GetSingleItemFormat - // if you fail to do so, users will start getting different outputs - // depending on internal - // implementation details they should not care about || - case eFormatVectorOfChar: // || - s->PutChar('{'); // \/ - offset = Dump(s, offset, eFormatCharArray, 1, item_byte_size, - item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfSInt8: - s->PutChar('{'); - offset = Dump(s, offset, eFormatDecimal, 1, item_byte_size, - item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfUInt8: - s->PutChar('{'); - offset = Dump(s, offset, eFormatHex, 1, item_byte_size, item_byte_size, - LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfSInt16: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatDecimal, sizeof(uint16_t), - item_byte_size / sizeof(uint16_t), - item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfUInt16: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatHex, sizeof(uint16_t), - item_byte_size / sizeof(uint16_t), - item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfSInt32: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatDecimal, sizeof(uint32_t), - item_byte_size / sizeof(uint32_t), - item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfUInt32: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatHex, sizeof(uint32_t), - item_byte_size / sizeof(uint32_t), - item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfSInt64: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatDecimal, sizeof(uint64_t), - item_byte_size / sizeof(uint64_t), - item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfUInt64: - s->PutChar('{'); - offset = - Dump(s, offset, eFormatHex, sizeof(uint64_t), - item_byte_size / sizeof(uint64_t), - item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfFloat16: - s->PutChar('{'); - offset = Dump(s, offset, eFormatFloat, 2, item_byte_size / 2, - item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfFloat32: - s->PutChar('{'); - offset = Dump(s, offset, eFormatFloat, 4, item_byte_size / 4, - item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfFloat64: - s->PutChar('{'); - offset = Dump(s, offset, eFormatFloat, 8, item_byte_size / 8, - item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - - case eFormatVectorOfUInt128: - s->PutChar('{'); - offset = Dump(s, offset, eFormatHex, 16, item_byte_size / 16, - item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('}'); - break; - } - } - - if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { - s->Printf("%*s", static_cast<int>( - (num_per_line - (offset - line_start_offset)) * 3 + 2), - ""); - Dump(s, line_start_offset, eFormatCharPrintable, 1, - offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0); - } - return offset; // Return the offset at which we ended up -} - -//---------------------------------------------------------------------- -// Dumps bytes from this object's data to the stream "s" starting -// "start_offset" bytes into this data, and ending with the byte -// before "end_offset". "base_addr" will be added to the offset -// into the dumped data when showing the offset into the data in the -// output information. "num_per_line" objects of type "type" will -// be dumped with the option to override the format for each object -// with "type_format". "type_format" is a printf style formatting -// string. If "type_format" is nullptr, then an appropriate format -// string will be used for the supplied "type". If the stream "s" -// is nullptr, then the output will be send to Log(). -//---------------------------------------------------------------------- -lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset, - offset_t length, uint64_t base_addr, - uint32_t num_per_line, - DataExtractor::Type type, - const char *format) const { - if (log == nullptr) - return start_offset; - - offset_t offset; - offset_t end_offset; - uint32_t count; - StreamString sstr; - for (offset = start_offset, end_offset = offset + length, count = 0; - ValidOffset(offset) && offset < end_offset; ++count) { - if ((count % num_per_line) == 0) { - // Print out any previous string - if (sstr.GetSize() > 0) { - log->PutString(sstr.GetString()); - sstr.Clear(); - } - // Reset string offset and fill the current line string with address: - if (base_addr != LLDB_INVALID_ADDRESS) - sstr.Printf("0x%8.8" PRIx64 ":", - (uint64_t)(base_addr + (offset - start_offset))); - } - - switch (type) { - case TypeUInt8: - sstr.Printf(format ? format : " %2.2x", GetU8(&offset)); - break; - case TypeChar: { - char ch = GetU8(&offset); - sstr.Printf(format ? format : " %c", isprint(ch) ? ch : ' '); - } break; - case TypeUInt16: - sstr.Printf(format ? format : " %4.4x", GetU16(&offset)); - break; - case TypeUInt32: - sstr.Printf(format ? format : " %8.8x", GetU32(&offset)); - break; - case TypeUInt64: - sstr.Printf(format ? format : " %16.16" PRIx64, GetU64(&offset)); - break; - case TypePointer: - sstr.Printf(format ? format : " 0x%" PRIx64, GetAddress(&offset)); - break; - case TypeULEB128: - sstr.Printf(format ? format : " 0x%" PRIx64, GetULEB128(&offset)); - break; - case TypeSLEB128: - sstr.Printf(format ? format : " %" PRId64, GetSLEB128(&offset)); - break; - } - } - - if (!sstr.Empty()) - log->PutString(sstr.GetString()); - - return offset; // Return the offset at which we ended up -} - -//---------------------------------------------------------------------- -// DumpUUID -// -// Dump out a UUID starting at 'offset' bytes into the buffer -//---------------------------------------------------------------------- -void DataExtractor::DumpUUID(Stream *s, offset_t offset) const { - if (s) { - const uint8_t *uuid_data = PeekData(offset, 16); - if (uuid_data) { - lldb_private::UUID uuid(uuid_data, 16); - uuid.Dump(s); - } else { - s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">", - offset); - } - } -} - -void DataExtractor::DumpHexBytes(Stream *s, const void *src, size_t src_len, - uint32_t bytes_per_line, addr_t base_addr) { - DataExtractor data(src, src_len, eByteOrderLittle, 4); - data.Dump(s, - 0, // Offset into "src" - eFormatBytes, // Dump as hex bytes - 1, // Size of each item is 1 for single bytes - src_len, // Number of bytes - bytes_per_line, // Num bytes per line - base_addr, // Base address - 0, 0); // Bitfield info -} - -size_t DataExtractor::Copy(DataExtractor &dest_data) const { - if (m_data_sp) { - // 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 = nullptr; - DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); - - if (!buffer_sp || buffer_heap_ptr == nullptr) - 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, offset_t length) { - if (buf == nullptr) - return false; - - if (length == 0) - return true; - - size_t bytes = GetByteSize() + length; - - DataBufferHeap *buffer_heap_ptr = nullptr; - DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0)); - - if (!buffer_sp || buffer_heap_ptr == nullptr) - 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; -} - -void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest, - uint64_t max_data) { - if (max_data == 0) - max_data = GetByteSize(); - else - max_data = std::min(max_data, GetByteSize()); - - llvm::MD5 md5; - - const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data); - md5.update(data); - - llvm::MD5::MD5Result result; - md5.final(result); - - dest.resize(16); - std::copy(result, result + 16, dest.begin()); -} diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp index 8f888a518d5b..751ceed13149 100644 --- a/source/Core/Debugger.cpp +++ b/source/Core/Debugger.cpp @@ -9,57 +9,70 @@ #include "lldb/Core/Debugger.h" -// C Includes -// C++ Includes -#include <map> -#include <mutex> - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DynamicLibrary.h" - -// Project includes +#include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint, Brea... +#include "lldb/Core/Event.h" // for Event, EventData... #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginInterface.h" +#include "lldb/Core/Listener.h" // for Listener +#include "lldb/Core/Mangled.h" // for Mangled #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamAsynchronousIO.h" -#include "lldb/Core/StreamCallback.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/StructuredData.h" -#include "lldb/Core/Timer.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/FormatManager.h" -#include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Expression/REPL.h" -#include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/File.h" // for File, File::kInv... #include "lldb/Host/HostInfo.h" #include "lldb/Host/Terminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionValue.h" // for OptionValue, Opt... #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/OptionValueSInt64.h" #include "lldb/Interpreter/OptionValueString.h" -#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Interpreter/Property.h" // for PropertyDefinition +#include "lldb/Interpreter/ScriptInterpreter.h" // for ScriptInterpreter #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/VariableList.h" +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/StopInfo.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadList.h" // for ThreadList #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/lldb-private.h" +#include "lldb/Utility/Log.h" // for LLDB_LOG_OPTION_... +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamCallback.h" +#include "lldb/Utility/StreamString.h" + +#if defined(LLVM_ON_WIN32) +#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#endif + +#include "llvm/ADT/None.h" // for None +#include "llvm/ADT/STLExtras.h" // for make_unique +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" // for iterator_facade_... +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Threading.h" +#include "llvm/Support/raw_ostream.h" // for raw_fd_ostream + +#include <list> // for list +#include <memory> // for make_shared +#include <mutex> +#include <set> // for set +#include <stdio.h> // for size_t, NULL +#include <stdlib.h> // for getenv +#include <string.h> // for strcmp +#include <string> // for string +#include <system_error> // for error_code + +namespace lldb_private { +class Address; +} using namespace lldb; using namespace lldb_private; @@ -125,7 +138,7 @@ OptionEnumValueElement g_language_enumerators[] = { "\\n" #define DEFAULT_FRAME_FORMAT \ - "frame #${frame.index}:{ ${frame.no-debug}${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ + "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE \ IS_OPTIMIZED "\\n" // Three parts to this disassembly format specification: @@ -296,9 +309,9 @@ Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, if (str.length()) new_prompt = str; GetCommandInterpreter().UpdatePrompt(new_prompt); - EventSP prompt_change_event_sp( - new Event(CommandInterpreter::eBroadcastBitResetPrompt, - new EventDataBytes(new_prompt))); + auto bytes = llvm::make_unique<EventDataBytes>(new_prompt); + auto prompt_change_event_sp = std::make_shared<Event>( + CommandInterpreter::eBroadcastBitResetPrompt, bytes.release()); GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp); } else if (property_path == g_properties[ePropertyUseColor].name) { // use-color changed. Ping the prompt so it can reset the ansi terminal @@ -555,7 +568,7 @@ bool Debugger::LoadPlugin(const FileSpec &spec, Error &error) { } static FileSpec::EnumerateDirectoryResult -LoadPluginCallback(void *baton, FileSpec::FileType file_type, +LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) { Error error; @@ -567,13 +580,13 @@ LoadPluginCallback(void *baton, FileSpec::FileType file_type, Debugger *debugger = (Debugger *)baton; + namespace fs = llvm::sys::fs; // If we have a regular file, a symbolic link or unknown file type, try // and process the file. We must handle unknown as sometimes the directory // enumeration might be enumerating a file system that doesn't have correct // file type information. - if (file_type == FileSpec::eFileTypeRegular || - file_type == FileSpec::eFileTypeSymbolicLink || - file_type == FileSpec::eFileTypeUnknown) { + if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || + ft == fs::file_type::type_unknown) { FileSpec plugin_file_spec(file_spec); plugin_file_spec.ResolvePath(); @@ -586,9 +599,9 @@ LoadPluginCallback(void *baton, FileSpec::FileType file_type, debugger->LoadPlugin(plugin_file_spec, plugin_load_error); return FileSpec::eEnumerateDirectoryResultNext; - } else if (file_type == FileSpec::eFileTypeUnknown || - file_type == FileSpec::eFileTypeDirectory || - file_type == FileSpec::eFileTypeSymbolicLink) { + } else if (ft == fs::file_type::directory_file || + ft == fs::file_type::symlink_file || + ft == fs::file_type::type_unknown) { // Try and recurse into anything that a directory or symbolic link. // We must also do this for unknown as sometimes the directory enumeration // might be enumerating a file system that doesn't have correct file type @@ -697,16 +710,16 @@ TargetSP Debugger::FindTargetWithProcess(Process *process) { Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : UserID(g_unique_id++), - Properties(OptionValuePropertiesSP(new OptionValueProperties())), - m_input_file_sp(new StreamFile(stdin, false)), - m_output_file_sp(new StreamFile(stdout, false)), - m_error_file_sp(new StreamFile(stderr, false)), + Properties(std::make_shared<OptionValueProperties>()), + m_input_file_sp(std::make_shared<StreamFile>(stdin, false)), + m_output_file_sp(std::make_shared<StreamFile>(stdout, false)), + m_error_file_sp(std::make_shared<StreamFile>(stderr, false)), m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), m_terminal_state(), m_target_list(*this), m_platform_list(), m_listener_sp(Listener::MakeListener("lldb.Debugger")), m_source_manager_ap(), m_source_file_cache(), - m_command_interpreter_ap( - new CommandInterpreter(*this, eScriptLanguageDefault, false)), + m_command_interpreter_ap(llvm::make_unique<CommandInterpreter>( + *this, eScriptLanguageDefault, false)), m_input_reader_stack(), m_instance_name(), m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), @@ -715,7 +728,8 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID()); m_instance_name.SetCString(instance_cstr); if (log_callback) - m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton)); + m_log_callback_stream_sp = + std::make_shared<StreamCallback>(log_callback, baton); m_command_interpreter_ap->Initialize(); // Always add our default platform to the platform list PlatformSP default_platform_sp(Platform::GetHostPlatform()); @@ -762,7 +776,7 @@ void Debugger::Clear() { // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); // static void Debugger::Terminate(); //---------------------------------------------------------------------- - std::call_once(m_clear_once, [this]() { + llvm::call_once(m_clear_once, [this]() { ClearIOHandlers(); StopIOHandlerThread(); StopEventHandlerThread(); @@ -811,7 +825,7 @@ void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) { if (m_input_file_sp) m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership); else - m_input_file_sp.reset(new StreamFile(fh, tranfer_ownership)); + m_input_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); File &in_file = m_input_file_sp->GetFile(); if (!in_file.IsValid()) @@ -826,7 +840,7 @@ void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) { if (m_output_file_sp) m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership); else - m_output_file_sp.reset(new StreamFile(fh, tranfer_ownership)); + m_output_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); File &out_file = m_output_file_sp->GetFile(); if (!out_file.IsValid()) @@ -845,7 +859,7 @@ void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) { if (m_error_file_sp) m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership); else - m_error_file_sp.reset(new StreamFile(fh, tranfer_ownership)); + m_error_file_sp = std::make_shared<StreamFile>(fh, tranfer_ownership); File &err_file = m_error_file_sp->GetFile(); if (!err_file.IsValid()) @@ -996,7 +1010,7 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, // If there is nothing, use stdin if (!in) - in = StreamFileSP(new StreamFile(stdin, false)); + in = std::make_shared<StreamFile>(stdin, false); } // If no STDOUT has been set, then set it appropriately if (!out) { @@ -1007,7 +1021,7 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, // If there is nothing, use stdout if (!out) - out = StreamFileSP(new StreamFile(stdout, false)); + out = std::make_shared<StreamFile>(stdout, false); } // If no STDERR has been set, then set it appropriately if (!err) { @@ -1018,7 +1032,7 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, // If there is nothing, use stderr if (!err) - err = StreamFileSP(new StreamFile(stdout, false)); + err = std::make_shared<StreamFile>(stdout, false); } } @@ -1075,11 +1089,11 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { } StreamSP Debugger::GetAsyncOutputStream() { - return StreamSP(new StreamAsynchronousIO(*this, true)); + return std::make_shared<StreamAsynchronousIO>(*this, true); } StreamSP Debugger::GetAsyncErrorStream() { - return StreamSP(new StreamAsynchronousIO(*this, false)); + return std::make_shared<StreamAsynchronousIO>(*this, false); } size_t Debugger::GetNumDebuggers() { @@ -1234,31 +1248,42 @@ void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, // For simplicity's sake, I am not going to deal with how to close down any // open logging streams, I just redirect everything from here on out to the // callback. - m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton)); + m_log_callback_stream_sp = + std::make_shared<StreamCallback>(log_callback, baton); } -bool Debugger::EnableLog(const char *channel, const char **categories, - const char *log_file, uint32_t log_options, - Stream &error_stream) { - StreamSP log_stream_sp; +bool Debugger::EnableLog(llvm::StringRef channel, + llvm::ArrayRef<const char *> categories, + llvm::StringRef log_file, uint32_t log_options, + llvm::raw_ostream &error_stream) { + const bool should_close = true; + const bool unbuffered = true; + + std::shared_ptr<llvm::raw_ostream> log_stream_sp; if (m_log_callback_stream_sp) { log_stream_sp = m_log_callback_stream_sp; // For now when using the callback mode you always get thread & timestamp. log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; - } else if (log_file == nullptr || *log_file == '\0') { - log_stream_sp = GetOutputFile(); + } else if (log_file.empty()) { + log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( + GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered); } else { - LogStreamMap::iterator pos = m_log_streams.find(log_file); + auto pos = m_log_streams.find(log_file); if (pos != m_log_streams.end()) log_stream_sp = pos->second.lock(); if (!log_stream_sp) { - uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate | - File::eOpenOptionCloseOnExec | File::eOpenOptionAppend; - if (!(log_options & LLDB_LOG_OPTION_APPEND)) - options |= File::eOpenOptionTruncate; - - log_stream_sp.reset(new StreamFile(log_file, options)); + llvm::sys::fs::OpenFlags flags = llvm::sys::fs::F_Text; + if (log_options & LLDB_LOG_OPTION_APPEND) + flags |= llvm::sys::fs::F_Append; + int FD; + if (std::error_code ec = + llvm::sys::fs::openFileForWrite(log_file, FD, flags)) { + error_stream << "Unable to open log file: " << ec.message(); + return false; + } + log_stream_sp = + std::make_shared<llvm::raw_fd_ostream>(FD, should_close, unbuffered); m_log_streams[log_file] = log_stream_sp; } } @@ -1274,7 +1299,7 @@ bool Debugger::EnableLog(const char *channel, const char **categories, SourceManager &Debugger::GetSourceManager() { if (!m_source_manager_ap) - m_source_manager_ap.reset(new SourceManager(shared_from_this())); + m_source_manager_ap = llvm::make_unique<SourceManager>(shared_from_this()); return *m_source_manager_ap; } diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp index 7cac29491c8c..3880bfd16ecc 100644 --- a/source/Core/Disassembler.cpp +++ b/source/Core/Disassembler.cpp @@ -9,21 +9,14 @@ #include "lldb/Core/Disassembler.h" -// C Includes -// C++ Includes -#include <cstdio> -#include <cstring> - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/Debugger.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/Error.h" +#include "lldb/Core/Mangled.h" // for Mangled, Mangled... #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/SourceManager.h" // for SourceManager #include "lldb/Core/Timer.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/OptionValue.h" @@ -33,13 +26,30 @@ #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" // for Symbol +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -#include "lldb/lldb-private.h" +#include "lldb/Target/Thread.h" // for Thread +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" // for StreamString +#include "lldb/lldb-private-enumerations.h" // for InstructionType:... +#include "lldb/lldb-private-interfaces.h" // for DisassemblerCrea... +#include "lldb/lldb-private-types.h" // for RegisterInfo +#include "llvm/ADT/Triple.h" // for Triple, Triple::... +#include "llvm/Support/Compiler.h" // for LLVM_PRETTY_FUNC... + +#include <cstdint> // for uint32_t, UINT32... +#include <cstring> +#include <utility> // for pair + +#include <assert.h> // for assert #define DEFAULT_DISASM_BYTE_SIZE 32 @@ -759,7 +769,7 @@ OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream, bool done = false; char buffer[1024]; - OptionValueSP option_value_sp(new OptionValueArray(1u << data_type)); + auto option_value_sp = std::make_shared<OptionValueArray>(1u << data_type); int idx = 0; while (!done) { @@ -797,12 +807,12 @@ OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream, OptionValueSP data_value_sp; switch (data_type) { case OptionValue::eTypeUInt64: - data_value_sp.reset(new OptionValueUInt64(0, 0)); + data_value_sp = std::make_shared<OptionValueUInt64>(0, 0); data_value_sp->SetValueFromString(value); break; // Other types can be added later as needed. default: - data_value_sp.reset(new OptionValueString(value.c_str(), "")); + data_value_sp = std::make_shared<OptionValueString>(value.c_str(), ""); break; } @@ -818,7 +828,7 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { bool done = false; char buffer[1024]; - OptionValueSP option_value_sp(new OptionValueDictionary()); + auto option_value_sp = std::make_shared<OptionValueDictionary>(); static ConstString encoding_key("data_encoding"); OptionValue::Type data_type = OptionValue::eTypeInvalid; @@ -891,13 +901,13 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { // We've used the data_type to read an array; re-set the type to Invalid data_type = OptionValue::eTypeInvalid; } else if ((value[0] == '0') && (value[1] == 'x')) { - value_sp.reset(new OptionValueUInt64(0, 0)); + value_sp = std::make_shared<OptionValueUInt64>(0, 0); value_sp->SetValueFromString(value); } else { size_t len = value.size(); if ((value[0] == '"') && (value[len - 1] == '"')) value = value.substr(1, len - 2); - value_sp.reset(new OptionValueString(value.c_str(), "")); + value_sp = std::make_shared<OptionValueString>(value.c_str(), ""); } if (const_key == encoding_key) { @@ -1163,18 +1173,17 @@ size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, !range.GetBaseAddress().IsValid()) return 0; - DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); + auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0'); Error error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = target->ReadMemory( - range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(), - heap_buffer->GetByteSize(), error, &load_addr); + range.GetBaseAddress(), prefer_file_cache, data_sp->GetBytes(), + data_sp->GetByteSize(), error, &load_addr); if (bytes_read > 0) { - if (bytes_read != heap_buffer->GetByteSize()) - heap_buffer->SetByteSize(bytes_read); + if (bytes_read != data_sp->GetByteSize()) + data_sp->SetByteSize(bytes_read); DataExtractor data(data_sp, m_arch.GetByteOrder(), m_arch.GetAddressByteSize()); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; diff --git a/source/Core/DumpDataExtractor.cpp b/source/Core/DumpDataExtractor.cpp new file mode 100644 index 000000000000..2b7abd60f8bc --- /dev/null +++ b/source/Core/DumpDataExtractor.cpp @@ -0,0 +1,824 @@ +//===-- DumpDataExtractor.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/DumpDataExtractor.h" + +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-forward.h" // for TargetSP, DisassemblerSP + +#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Stream.h" + +#include "clang/AST/ASTContext.h" // for ASTContext +#include "clang/AST/CanonicalType.h" // for CanQualType + +#include "llvm/ADT/APFloat.h" // for APFloat, APFloatBase:... +#include "llvm/ADT/APInt.h" // for APInt +#include "llvm/ADT/ArrayRef.h" // for ArrayRef +#include "llvm/ADT/SmallVector.h" // for SmallVector + +#include <limits> // for numeric_limits, numer... +#include <memory> // for shared_ptr +#include <string> // for string, basic_string + +#include <assert.h> // for assert +#include <ctype.h> // for isprint +#include <inttypes.h> // for PRIu64, PRIx64, PRIX64 +#include <math.h> // for ldexpf + +#include <bitset> +#include <sstream> + +using namespace lldb_private; +using namespace lldb; + +#define NON_PRINTABLE_CHAR '.' + +static float half2float(uint16_t half) { + union { + float f; + uint32_t u; + } u; + int32_t v = (int16_t)half; + + if (0 == (v & 0x7c00)) { + u.u = v & 0x80007FFFU; + return u.f * ldexpf(1, 125); + } + + v <<= 13; + u.u = v | 0x70000000U; + return u.f * ldexpf(1, -112); +} + +static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr, + lldb::offset_t byte_size, llvm::APInt &result) { + llvm::SmallVector<uint64_t, 2> uint64_array; + lldb::offset_t bytes_left = byte_size; + uint64_t u64; + const lldb::ByteOrder byte_order = data.GetByteOrder(); + if (byte_order == lldb::eByteOrderLittle) { + while (bytes_left > 0) { + if (bytes_left >= 8) { + u64 = data.GetU64(offset_ptr); + bytes_left -= 8; + } else { + u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); + bytes_left = 0; + } + uint64_array.push_back(u64); + } + result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); + return true; + } else if (byte_order == lldb::eByteOrderBig) { + lldb::offset_t be_offset = *offset_ptr + byte_size; + lldb::offset_t temp_offset; + while (bytes_left > 0) { + if (bytes_left >= 8) { + be_offset -= 8; + temp_offset = be_offset; + u64 = data.GetU64(&temp_offset); + bytes_left -= 8; + } else { + be_offset -= bytes_left; + temp_offset = be_offset; + u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); + bytes_left = 0; + } + uint64_array.push_back(u64); + } + *offset_ptr += byte_size; + result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); + return true; + } + return false; +} + +static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, + lldb::offset_t offset, lldb::offset_t byte_size, + bool is_signed, unsigned radix) { + llvm::APInt apint; + if (GetAPInt(data, &offset, byte_size, apint)) { + std::string apint_str(apint.toString(radix, is_signed)); + switch (radix) { + case 2: + s->Write("0b", 2); + break; + case 8: + s->Write("0", 1); + break; + case 10: + break; + } + s->Write(apint_str.c_str(), apint_str.size()); + } + return offset; +} + +lldb::offset_t lldb_private::DumpDataExtractor( + const DataExtractor &DE, Stream *s, offset_t start_offset, + lldb::Format item_format, size_t item_byte_size, size_t item_count, + size_t num_per_line, uint64_t base_addr, + uint32_t item_bit_size, // If zero, this is not a bitfield value, if + // non-zero, the value is a bitfield + uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the + // shift amount to apply to a bitfield + ExecutionContextScope *exe_scope) { + if (s == nullptr) + return start_offset; + + if (item_format == eFormatPointer) { + if (item_byte_size != 4 && item_byte_size != 8) + item_byte_size = s->GetAddressByteSize(); + } + + offset_t offset = start_offset; + + if (item_format == eFormatInstruction) { + TargetSP target_sp; + if (exe_scope) + target_sp = exe_scope->CalculateTarget(); + if (target_sp) { + DisassemblerSP disassembler_sp(Disassembler::FindPlugin( + target_sp->GetArchitecture(), nullptr, nullptr)); + if (disassembler_sp) { + lldb::addr_t addr = base_addr + start_offset; + lldb_private::Address so_addr; + bool data_from_file = true; + if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { + data_from_file = false; + } else { + if (target_sp->GetSectionLoadList().IsEmpty() || + !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) + so_addr.SetRawAddress(addr); + } + + size_t bytes_consumed = disassembler_sp->DecodeInstructions( + so_addr, DE, start_offset, item_count, false, data_from_file); + + if (bytes_consumed) { + offset += bytes_consumed; + const bool show_address = base_addr != LLDB_INVALID_ADDRESS; + const bool show_bytes = true; + ExecutionContext exe_ctx; + exe_scope->CalculateExecutionContext(exe_ctx); + disassembler_sp->GetInstructionList().Dump(s, show_address, + show_bytes, &exe_ctx); + } + } + } else + s->Printf("invalid target"); + + return offset; + } + + if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && + item_byte_size > 8) + item_format = eFormatHex; + + lldb::offset_t line_start_offset = start_offset; + for (uint32_t count = 0; DE.ValidOffset(offset) && count < item_count; + ++count) { + if ((count % num_per_line) == 0) { + if (count > 0) { + if (item_format == eFormatBytesWithASCII && + offset > line_start_offset) { + s->Printf("%*s", + static_cast<int>( + (num_per_line - (offset - line_start_offset)) * 3 + 2), + ""); + DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, + offset - line_start_offset, SIZE_MAX, + LLDB_INVALID_ADDRESS, 0, 0); + } + s->EOL(); + } + if (base_addr != LLDB_INVALID_ADDRESS) + s->Printf("0x%8.8" PRIx64 ": ", + (uint64_t)(base_addr + + (offset - start_offset) / DE.getTargetByteSize())); + + line_start_offset = offset; + } else if (item_format != eFormatChar && + item_format != eFormatCharPrintable && + item_format != eFormatCharArray && count > 0) { + s->PutChar(' '); + } + + switch (item_format) { + case eFormatBoolean: + if (item_byte_size <= 8) + s->Printf("%s", DE.GetMaxU64Bitfield(&offset, item_byte_size, + item_bit_size, item_bit_offset) + ? "true" + : "false"); + else { + s->Printf("error: unsupported byte size (%" PRIu64 + ") for boolean format", + (uint64_t)item_byte_size); + return offset; + } + break; + + case eFormatBinary: + if (item_byte_size <= 8) { + uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, + item_bit_size, item_bit_offset); + // Avoid std::bitset<64>::to_string() since it is missing in + // earlier C++ libraries + std::string binary_value(64, '0'); + std::bitset<64> bits(uval64); + for (uint32_t i = 0; i < 64; ++i) + if (bits[i]) + binary_value[64 - 1 - i] = '1'; + if (item_bit_size > 0) + s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size); + else if (item_byte_size > 0 && item_byte_size <= 8) + s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8); + } else { + const bool is_signed = false; + const unsigned radix = 2; + offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); + } + break; + + case eFormatBytes: + case eFormatBytesWithASCII: + for (uint32_t i = 0; i < item_byte_size; ++i) { + s->Printf("%2.2x", DE.GetU8(&offset)); + } + + // Put an extra space between the groups of bytes if more than one + // is being dumped in a group (item_byte_size is more than 1). + if (item_byte_size > 1) + s->PutChar(' '); + break; + + case eFormatChar: + case eFormatCharPrintable: + case eFormatCharArray: { + // If we are only printing one character surround it with single + // quotes + if (item_count == 1 && item_format == eFormatChar) + s->PutChar('\''); + + const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, + item_bit_size, item_bit_offset); + if (isprint(ch)) + s->Printf("%c", (char)ch); + else if (item_format != eFormatCharPrintable) { + switch (ch) { + case '\033': + s->Printf("\\e"); + break; + case '\a': + s->Printf("\\a"); + break; + case '\b': + s->Printf("\\b"); + break; + case '\f': + s->Printf("\\f"); + break; + case '\n': + s->Printf("\\n"); + break; + case '\r': + s->Printf("\\r"); + break; + case '\t': + s->Printf("\\t"); + break; + case '\v': + s->Printf("\\v"); + break; + case '\0': + s->Printf("\\0"); + break; + default: + if (item_byte_size == 1) + s->Printf("\\x%2.2x", (uint8_t)ch); + else + s->Printf("%" PRIu64, ch); + break; + } + } else { + s->PutChar(NON_PRINTABLE_CHAR); + } + + // If we are only printing one character surround it with single quotes + if (item_count == 1 && item_format == eFormatChar) + s->PutChar('\''); + } break; + + case eFormatEnum: // Print enum value as a signed integer when we don't get + // the enum type + case eFormatDecimal: + if (item_byte_size <= 8) + s->Printf("%" PRId64, + DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset)); + else { + const bool is_signed = true; + const unsigned radix = 10; + offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); + } + break; + + case eFormatUnsigned: + if (item_byte_size <= 8) + s->Printf("%" PRIu64, + DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset)); + else { + const bool is_signed = false; + const unsigned radix = 10; + offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); + } + break; + + case eFormatOctal: + if (item_byte_size <= 8) + s->Printf("0%" PRIo64, + DE.GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset)); + else { + const bool is_signed = false; + const unsigned radix = 8; + offset = DumpAPInt(s, DE, offset, item_byte_size, is_signed, radix); + } + break; + + case eFormatOSType: { + uint64_t uval64 = DE.GetMaxU64Bitfield(&offset, item_byte_size, + item_bit_size, item_bit_offset); + s->PutChar('\''); + for (uint32_t i = 0; i < item_byte_size; ++i) { + uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); + if (isprint(ch)) + s->Printf("%c", ch); + else { + switch (ch) { + case '\033': + s->Printf("\\e"); + break; + case '\a': + s->Printf("\\a"); + break; + case '\b': + s->Printf("\\b"); + break; + case '\f': + s->Printf("\\f"); + break; + case '\n': + s->Printf("\\n"); + break; + case '\r': + s->Printf("\\r"); + break; + case '\t': + s->Printf("\\t"); + break; + case '\v': + s->Printf("\\v"); + break; + case '\0': + s->Printf("\\0"); + break; + default: + s->Printf("\\x%2.2x", ch); + break; + } + } + } + s->PutChar('\''); + } break; + + case eFormatCString: { + const char *cstr = DE.GetCStr(&offset); + + if (!cstr) { + s->Printf("NULL"); + offset = LLDB_INVALID_OFFSET; + } else { + s->PutChar('\"'); + + while (const char c = *cstr) { + if (isprint(c)) { + s->PutChar(c); + } else { + switch (c) { + case '\033': + s->Printf("\\e"); + break; + case '\a': + s->Printf("\\a"); + break; + case '\b': + s->Printf("\\b"); + break; + case '\f': + s->Printf("\\f"); + break; + case '\n': + s->Printf("\\n"); + break; + case '\r': + s->Printf("\\r"); + break; + case '\t': + s->Printf("\\t"); + break; + case '\v': + s->Printf("\\v"); + break; + default: + s->Printf("\\x%2.2x", c); + break; + } + } + + ++cstr; + } + + s->PutChar('\"'); + } + } break; + + case eFormatPointer: + s->Address(DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset), + sizeof(addr_t)); + break; + + case eFormatComplexInteger: { + size_t complex_int_byte_size = item_byte_size / 2; + + if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) { + s->Printf("%" PRIu64, + DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); + s->Printf(" + %" PRIu64 "i", + DE.GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0)); + } else { + s->Printf("error: unsupported byte size (%" PRIu64 + ") for complex integer format", + (uint64_t)item_byte_size); + return offset; + } + } break; + + case eFormatComplex: + if (sizeof(float) * 2 == item_byte_size) { + float f32_1 = DE.GetFloat(&offset); + float f32_2 = DE.GetFloat(&offset); + + s->Printf("%g + %gi", f32_1, f32_2); + break; + } else if (sizeof(double) * 2 == item_byte_size) { + double d64_1 = DE.GetDouble(&offset); + double d64_2 = DE.GetDouble(&offset); + + s->Printf("%lg + %lgi", d64_1, d64_2); + break; + } else if (sizeof(long double) * 2 == item_byte_size) { + long double ld64_1 = DE.GetLongDouble(&offset); + long double ld64_2 = DE.GetLongDouble(&offset); + s->Printf("%Lg + %Lgi", ld64_1, ld64_2); + break; + } else { + s->Printf("error: unsupported byte size (%" PRIu64 + ") for complex float format", + (uint64_t)item_byte_size); + return offset; + } + break; + + default: + case eFormatDefault: + case eFormatHex: + case eFormatHexUppercase: { + bool wantsuppercase = (item_format == eFormatHexUppercase); + switch (item_byte_size) { + case 1: + case 2: + case 4: + case 8: + s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, + (int)(2 * item_byte_size), (int)(2 * item_byte_size), + DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset)); + break; + default: { + assert(item_bit_size == 0 && item_bit_offset == 0); + const uint8_t *bytes = + (const uint8_t *)DE.GetData(&offset, item_byte_size); + if (bytes) { + s->PutCString("0x"); + uint32_t idx; + if (DE.GetByteOrder() == eByteOrderBig) { + for (idx = 0; idx < item_byte_size; ++idx) + s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]); + } else { + for (idx = 0; idx < item_byte_size; ++idx) + s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", + bytes[item_byte_size - 1 - idx]); + } + } + } break; + } + } break; + + case eFormatFloat: { + TargetSP target_sp; + bool used_apfloat = false; + if (exe_scope) + target_sp = exe_scope->CalculateTarget(); + if (target_sp) { + ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); + if (clang_ast) { + clang::ASTContext *ast = clang_ast->getASTContext(); + if (ast) { + llvm::SmallVector<char, 256> sv; + // Show full precision when printing float values + const unsigned format_precision = 0; + const unsigned format_max_padding = 100; + size_t item_bit_size = item_byte_size * 8; + + if (item_bit_size == ast->getTypeSize(ast->FloatTy)) { + llvm::APInt apint(item_bit_size, + DE.GetMaxU64(&offset, item_byte_size)); + llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy), + apint); + apfloat.toString(sv, format_precision, format_max_padding); + } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) { + llvm::APInt apint; + if (GetAPInt(DE, &offset, item_byte_size, apint)) { + llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy), + apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) { + const auto &semantics = + ast->getFloatTypeSemantics(ast->LongDoubleTy); + const auto byte_size = + (llvm::APFloat::getSizeInBits(semantics) + 7) / 8; + + llvm::APInt apint; + if (GetAPInt(DE, &offset, byte_size, apint)) { + llvm::APFloat apfloat(semantics, apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) { + llvm::APInt apint(item_bit_size, DE.GetU16(&offset)); + llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy), + apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + + if (!sv.empty()) { + s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); + used_apfloat = true; + } + } + } + } + + if (!used_apfloat) { + std::ostringstream ss; + if (item_byte_size == sizeof(float) || item_byte_size == 2) { + float f; + if (item_byte_size == 2) { + uint16_t half = DE.GetU16(&offset); + f = half2float(half); + } else { + f = DE.GetFloat(&offset); + } + ss.precision(std::numeric_limits<float>::digits10); + ss << f; + } else if (item_byte_size == sizeof(double)) { + ss.precision(std::numeric_limits<double>::digits10); + ss << DE.GetDouble(&offset); + } else if (item_byte_size == sizeof(long double) || + item_byte_size == 10) { + ss.precision(std::numeric_limits<long double>::digits10); + ss << DE.GetLongDouble(&offset); + } else { + s->Printf("error: unsupported byte size (%" PRIu64 + ") for float format", + (uint64_t)item_byte_size); + return offset; + } + ss.flush(); + s->Printf("%s", ss.str().c_str()); + } + } break; + + case eFormatUnicode16: + s->Printf("U+%4.4x", DE.GetU16(&offset)); + break; + + case eFormatUnicode32: + s->Printf("U+0x%8.8x", DE.GetU32(&offset)); + break; + + case eFormatAddressInfo: { + addr_t addr = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, + item_bit_offset); + s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), + (int)(2 * item_byte_size), addr); + if (exe_scope) { + TargetSP target_sp(exe_scope->CalculateTarget()); + lldb_private::Address so_addr; + if (target_sp) { + if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, + so_addr)) { + s->PutChar(' '); + so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription, + Address::DumpStyleModuleWithFileAddress); + } else { + so_addr.SetOffset(addr); + so_addr.Dump(s, exe_scope, + Address::DumpStyleResolvedPointerDescription); + } + } + } + } break; + + case eFormatHexFloat: + if (sizeof(float) == item_byte_size) { + char float_cstr[256]; + llvm::APFloat ap_float(DE.GetFloat(&offset)); + ap_float.convertToHexString(float_cstr, 0, false, + llvm::APFloat::rmNearestTiesToEven); + s->Printf("%s", float_cstr); + break; + } else if (sizeof(double) == item_byte_size) { + char float_cstr[256]; + llvm::APFloat ap_float(DE.GetDouble(&offset)); + ap_float.convertToHexString(float_cstr, 0, false, + llvm::APFloat::rmNearestTiesToEven); + s->Printf("%s", float_cstr); + break; + } else { + s->Printf("error: unsupported byte size (%" PRIu64 + ") for hex float format", + (uint64_t)item_byte_size); + return offset; + } + break; + + // please keep the single-item formats below in sync with + // FormatManager::GetSingleItemFormat + // if you fail to do so, users will start getting different outputs + // depending on internal + // implementation details they should not care about || + case eFormatVectorOfChar: // || + s->PutChar('{'); // \/ + offset = + DumpDataExtractor(DE, s, offset, eFormatCharArray, 1, item_byte_size, + item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfSInt8: + s->PutChar('{'); + offset = + DumpDataExtractor(DE, s, offset, eFormatDecimal, 1, item_byte_size, + item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfUInt8: + s->PutChar('{'); + offset = DumpDataExtractor(DE, s, offset, eFormatHex, 1, item_byte_size, + item_byte_size, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfSInt16: + s->PutChar('{'); + offset = DumpDataExtractor( + DE, s, offset, eFormatDecimal, sizeof(uint16_t), + item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfUInt16: + s->PutChar('{'); + offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint16_t), + item_byte_size / sizeof(uint16_t), + item_byte_size / sizeof(uint16_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfSInt32: + s->PutChar('{'); + offset = DumpDataExtractor( + DE, s, offset, eFormatDecimal, sizeof(uint32_t), + item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfUInt32: + s->PutChar('{'); + offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint32_t), + item_byte_size / sizeof(uint32_t), + item_byte_size / sizeof(uint32_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfSInt64: + s->PutChar('{'); + offset = DumpDataExtractor( + DE, s, offset, eFormatDecimal, sizeof(uint64_t), + item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfUInt64: + s->PutChar('{'); + offset = DumpDataExtractor(DE, s, offset, eFormatHex, sizeof(uint64_t), + item_byte_size / sizeof(uint64_t), + item_byte_size / sizeof(uint64_t), + LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfFloat16: + s->PutChar('{'); + offset = + DumpDataExtractor(DE, s, offset, eFormatFloat, 2, item_byte_size / 2, + item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfFloat32: + s->PutChar('{'); + offset = + DumpDataExtractor(DE, s, offset, eFormatFloat, 4, item_byte_size / 4, + item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfFloat64: + s->PutChar('{'); + offset = + DumpDataExtractor(DE, s, offset, eFormatFloat, 8, item_byte_size / 8, + item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + + case eFormatVectorOfUInt128: + s->PutChar('{'); + offset = + DumpDataExtractor(DE, s, offset, eFormatHex, 16, item_byte_size / 16, + item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + } + } + + if (item_format == eFormatBytesWithASCII && offset > line_start_offset) { + s->Printf("%*s", static_cast<int>( + (num_per_line - (offset - line_start_offset)) * 3 + 2), + ""); + DumpDataExtractor(DE, s, line_start_offset, eFormatCharPrintable, 1, + offset - line_start_offset, SIZE_MAX, + LLDB_INVALID_ADDRESS, 0, 0); + } + return offset; // Return the offset at which we ended up +} + +void lldb_private::DumpHexBytes(Stream *s, const void *src, size_t src_len, + uint32_t bytes_per_line, + lldb::addr_t base_addr) { + DataExtractor data(src, src_len, lldb::eByteOrderLittle, 4); + DumpDataExtractor(data, s, + 0, // Offset into "src" + lldb::eFormatBytes, // Dump as hex bytes + 1, // Size of each item is 1 for single bytes + src_len, // Number of bytes + bytes_per_line, // Num bytes per line + base_addr, // Base address + 0, 0); // Bitfield info +} diff --git a/source/Core/DynamicLoader.cpp b/source/Core/DynamicLoader.cpp index 69c5ea30dad2..03fad244acfc 100644 --- a/source/Core/DynamicLoader.cpp +++ b/source/Core/DynamicLoader.cpp @@ -7,19 +7,25 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/DynamicLoader.h" + #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Symbol/ObjectFile.h" // for ObjectFile #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/lldb-private.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/lldb-private-interfaces.h" // for DynamicLoaderCreateInstance + +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <memory> // for shared_ptr, unique_ptr + +#include <assert.h> // for assert using namespace lldb; using namespace lldb_private; @@ -78,7 +84,7 @@ ModuleSP DynamicLoader::GetTargetExecutable() { if (executable->GetFileSpec().Exists()) { ModuleSpec module_spec(executable->GetFileSpec(), executable->GetArchitecture()); - ModuleSP module_sp(new Module(module_spec)); + auto module_sp = std::make_shared<Module>(module_spec); // Check if the executable has changed and set it to the target executable // if they differ. @@ -189,7 +195,8 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, MemoryRegionInfo memory_info; Error error = m_process->GetMemoryRegionInfo(base_addr, memory_info); if (error.Success() && memory_info.GetMapped() && - memory_info.GetRange().GetRangeBase() == base_addr) { + memory_info.GetRange().GetRangeBase() == base_addr && + !(memory_info.GetName().IsEmpty())) { ModuleSpec new_module_spec( FileSpec(memory_info.GetName().AsCString(), false), target.GetArchitecture()); @@ -233,3 +240,10 @@ addr_t DynamicLoader::ReadPointer(addr_t addr) { else return value; } + +void DynamicLoader::LoadOperatingSystemPlugin(bool flush) +{ + if (m_process) + m_process->LoadOperatingSystemPlugin(flush); +} + diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp index bc32fb2f35eb..f18a4af67ef9 100644 --- a/source/Core/EmulateInstruction.cpp +++ b/source/Core/EmulateInstruction.cpp @@ -9,25 +9,33 @@ #include "lldb/Core/EmulateInstruction.h" -// C Includes -// C++ Includes -#include <cstring> - -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Error.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Endian.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Target/StackFrame.h" // for StackFrame +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" // for Stream, Stream::::eBinary +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-forward.h" // for ProcessSP +#include "lldb/lldb-private-interfaces.h" // for EmulateInstructionCreateIn... + +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <cstring> +#include <memory> // for shared_ptr + +#include <inttypes.h> // for PRIx64, PRId64, PRIu64 +#include <stdio.h> // for stdout + +namespace lldb_private { +class Target; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/Error.cpp b/source/Core/Error.cpp deleted file mode 100644 index 23696127d3b4..000000000000 --- a/source/Core/Error.cpp +++ /dev/null @@ -1,336 +0,0 @@ -//===-- Error.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 -#ifdef __APPLE__ -#include <mach/mach.h> -#endif - -// C++ Includes -#include <cerrno> -#include <cstdarg> - -// Other libraries and framework includes -#include "llvm/ADT/SmallVector.h" - -// Project includes -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Host/PosixApi.h" - -using namespace lldb; -using namespace lldb_private; - -Error::Error() : m_code(0), m_type(eErrorTypeInvalid), m_string() {} - -Error::Error(ValueType err, ErrorType type) - : m_code(err), m_type(type), m_string() {} - -Error::Error(const Error &rhs) = default; - -Error::Error(const char *format, ...) - : m_code(0), m_type(eErrorTypeInvalid), m_string() { - va_list args; - va_start(args, format); - SetErrorToGenericError(); - SetErrorStringWithVarArg(format, args); - va_end(args); -} - -//---------------------------------------------------------------------- -// Assignment operator -//---------------------------------------------------------------------- -const Error &Error::operator=(const Error &rhs) { - if (this != &rhs) { - m_code = rhs.m_code; - m_type = rhs.m_type; - m_string = rhs.m_string; - } - return *this; -} - -//---------------------------------------------------------------------- -// Assignment operator -//---------------------------------------------------------------------- -const Error &Error::operator=(uint32_t err) { - m_code = err; - m_type = eErrorTypeMachKernel; - m_string.clear(); - return *this; -} - -Error::~Error() = default; - -//---------------------------------------------------------------------- -// Get the error value as a NULL C string. The error string will be -// fetched and cached on demand. The cached error string value will -// remain until the error value is changed or cleared. -//---------------------------------------------------------------------- -const char *Error::AsCString(const char *default_error_str) const { - if (Success()) - return nullptr; - - if (m_string.empty()) { - const char *s = nullptr; - switch (m_type) { - case eErrorTypeMachKernel: -#if defined(__APPLE__) - s = ::mach_error_string(m_code); -#endif - break; - - case eErrorTypePOSIX: - s = ::strerror(m_code); - break; - - default: - break; - } - if (s != nullptr) - m_string.assign(s); - } - if (m_string.empty()) { - if (default_error_str) - m_string.assign(default_error_str); - else - return nullptr; // User wanted a nullptr string back... - } - return m_string.c_str(); -} - -//---------------------------------------------------------------------- -// Clear the error and any cached error string that it might contain. -//---------------------------------------------------------------------- -void Error::Clear() { - m_code = 0; - m_type = eErrorTypeInvalid; - m_string.clear(); -} - -//---------------------------------------------------------------------- -// Access the error value. -//---------------------------------------------------------------------- -Error::ValueType Error::GetError() const { return m_code; } - -//---------------------------------------------------------------------- -// Access the error type. -//---------------------------------------------------------------------- -ErrorType Error::GetType() const { return m_type; } - -//---------------------------------------------------------------------- -// Returns true if this object contains a value that describes an -// error or otherwise non-success result. -//---------------------------------------------------------------------- -bool Error::Fail() const { return m_code != 0; } - -//---------------------------------------------------------------------- -// Log the error given a string with format. If the this object -// contains an error code, update the error string to contain the -// "error: " followed by the formatted string, followed by the error -// value and any string that describes the current error. This -// allows more context to be given to an error string that remains -// cached in this object. Logging always occurs even when the error -// code contains a non-error value. -//---------------------------------------------------------------------- -void Error::PutToLog(Log *log, const char *format, ...) { - char *arg_msg = nullptr; - va_list args; - va_start(args, format); - ::vasprintf(&arg_msg, format, args); - va_end(args); - - if (arg_msg != nullptr) { - if (Fail()) { - const char *err_str = AsCString(); - if (err_str == nullptr) - err_str = "???"; - - SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, - m_code); - if (log != nullptr) - log->Error("%s", m_string.c_str()); - } else { - if (log != nullptr) - log->Printf("%s err = 0x%8.8x", arg_msg, m_code); - } - ::free(arg_msg); - } -} - -//---------------------------------------------------------------------- -// Log the error given a string with format. If the this object -// contains an error code, update the error string to contain the -// "error: " followed by the formatted string, followed by the error -// value and any string that describes the current error. This -// allows more context to be given to an error string that remains -// cached in this object. Logging only occurs even when the error -// code contains a error value. -//---------------------------------------------------------------------- -void Error::LogIfError(Log *log, const char *format, ...) { - if (Fail()) { - char *arg_msg = nullptr; - va_list args; - va_start(args, format); - ::vasprintf(&arg_msg, format, args); - va_end(args); - - if (arg_msg != nullptr) { - const char *err_str = AsCString(); - if (err_str == nullptr) - err_str = "???"; - - SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, - m_code); - if (log != nullptr) - log->Error("%s", m_string.c_str()); - - ::free(arg_msg); - } - } -} - -//---------------------------------------------------------------------- -// Set accesssor for the error value to "err" and the type to -// "eErrorTypeMachKernel" -//---------------------------------------------------------------------- -void Error::SetMachError(uint32_t err) { - m_code = err; - m_type = eErrorTypeMachKernel; - m_string.clear(); -} - -void Error::SetExpressionError(lldb::ExpressionResults result, - const char *mssg) { - m_code = result; - m_type = eErrorTypeExpression; - m_string = mssg; -} - -int Error::SetExpressionErrorWithFormat(lldb::ExpressionResults result, - const char *format, ...) { - int length = 0; - - if (format != nullptr && format[0]) { - va_list args; - va_start(args, format); - length = SetErrorStringWithVarArg(format, args); - va_end(args); - } else { - m_string.clear(); - } - m_code = result; - m_type = eErrorTypeExpression; - return length; -} - -//---------------------------------------------------------------------- -// Set accesssor for the error value and type. -//---------------------------------------------------------------------- -void Error::SetError(ValueType err, ErrorType type) { - m_code = err; - m_type = type; - m_string.clear(); -} - -//---------------------------------------------------------------------- -// Update the error value to be "errno" and update the type to -// be "POSIX". -//---------------------------------------------------------------------- -void Error::SetErrorToErrno() { - m_code = errno; - m_type = eErrorTypePOSIX; - m_string.clear(); -} - -//---------------------------------------------------------------------- -// Update the error value to be LLDB_GENERIC_ERROR and update the type -// to be "Generic". -//---------------------------------------------------------------------- -void Error::SetErrorToGenericError() { - m_code = LLDB_GENERIC_ERROR; - m_type = eErrorTypeGeneric; - m_string.clear(); -} - -//---------------------------------------------------------------------- -// Set accessor for the error string value for a specific error. -// This allows any string to be supplied as an error explanation. -// The error string value will remain until the error value is -// cleared or a new error value/type is assigned. -//---------------------------------------------------------------------- -void Error::SetErrorString(llvm::StringRef err_str) { - if (!err_str.empty()) { - // If we have an error string, we should always at least have an error - // set to a generic value. - if (Success()) - SetErrorToGenericError(); - } - m_string = err_str; -} - -//------------------------------------------------------------------ -/// Set the current error string to a formatted error string. -/// -/// @param format -/// A printf style format string -//------------------------------------------------------------------ -int Error::SetErrorStringWithFormat(const char *format, ...) { - if (format != nullptr && format[0]) { - va_list args; - va_start(args, format); - int length = SetErrorStringWithVarArg(format, args); - va_end(args); - return length; - } else { - m_string.clear(); - } - return 0; -} - -int Error::SetErrorStringWithVarArg(const char *format, va_list args) { - if (format != nullptr && format[0]) { - // If we have an error string, we should always at least have - // an error set to a generic value. - if (Success()) - SetErrorToGenericError(); - - // Try and fit our error into a 1024 byte buffer first... - llvm::SmallVector<char, 1024> buf; - buf.resize(1024); - // Copy in case our first call to vsnprintf doesn't fit into our - // allocated buffer above - va_list copy_args; - va_copy(copy_args, args); - unsigned length = ::vsnprintf(buf.data(), buf.size(), format, args); - if (length >= buf.size()) { - // The error formatted string didn't fit into our buffer, resize it - // to the exact needed size, and retry - buf.resize(length + 1); - length = ::vsnprintf(buf.data(), buf.size(), format, copy_args); - va_end(copy_args); - assert(length < buf.size()); - } - m_string.assign(buf.data(), length); - va_end(args); - return length; - } else { - m_string.clear(); - } - return 0; -} - -//---------------------------------------------------------------------- -// Returns true if the error code in this object is considered a -// successful return value. -//---------------------------------------------------------------------- -bool Error::Success() const { return m_code == 0; } - -bool Error::WasInterrupted() const { - return (m_type == eErrorTypePOSIX && m_code == EINTR); -} diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp index bd57198f5487..8d351d8ba1a5 100644 --- a/source/Core/Event.cpp +++ b/source/Core/Event.cpp @@ -7,20 +7,19 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -#include <algorithm> +#include "lldb/Core/Event.h" -// Other libraries and framework includes -// Project includes #include "lldb/Core/Broadcaster.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Event.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/State.h" -#include "lldb/Core/Stream.h" -#include "lldb/Host/Endian.h" -#include "lldb/Target/Process.h" +#include "lldb/Core/DumpDataExtractor.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" // for StreamString +#include "lldb/lldb-enumerations.h" // for Format::eFormatBytes + +#include <algorithm> + +#include <ctype.h> // for isprint using namespace lldb; using namespace lldb_private; @@ -140,8 +139,8 @@ void EventDataBytes::Dump(Stream *s) const { } else if (!m_bytes.empty()) { DataExtractor data; data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder()); - data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS, - 0, 0); + DumpDataExtractor(data, s, 0, eFormatBytes, 1, m_bytes.size(), 32, + LLDB_INVALID_ADDRESS, 0, 0); } } diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp deleted file mode 100644 index 0bed4a1f20ad..000000000000 --- a/source/Core/FastDemangle.cpp +++ /dev/null @@ -1,2396 +0,0 @@ -//===-- FastDemangle.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <functional> - -#include "lldb/Core/FastDemangle.h" -#include "lldb/lldb-private.h" - -//#define DEBUG_FAILURES 1 -//#define DEBUG_SUBSTITUTIONS 1 -//#define DEBUG_TEMPLATE_ARGS 1 -//#define DEBUG_HIGHWATER 1 -//#define DEBUG_REORDERING 1 - -namespace { - -/// @brief Represents the collection of qualifiers on a type - -enum Qualifiers { - QualifierNone = 0, - QualifierConst = 1, - QualifierRestrict = 2, - QualifierVolatile = 4, - QualifierReference = 8, - QualifierRValueReference = 16, - QualifierPointer = 32 -}; - -/// @brief Categorizes the recognized operators - -enum class OperatorKind { - Unary, - Postfix, - Binary, - Ternary, - Other, - ConversionOperator, - Vendor, - NoMatch -}; - -/// @brief Represents one of the recognized two-character operator -/// abbreviations used when parsing operators as names and expressions - -struct Operator { - const char *name; - OperatorKind kind; -}; - -/// @brief Represents a range of characters in the output buffer, typically for -/// use with RewriteRange() - -struct BufferRange { - int offset; - int length; -}; - -/// @brief Transient state required while parsing a name - -struct NameState { - bool parse_function_params; - bool is_last_generic; - bool has_no_return_type; - BufferRange last_name_range; -}; - -/// @brief LLDB's fast C++ demangler -/// -/// This is an incomplete implementation designed to speed up the demangling -/// process that is often a bottleneck when LLDB stops a process for the first -/// time. Where the implementation doesn't know how to demangle a symbol it -/// fails gracefully to allow the caller to fall back to the existing demangler. -/// -/// Over time the full mangling spec should be supported without compromising -/// performance for the most common cases. - -class SymbolDemangler { -public: - //---------------------------------------------------- - // Public API - //---------------------------------------------------- - - /// @brief Create a SymbolDemangler - /// - /// The newly created demangler allocates and owns scratch memory sufficient - /// for demangling typical symbols. Additional memory will be allocated if - /// needed and managed by the demangler instance. - - SymbolDemangler() { - m_buffer = (char *)malloc(8192); - m_buffer_end = m_buffer + 8192; - m_owns_buffer = true; - - m_rewrite_ranges = (BufferRange *)malloc(128 * sizeof(BufferRange)); - m_rewrite_ranges_size = 128; - m_owns_m_rewrite_ranges = true; - } - - /// @brief Create a SymbolDemangler that uses provided scratch memory - /// - /// The provided memory is not owned by the demangler. It will be - /// overwritten during calls to GetDemangledCopy() but can be used for - /// other purposes between calls. The provided memory will not be freed - /// when this instance is destroyed. - /// - /// If demangling a symbol requires additional space it will be allocated - /// and managed by the demangler instance. - /// - /// @param storage_ptr Valid pointer to at least storage_size bytes of - /// space that the SymbolDemangler can use during demangling - /// - /// @param storage_size Number of bytes of space available scratch memory - /// referenced by storage_ptr - - SymbolDemangler(void *storage_ptr, size_t storage_size, - std::function<void(const char *)> builtins_hook = nullptr) - : m_builtins_hook(builtins_hook) { - // Use up to 1/8th of the provided space for rewrite ranges - m_rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange); - m_rewrite_ranges = (BufferRange *)storage_ptr; - m_owns_m_rewrite_ranges = false; - - // Use the rest for the character buffer - m_buffer = - (char *)storage_ptr + m_rewrite_ranges_size * sizeof(BufferRange); - m_buffer_end = (const char *)storage_ptr + storage_size; - m_owns_buffer = false; - } - - /// @brief Destroys the SymbolDemangler and deallocates any scratch - /// memory that it owns - - ~SymbolDemangler() { - if (m_owns_buffer) - free(m_buffer); - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - } - -#ifdef DEBUG_HIGHWATER - int highwater_store = 0; - int highwater_buffer = 0; -#endif - - /// @brief Parses the provided mangled name and returns a newly allocated - /// demangling - /// - /// @param mangled_name Valid null-terminated C++ mangled name following - /// the Itanium C++ ABI mangling specification as implemented by Clang - /// - /// @result Newly allocated null-terminated demangled name when demangling - /// is successful, and nullptr when demangling fails. The caller is - /// responsible for freeing the allocated memory. - - char *GetDemangledCopy(const char *mangled_name, - long mangled_name_length = 0) { - if (!ParseMangling(mangled_name, mangled_name_length)) - return nullptr; - -#ifdef DEBUG_HIGHWATER - int rewrite_count = m_next_substitute_index + - (m_rewrite_ranges_size - 1 - m_next_template_arg_index); - int buffer_size = (int)(m_write_ptr - m_buffer); - if (rewrite_count > highwater_store) - highwater_store = rewrite_count; - if (buffer_size > highwater_buffer) - highwater_buffer = buffer_size; -#endif - - int length = (int)(m_write_ptr - m_buffer); - char *copy = (char *)malloc(length + 1); - memcpy(copy, m_buffer, length); - copy[length] = '\0'; - return copy; - } - -private: - //---------------------------------------------------- - // Grow methods - // - // Manage the storage used during demangling - //---------------------------------------------------- - - void GrowBuffer(long min_growth = 0) { - // By default, double the size of the buffer - long growth = m_buffer_end - m_buffer; - - // Avoid growing by more than 1MB at a time - if (growth > 1 << 20) - growth = 1 << 20; - - // ... but never grow by less than requested, - // or 1K, whichever is greater - if (min_growth < 1024) - min_growth = 1024; - if (growth < min_growth) - growth = min_growth; - - // Allocate the new m_buffer and migrate content - long new_size = (m_buffer_end - m_buffer) + growth; - char *new_buffer = (char *)malloc(new_size); - memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer); - if (m_owns_buffer) - free(m_buffer); - m_owns_buffer = true; - - // Update references to the new buffer - m_write_ptr = new_buffer + (m_write_ptr - m_buffer); - m_buffer = new_buffer; - m_buffer_end = m_buffer + new_size; - } - - void GrowRewriteRanges() { - // By default, double the size of the array - int growth = m_rewrite_ranges_size; - - // Apply reasonable minimum and maximum sizes for growth - if (growth > 128) - growth = 128; - if (growth < 16) - growth = 16; - - // Allocate the new array and migrate content - int bytes = (m_rewrite_ranges_size + growth) * sizeof(BufferRange); - BufferRange *new_ranges = (BufferRange *)malloc(bytes); - for (int index = 0; index < m_next_substitute_index; index++) { - new_ranges[index] = m_rewrite_ranges[index]; - } - for (int index = m_rewrite_ranges_size - 1; - index > m_next_template_arg_index; index--) { - new_ranges[index + growth] = m_rewrite_ranges[index]; - } - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - m_owns_m_rewrite_ranges = true; - - // Update references to the new array - m_rewrite_ranges = new_ranges; - m_rewrite_ranges_size += growth; - m_next_template_arg_index += growth; - } - - //---------------------------------------------------- - // Range and state management - //---------------------------------------------------- - - int GetStartCookie() { return (int)(m_write_ptr - m_buffer); } - - BufferRange EndRange(int start_cookie) { - return {start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie))}; - } - - void ReorderRange(BufferRange source_range, int insertion_point_cookie) { - // Ensure there's room the preserve the source range - if (m_write_ptr + source_range.length > m_buffer_end) { - GrowBuffer(m_write_ptr + source_range.length - m_buffer_end); - } - - // Reorder the content - memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length); - memmove(m_buffer + insertion_point_cookie + source_range.length, - m_buffer + insertion_point_cookie, - source_range.offset - insertion_point_cookie); - memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length); - - // Fix up rewritable ranges, covering both substitutions and templates - int index = 0; - while (true) { - if (index == m_next_substitute_index) - index = m_next_template_arg_index + 1; - if (index == m_rewrite_ranges_size) - break; - - // Affected ranges are either shuffled forward when after the - // insertion but before the source, or backward when inside the - // source - int candidate_offset = m_rewrite_ranges[index].offset; - if (candidate_offset >= insertion_point_cookie) { - if (candidate_offset < source_range.offset) { - m_rewrite_ranges[index].offset += source_range.length; - } else if (candidate_offset >= source_range.offset) { - m_rewrite_ranges[index].offset -= - (source_range.offset - insertion_point_cookie); - } - } - ++index; - } - } - - void EndSubstitution(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_substitute_index++; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_SUBSTITUTIONS - printf("Saved substitution # %d = %.*s\n", index, - m_rewrite_ranges[index].length, m_buffer + start_cookie); -#endif - } - - void EndTemplateArg(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_template_arg_index--; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_TEMPLATE_ARGS - printf("Saved template arg # %d = %.*s\n", - m_rewrite_ranges_size - index - 1, m_rewrite_ranges[index].length, - m_buffer + start_cookie); -#endif - } - - void ResetTemplateArgs() { - // TODO: this works, but is it the right thing to do? - // Should we push/pop somehow at the call sites? - m_next_template_arg_index = m_rewrite_ranges_size - 1; - } - - //---------------------------------------------------- - // Write methods - // - // Appends content to the existing output buffer - //---------------------------------------------------- - - void Write(char character) { - if (m_write_ptr == m_buffer_end) - GrowBuffer(); - *m_write_ptr++ = character; - } - - void Write(const char *content) { Write(content, strlen(content)); } - - void Write(const char *content, long content_length) { - char *end_m_write_ptr = m_write_ptr + content_length; - if (end_m_write_ptr > m_buffer_end) { - if (content >= m_buffer && content < m_buffer_end) { - long offset = content - m_buffer; - GrowBuffer(end_m_write_ptr - m_buffer_end); - content = m_buffer + offset; - } else { - GrowBuffer(end_m_write_ptr - m_buffer_end); - } - end_m_write_ptr = m_write_ptr + content_length; - } - memcpy(m_write_ptr, content, content_length); - m_write_ptr = end_m_write_ptr; - } -#define WRITE(x) Write(x, sizeof(x) - 1) - - void WriteTemplateStart() { Write('<'); } - - void WriteTemplateEnd() { - // Put a space between terminal > characters when nesting templates - if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>') - WRITE(" >"); - else - Write('>'); - } - - void WriteCommaSpace() { WRITE(", "); } - - void WriteNamespaceSeparator() { WRITE("::"); } - - void WriteStdPrefix() { WRITE("std::"); } - - void WriteQualifiers(int qualifiers, bool space_before_reference = true) { - if (qualifiers & QualifierPointer) - Write('*'); - if (qualifiers & QualifierConst) - WRITE(" const"); - if (qualifiers & QualifierVolatile) - WRITE(" volatile"); - if (qualifiers & QualifierRestrict) - WRITE(" restrict"); - if (qualifiers & QualifierReference) { - if (space_before_reference) - WRITE(" &"); - else - Write('&'); - } - if (qualifiers & QualifierRValueReference) { - if (space_before_reference) - WRITE(" &&"); - else - WRITE("&&"); - } - } - - //---------------------------------------------------- - // Rewrite methods - // - // Write another copy of content already present - // earlier in the output buffer - //---------------------------------------------------- - - void RewriteRange(BufferRange range) { - Write(m_buffer + range.offset, range.length); - } - - bool RewriteSubstitution(int index) { - if (index < 0 || index >= m_next_substitute_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid substitution #%d\n", index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - bool RewriteTemplateArg(int template_index) { - int index = m_rewrite_ranges_size - 1 - template_index; - if (template_index < 0 || index <= m_next_template_arg_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid template arg reference #%d\n", template_index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - //---------------------------------------------------- - // TryParse methods - // - // Provide information with return values instead of - // writing to the output buffer - // - // Values indicating failure guarantee that the pre- - // call m_read_ptr is unchanged - //---------------------------------------------------- - - int TryParseNumber() { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - return -1; - - int count = digit; - while (true) { - digit = *++m_read_ptr - '0'; - if (digit > 9) - break; - - count = count * 10 + digit; - } - return count; - } - - int TryParseBase36Number() { - char digit = *m_read_ptr; - int count; - if (digit >= '0' && digit <= '9') - count = digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - count = digit -= ('A' - 10); - else - return -1; - - while (true) { - digit = *++m_read_ptr; - if (digit >= '0' && digit <= '9') - digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - digit -= ('A' - 10); - else - break; - - count = count * 36 + digit; - } - return count; - } - - // <builtin-type> ::= v # void - // ::= w # wchar_t - // ::= b # bool - // ::= c # char - // ::= a # signed char - // ::= h # unsigned char - // ::= s # short - // ::= t # unsigned short - // ::= i # int - // ::= j # unsigned int - // ::= l # long - // ::= m # unsigned long - // ::= x # long long, __int64 - // ::= y # unsigned long long, __int64 - // ::= n # __int128 - // ::= o # unsigned __int128 - // ::= f # float - // ::= d # double - // ::= e # long double, __float80 - // ::= g # __float128 - // ::= z # ellipsis - // ::= Dd # IEEE 754r decimal floating point (64 bits) - // ::= De # IEEE 754r decimal floating point (128 bits) - // ::= Df # IEEE 754r decimal floating point (32 bits) - // ::= Dh # IEEE 754r half-precision floating point (16 bits) - // ::= Di # char32_t - // ::= Ds # char16_t - // ::= Da # auto (in dependent new-expressions) - // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) - // ::= u <source-name> # vendor extended type - - const char *TryParseBuiltinType() { - if (m_builtins_hook) - m_builtins_hook(m_read_ptr); - - switch (*m_read_ptr++) { - case 'v': - return "void"; - case 'w': - return "wchar_t"; - case 'b': - return "bool"; - case 'c': - return "char"; - case 'a': - return "signed char"; - case 'h': - return "unsigned char"; - case 's': - return "short"; - case 't': - return "unsigned short"; - case 'i': - return "int"; - case 'j': - return "unsigned int"; - case 'l': - return "long"; - case 'm': - return "unsigned long"; - case 'x': - return "long long"; - case 'y': - return "unsigned long long"; - case 'n': - return "__int128"; - case 'o': - return "unsigned __int128"; - case 'f': - return "float"; - case 'd': - return "double"; - case 'e': - return "long double"; - case 'g': - return "__float128"; - case 'z': - return "..."; - case 'D': { - switch (*m_read_ptr++) { - case 'd': - return "decimal64"; - case 'e': - return "decimal128"; - case 'f': - return "decimal32"; - case 'h': - return "decimal16"; - case 'i': - return "char32_t"; - case 's': - return "char16_t"; - case 'a': - return "auto"; - case 'c': - return "decltype(auto)"; - case 'n': - return "std::nullptr_t"; - default: - --m_read_ptr; - } - } - } - --m_read_ptr; - return nullptr; - } - - // <operator-name> - // ::= aa # && - // ::= ad # & (unary) - // ::= an # & - // ::= aN # &= - // ::= aS # = - // ::= cl # () - // ::= cm # , - // ::= co # ~ - // ::= da # delete[] - // ::= de # * (unary) - // ::= dl # delete - // ::= dv # / - // ::= dV # /= - // ::= eo # ^ - // ::= eO # ^= - // ::= eq # == - // ::= ge # >= - // ::= gt # > - // ::= ix # [] - // ::= le # <= - // ::= ls # << - // ::= lS # <<= - // ::= lt # < - // ::= mi # - - // ::= mI # -= - // ::= ml # * - // ::= mL # *= - // ::= mm # -- (postfix in <expression> context) - // ::= na # new[] - // ::= ne # != - // ::= ng # - (unary) - // ::= nt # ! - // ::= nw # new - // ::= oo # || - // ::= or # | - // ::= oR # |= - // ::= pm # ->* - // ::= pl # + - // ::= pL # += - // ::= pp # ++ (postfix in <expression> context) - // ::= ps # + (unary) - // ::= pt # -> - // ::= qu # ? - // ::= rm # % - // ::= rM # %= - // ::= rs # >> - // ::= rS # >>= - // ::= cv <type> # (cast) - // ::= v <digit> <source-name> # vendor extended - // operator - - Operator TryParseOperator() { - switch (*m_read_ptr++) { - case 'a': - switch (*m_read_ptr++) { - case 'a': - return {"&&", OperatorKind::Binary}; - case 'd': - return {"&", OperatorKind::Unary}; - case 'n': - return {"&", OperatorKind::Binary}; - case 'N': - return {"&=", OperatorKind::Binary}; - case 'S': - return {"=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'c': - switch (*m_read_ptr++) { - case 'l': - return {"()", OperatorKind::Other}; - case 'm': - return {",", OperatorKind::Other}; - case 'o': - return {"~", OperatorKind::Unary}; - case 'v': - return {nullptr, OperatorKind::ConversionOperator}; - } - --m_read_ptr; - break; - case 'd': - switch (*m_read_ptr++) { - case 'a': - return {" delete[]", OperatorKind::Other}; - case 'e': - return {"*", OperatorKind::Unary}; - case 'l': - return {" delete", OperatorKind::Other}; - case 'v': - return {"/", OperatorKind::Binary}; - case 'V': - return {"/=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'e': - switch (*m_read_ptr++) { - case 'o': - return {"^", OperatorKind::Binary}; - case 'O': - return {"^=", OperatorKind::Binary}; - case 'q': - return {"==", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'g': - switch (*m_read_ptr++) { - case 'e': - return {">=", OperatorKind::Binary}; - case 't': - return {">", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'i': - switch (*m_read_ptr++) { - case 'x': - return {"[]", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'l': - switch (*m_read_ptr++) { - case 'e': - return {"<=", OperatorKind::Binary}; - case 's': - return {"<<", OperatorKind::Binary}; - case 'S': - return {"<<=", OperatorKind::Binary}; - case 't': - return {"<", OperatorKind::Binary}; - // case 'i': return { "?", OperatorKind::Binary }; - } - --m_read_ptr; - break; - case 'm': - switch (*m_read_ptr++) { - case 'i': - return {"-", OperatorKind::Binary}; - case 'I': - return {"-=", OperatorKind::Binary}; - case 'l': - return {"*", OperatorKind::Binary}; - case 'L': - return {"*=", OperatorKind::Binary}; - case 'm': - return {"--", OperatorKind::Postfix}; - } - --m_read_ptr; - break; - case 'n': - switch (*m_read_ptr++) { - case 'a': - return {" new[]", OperatorKind::Other}; - case 'e': - return {"!=", OperatorKind::Binary}; - case 'g': - return {"-", OperatorKind::Unary}; - case 't': - return {"!", OperatorKind::Unary}; - case 'w': - return {" new", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'o': - switch (*m_read_ptr++) { - case 'o': - return {"||", OperatorKind::Binary}; - case 'r': - return {"|", OperatorKind::Binary}; - case 'R': - return {"|=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'p': - switch (*m_read_ptr++) { - case 'm': - return {"->*", OperatorKind::Binary}; - case 's': - return {"+", OperatorKind::Unary}; - case 'l': - return {"+", OperatorKind::Binary}; - case 'L': - return {"+=", OperatorKind::Binary}; - case 'p': - return {"++", OperatorKind::Postfix}; - case 't': - return {"->", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'q': - switch (*m_read_ptr++) { - case 'u': - return {"?", OperatorKind::Ternary}; - } - --m_read_ptr; - break; - case 'r': - switch (*m_read_ptr++) { - case 'm': - return {"%", OperatorKind::Binary}; - case 'M': - return {"%=", OperatorKind::Binary}; - case 's': - return {">>", OperatorKind::Binary}; - case 'S': - return {">=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'v': - char digit = *m_read_ptr; - if (digit >= '0' && digit <= '9') { - m_read_ptr++; - return {nullptr, OperatorKind::Vendor}; - } - --m_read_ptr; - break; - } - --m_read_ptr; - return {nullptr, OperatorKind::NoMatch}; - } - - // <CV-qualifiers> ::= [r] [V] [K] - // <ref-qualifier> ::= R # & ref-qualifier - // <ref-qualifier> ::= O # && ref-qualifier - - int TryParseQualifiers(bool allow_cv, bool allow_ro) { - int qualifiers = QualifierNone; - char next = *m_read_ptr; - if (allow_cv) { - if (next == 'r') // restrict - { - qualifiers |= QualifierRestrict; - next = *++m_read_ptr; - } - if (next == 'V') // volatile - { - qualifiers |= QualifierVolatile; - next = *++m_read_ptr; - } - if (next == 'K') // const - { - qualifiers |= QualifierConst; - next = *++m_read_ptr; - } - } - if (allow_ro) { - if (next == 'R') { - ++m_read_ptr; - qualifiers |= QualifierReference; - } else if (next == 'O') { - ++m_read_ptr; - qualifiers |= QualifierRValueReference; - } - } - return qualifiers; - } - - // <discriminator> := _ <non-negative number> # when number < 10 - // := __ <non-negative number> _ # when number >= 10 - // extension := decimal-digit+ - - int TryParseDiscriminator() { - const char *discriminator_start = m_read_ptr; - - // Test the extension first, since it's what Clang uses - int discriminator_value = TryParseNumber(); - if (discriminator_value != -1) - return discriminator_value; - - char next = *m_read_ptr; - if (next == '_') { - next = *++m_read_ptr; - if (next == '_') { - ++m_read_ptr; - discriminator_value = TryParseNumber(); - if (discriminator_value != -1 && *m_read_ptr++ != '_') { - return discriminator_value; - } - } else if (next >= '0' && next <= '9') { - ++m_read_ptr; - return next - '0'; - } - } - - // Not a valid discriminator - m_read_ptr = discriminator_start; - return -1; - } - - //---------------------------------------------------- - // Parse methods - // - // Consume input starting from m_read_ptr and produce - // buffered output at m_write_ptr - // - // Failures return false and may leave m_read_ptr in an - // indeterminate state - //---------------------------------------------------- - - bool Parse(char character) { - if (*m_read_ptr++ == character) - return true; -#ifdef DEBUG_FAILURES - printf("*** Expected '%c'\n", character); -#endif - return false; - } - - // <number> ::= [n] <non-negative decimal integer> - - bool ParseNumber(bool allow_negative = false) { - if (allow_negative && *m_read_ptr == 'n') { - Write('-'); - ++m_read_ptr; - } - const char *before_digits = m_read_ptr; - while (true) { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - break; - ++m_read_ptr; - } - if (int digit_count = (int)(m_read_ptr - before_digits)) { - Write(before_digits, digit_count); - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Expected number\n"); -#endif - return false; - } - - // <substitution> ::= S <seq-id> _ - // ::= S_ - // <substitution> ::= Sa # ::std::allocator - // <substitution> ::= Sb # ::std::basic_string - // <substitution> ::= Ss # ::std::basic_string < char, - // ::std::char_traits<char>, - // ::std::allocator<char> > - // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> - // > - // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> - // > - // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> - // > - - bool ParseSubstitution() { - const char *substitution; - switch (*m_read_ptr) { - case 'a': - substitution = "std::allocator"; - break; - case 'b': - substitution = "std::basic_string"; - break; - case 's': - substitution = "std::string"; - break; - case 'i': - substitution = "std::istream"; - break; - case 'o': - substitution = "std::ostream"; - break; - case 'd': - substitution = "std::iostream"; - break; - default: - // A failed attempt to parse a number will return -1 which turns out to be - // perfect here as S_ is the first substitution, S0_ the next and so forth - int substitution_index = TryParseBase36Number(); - if (*m_read_ptr++ != '_') { -#ifdef DEBUG_FAILURES - printf("*** Expected terminal _ in substitution\n"); -#endif - return false; - } - return RewriteSubstitution(substitution_index + 1); - } - Write(substitution); - ++m_read_ptr; - return true; - } - - // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E - // - // <bare-function-type> ::= <signature type>+ # types are possible return - // type, then parameter types - - bool ParseFunctionType(int inner_qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Function types not supported\n"); -#endif - // TODO: first steps toward an implementation follow, but they're far - // from complete. Function types tend to bracket other types eg: - // int (*)() when used as the type for "name" becomes int (*name)(). - // This makes substitution et al ... interesting. - return false; - -#if 0 // TODO - if (*m_read_ptr == 'Y') - ++m_read_ptr; - - int return_type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - Write(' '); - - int insert_cookie = GetStartCookie(); - Write('('); - bool first_param = true; - int qualifiers = QualifierNone; - while (true) - { - switch (*m_read_ptr) - { - case 'E': - ++m_read_ptr; - Write(')'); - break; - case 'v': - ++m_read_ptr; - continue; - case 'R': - case 'O': - if (*(m_read_ptr + 1) == 'E') - { - qualifiers = TryParseQualifiers (false, true); - Parse('E'); - break; - } - // fallthrough - default: - { - if (first_param) - first_param = false; - else WriteCommaSpace(); - - if (!ParseType()) - return false; - continue; - } - } - break; - } - - if (qualifiers) - { - WriteQualifiers (qualifiers); - EndSubstitution (return_type_start_cookie); - } - - if (inner_qualifiers) - { - int qualifier_start_cookie = GetStartCookie(); - Write ('('); - WriteQualifiers (inner_qualifiers); - Write (')'); - ReorderRange (EndRange (qualifier_start_cookie), insert_cookie); - } - return true; -#endif // TODO - } - - // <array-type> ::= A <positive dimension number> _ <element type> - // ::= A [<dimension expression>] _ <element type> - - bool ParseArrayType(int qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Array type unsupported\n"); -#endif - // TODO: We fail horribly when recalling these as substitutions or - // templates and trying to constify them eg: - // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_ - // - // TODO: Chances are we don't do any better with references and pointers - // that should be type (&) [] instead of type & [] - - return false; - -#if 0 // TODO - if (*m_read_ptr == '_') - { - ++m_read_ptr; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - WRITE(" []"); - return true; - } - else - { - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - { - const char *after_digits = m_read_ptr; - if (!Parse('_')) - return false; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - Write(before_digits, after_digits - before_digits); - } - else - { - int type_insertion_cookie = GetStartCookie(); - if (!ParseExpression()) - return false; - if (!Parse('_')) - return false; - - int type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - ReorderRange (EndRange (type_start_cookie), type_insertion_cookie); - } - Write(']'); - return true; - } -#endif // TODO - } - - // <pointer-to-member-type> ::= M <class type> <member type> - - // TODO: Determine how to handle pointers to function members correctly, - // currently not an issue because we don't have function types at all... - bool ParsePointerToMemberType() { - int insertion_cookie = GetStartCookie(); - Write(' '); - if (!ParseType()) - return false; - WRITE("::*"); - - int type_cookie = GetStartCookie(); - if (!ParseType()) - return false; - ReorderRange(EndRange(type_cookie), insertion_cookie); - return true; - } - - // <template-param> ::= T_ # first template parameter - // ::= T <parameter-2 non-negative number> _ - - bool ParseTemplateParam() { - int count = TryParseNumber(); - if (!Parse('_')) - return false; - - // When no number is present we get -1, which is convenient since - // T_ is the zeroth element T0_ is element 1, and so on - return RewriteTemplateArg(count + 1); - } - - // <vector-type> - // Dv <dimension number> _ <vector type> - bool TryParseVectorType() { - const int dimension = TryParseNumber(); - if (dimension == -1) - return false; - - if (*m_read_ptr++ != '_') - return false; - - char vec_dimens[32] = {'\0'}; - ::snprintf(vec_dimens, sizeof vec_dimens - 1, " __vector(%d)", dimension); - ParseType(); - Write(vec_dimens); - return true; - } - - // <type> ::= <builtin-type> - // ::= <function-type> - // ::= <class-enum-type> - // ::= <array-type> - // ::= <pointer-to-member-type> - // ::= <template-param> - // ::= <template-template-param> <template-args> - // ::= <decltype> - // ::= <substitution> - // ::= <CV-qualifiers> <type> - // ::= P <type> # pointer-to - // ::= R <type> # reference-to - // ::= O <type> # rvalue reference-to (C++0x) - // ::= C <type> # complex pair (C 2000) - // ::= G <type> # imaginary (C 2000) - // ::= Dp <type> # pack expansion (C++0x) - // ::= U <source-name> <type> # vendor extended type qualifier - // extension := U <objc-name> <objc-type> # objc-type<identifier> - // extension := <vector-type> # <vector-type> starts with Dv - - // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + - // <number of digits in k1> + k1 - // <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> - // 11objc_object -> id<source-name> - - bool ParseType() { -#ifdef DEBUG_FAILURES - const char *failed_type = m_read_ptr; -#endif - int type_start_cookie = GetStartCookie(); - bool suppress_substitution = false; - - int qualifiers = TryParseQualifiers(true, false); - switch (*m_read_ptr) { - case 'D': - ++m_read_ptr; - switch (*m_read_ptr++) { - case 'p': - if (!ParseType()) - return false; - break; - case 'v': - if (!TryParseVectorType()) - return false; - break; - case 'T': - case 't': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - } - break; - case 'T': - ++m_read_ptr; - if (!ParseTemplateParam()) - return false; - break; - case 'M': - ++m_read_ptr; - if (!ParsePointerToMemberType()) - return false; - break; - case 'A': - ++m_read_ptr; - if (!ParseArrayType()) - return false; - break; - case 'F': - ++m_read_ptr; - if (!ParseFunctionType()) - return false; - break; - case 'S': - if (*++m_read_ptr == 't') { - ++m_read_ptr; - WriteStdPrefix(); - if (!ParseName()) - return false; - } else { - suppress_substitution = true; - if (!ParseSubstitution()) - return false; - } - break; - case 'P': { - switch (*++m_read_ptr) { - case 'F': - ++m_read_ptr; - if (!ParseFunctionType(QualifierPointer)) - return false; - break; - default: - if (!ParseType()) - return false; - Write('*'); - break; - } - break; - } - case 'R': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - break; - } - case 'O': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - Write('&'); - break; - } - case 'C': - case 'G': - case 'U': -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - // Test for common cases to avoid TryParseBuiltinType() overhead - case 'N': - case 'Z': - case 'L': - if (!ParseName()) - return false; - break; - default: - if (const char *builtin = TryParseBuiltinType()) { - Write(builtin); - suppress_substitution = true; - } else { - if (!ParseName()) - return false; - } - break; - } - - // Allow base substitutions to be suppressed, but always record - // substitutions for the qualified variant - if (!suppress_substitution) - EndSubstitution(type_start_cookie); - if (qualifiers) { - WriteQualifiers(qualifiers, false); - EndSubstitution(type_start_cookie); - } - return true; - } - - // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ - // ::= <closure-type-name> - // - // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ - // - // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda - // has no parameters - - bool ParseUnnamedTypeName(NameState &name_state) { - switch (*m_read_ptr++) { - case 't': { - int cookie = GetStartCookie(); - WRITE("'unnamed"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'b': { - int cookie = GetStartCookie(); - WRITE("'block"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'l': -#ifdef DEBUG_FAILURES - printf("*** Lambda type names unsupported\n"); -#endif - return false; - } -#ifdef DEBUG_FAILURES - printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2); -#endif - return false; - } - - // <ctor-dtor-name> ::= C1 # complete object constructor - // ::= C2 # base object constructor - // ::= C3 # complete object allocating constructor - - bool ParseCtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '1' || next == '2' || next == '3' || next == '5') { - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken constructor\n"); -#endif - return false; - } - - // <ctor-dtor-name> ::= D0 # deleting destructor - // ::= D1 # complete object destructor - // ::= D2 # base object destructor - - bool ParseDtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '0' || next == '1' || next == '2' || next == '5') { - Write('~'); - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken destructor\n"); -#endif - return false; - } - - // See TryParseOperator() - - bool ParseOperatorName(NameState &name_state) { -#ifdef DEBUG_FAILURES - const char *operator_ptr = m_read_ptr; -#endif - Operator parsed_operator = TryParseOperator(); - if (parsed_operator.name) { - WRITE("operator"); - Write(parsed_operator.name); - return true; - } - - // Handle special operators - switch (parsed_operator.kind) { - case OperatorKind::Vendor: - WRITE("operator "); - return ParseSourceName(); - case OperatorKind::ConversionOperator: - ResetTemplateArgs(); - name_state.has_no_return_type = true; - WRITE("operator "); - return ParseType(); - default: -#ifdef DEBUG_FAILURES - printf("*** Unknown operator: %.2s\n", operator_ptr); -#endif - return false; - } - } - - // <source-name> ::= <positive length number> <identifier> - - bool ParseSourceName() { - int count = TryParseNumber(); - if (count == -1) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, missing length count\n"); -#endif - return false; - } - - const char *next_m_read_ptr = m_read_ptr + count; - if (next_m_read_ptr > m_read_end) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, premature termination\n"); -#endif - return false; - } - - if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0) - WRITE("(anonymous namespace)"); - else - Write(m_read_ptr, count); - - m_read_ptr = next_m_read_ptr; - return true; - } - - // <unqualified-name> ::= <operator-name> - // ::= <ctor-dtor-name> - // ::= <source-name> - // ::= <unnamed-type-name> - - bool ParseUnqualifiedName(NameState &name_state) { - // Note that these are detected directly in ParseNestedName for - // performance rather than switching on the same options twice - char next = *m_read_ptr; - switch (next) { - case 'C': - ++m_read_ptr; - return ParseCtor(name_state); - case 'D': - ++m_read_ptr; - return ParseDtor(name_state); - case 'U': - ++m_read_ptr; - return ParseUnnamedTypeName(name_state); - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - int name_start_cookie = GetStartCookie(); - if (!ParseSourceName()) - return false; - name_state.last_name_range = EndRange(name_start_cookie); - return true; - } - default: - return ParseOperatorName(name_state); - }; - } - - // <unscoped-name> ::= <unqualified-name> - // ::= St <unqualified-name> # ::std:: - // extension ::= StL<unqualified-name> - - bool ParseUnscopedName(NameState &name_state) { - if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't') { - WriteStdPrefix(); - if (*(m_read_ptr += 2) == 'L') - ++m_read_ptr; - } - return ParseUnqualifiedName(name_state); - } - - bool ParseIntegerLiteral(const char *prefix, const char *suffix, - bool allow_negative) { - if (prefix) - Write(prefix); - if (!ParseNumber(allow_negative)) - return false; - if (suffix) - Write(suffix); - return Parse('E'); - } - - bool ParseBooleanLiteral() { - switch (*m_read_ptr++) { - case '0': - WRITE("false"); - break; - case '1': - WRITE("true"); - break; - default: -#ifdef DEBUG_FAILURES - printf("*** Boolean literal not 0 or 1\n"); -#endif - return false; - } - return Parse('E'); - } - - // <expr-primary> ::= L <type> <value number> E # - // integer literal - // ::= L <type> <value float> E # - // floating literal - // ::= L <string type> E # - // string literal - // ::= L <nullptr type> E # - // nullptr literal (i.e., "LDnE") - // ::= L <type> <real-part float> _ <imag-part float> E # - // complex floating point literal (C 2000) - // ::= L <mangled-name> E # - // external name - - bool ParseExpressionPrimary() { - switch (*m_read_ptr++) { - case 'b': - return ParseBooleanLiteral(); - case 'x': - return ParseIntegerLiteral(nullptr, "ll", true); - case 'l': - return ParseIntegerLiteral(nullptr, "l", true); - case 'i': - return ParseIntegerLiteral(nullptr, nullptr, true); - case 'n': - return ParseIntegerLiteral("(__int128)", nullptr, true); - case 'j': - return ParseIntegerLiteral(nullptr, "u", false); - case 'm': - return ParseIntegerLiteral(nullptr, "ul", false); - case 'y': - return ParseIntegerLiteral(nullptr, "ull", false); - case 'o': - return ParseIntegerLiteral("(unsigned __int128)", nullptr, false); - case '_': - if (*m_read_ptr++ == 'Z') { - if (!ParseEncoding()) - return false; - return Parse('E'); - } - --m_read_ptr; - LLVM_FALLTHROUGH; - case 'w': - case 'c': - case 'a': - case 'h': - case 's': - case 't': - case 'f': - case 'd': - case 'e': -#ifdef DEBUG_FAILURES - printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1); -#endif - return false; - case 'T': -// Invalid mangled name per -// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html -#ifdef DEBUG_FAILURES - printf("*** Invalid primary expr encoding\n"); -#endif - return false; - default: - --m_read_ptr; - Write('('); - if (!ParseType()) - return false; - Write(')'); - if (!ParseNumber()) - return false; - return Parse('E'); - } - } - - // <unresolved-type> ::= <template-param> - // ::= <decltype> - // ::= <substitution> - - bool ParseUnresolvedType() { - int type_start_cookie = GetStartCookie(); - switch (*m_read_ptr++) { - case 'T': - if (!ParseTemplateParam()) - return false; - EndSubstitution(type_start_cookie); - return true; - case 'S': { - if (*m_read_ptr != 't') - return ParseSubstitution(); - - ++m_read_ptr; - WriteStdPrefix(); - NameState type_name = {}; - if (!ParseUnqualifiedName(type_name)) - return false; - EndSubstitution(type_start_cookie); - return true; - } - case 'D': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1); -#endif - return false; - } - } - - // <base-unresolved-name> ::= <simple-id> # - // unresolved name - // extension ::= <operator-name> # - // unresolved operator-function-id - // extension ::= <operator-name> <template-args> # - // unresolved operator template-id - // ::= on <operator-name> # - // unresolved operator-function-id - // ::= on <operator-name> <template-args> # - // unresolved operator template-id - // ::= dn <destructor-name> # - // destructor or pseudo-destructor; - // # - // e.g. - // ~X - // or - // ~X<N-1> - - bool ParseBaseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Base unresolved name unsupported\n"); -#endif - return false; - } - - // <unresolved-name> - // extension ::= srN <unresolved-type> [<template-args>] - // <unresolved-qualifier-level>* E <base-unresolved-name> - // ::= [gs] <base-unresolved-name> # x - // or (with "gs") ::x - // ::= [gs] sr <unresolved-qualifier-level>+ E - // <base-unresolved-name> - // # - // A::x, - // N::y, - // A<T>::z; - // "gs" - // means - // leading - // "::" - // ::= sr <unresolved-type> <base-unresolved-name> # - // T::x / decltype(p)::x - // extension ::= sr <unresolved-type> <template-args> - // <base-unresolved-name> - // # - // T::N::x - // /decltype(p)::N::x - // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ - // E <base-unresolved-name> - - bool ParseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Unresolved names not supported\n"); -#endif - // TODO: grammar for all of this seems unclear... - return false; - -#if 0 // TODO - if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's') - { - m_read_ptr += 2; - WriteNamespaceSeparator(); - } -#endif // TODO - } - - // <expression> ::= <unary operator-name> <expression> - // ::= <binary operator-name> <expression> <expression> - // ::= <ternary operator-name> <expression> <expression> - // <expression> - // ::= cl <expression>+ E # - // call - // ::= cv <type> <expression> # - // conversion with one argument - // ::= cv <type> _ <expression>* E # - // conversion with a different number of arguments - // ::= [gs] nw <expression>* _ <type> E # new - // (expr-list) type - // ::= [gs] nw <expression>* _ <type> <initializer> # new - // (expr-list) type (init) - // ::= [gs] na <expression>* _ <type> E # - // new[] (expr-list) type - // ::= [gs] na <expression>* _ <type> <initializer> # - // new[] (expr-list) type (init) - // ::= [gs] dl <expression> # - // delete expression - // ::= [gs] da <expression> # - // delete[] expression - // ::= pp_ <expression> # - // prefix ++ - // ::= mm_ <expression> # - // prefix -- - // ::= ti <type> # - // typeid (type) - // ::= te <expression> # - // typeid (expression) - // ::= dc <type> <expression> # - // dynamic_cast<type> (expression) - // ::= sc <type> <expression> # - // static_cast<type> (expression) - // ::= cc <type> <expression> # - // const_cast<type> (expression) - // ::= rc <type> <expression> # - // reinterpret_cast<type> (expression) - // ::= st <type> # - // sizeof (a type) - // ::= sz <expression> # - // sizeof (an expression) - // ::= at <type> # - // alignof (a type) - // ::= az <expression> # - // alignof (an expression) - // ::= nx <expression> # - // noexcept (expression) - // ::= <template-param> - // ::= <function-param> - // ::= dt <expression> <unresolved-name> # - // expr.name - // ::= pt <expression> <unresolved-name> # - // expr->name - // ::= ds <expression> <expression> # - // expr.*expr - // ::= sZ <template-param> # - // size of a parameter pack - // ::= sZ <function-param> # - // size of a function parameter pack - // ::= sp <expression> # - // pack expansion - // ::= tw <expression> # - // throw expression - // ::= tr # - // throw with no operand (rethrow) - // ::= <unresolved-name> # - // f(p), N::f(p), ::f(p), - // # - // freestanding - // dependent - // name - // (e.g., - // T::x), - // # - // objectless - // nonstatic - // member - // reference - // ::= <expr-primary> - - bool ParseExpression() { - Operator expression_operator = TryParseOperator(); - switch (expression_operator.kind) { - case OperatorKind::Unary: - Write(expression_operator.name); - Write('('); - if (!ParseExpression()) - return false; - Write(')'); - return true; - case OperatorKind::Binary: - if (!ParseExpression()) - return false; - Write(expression_operator.name); - return ParseExpression(); - case OperatorKind::Ternary: - if (!ParseExpression()) - return false; - Write('?'); - if (!ParseExpression()) - return false; - Write(':'); - return ParseExpression(); - case OperatorKind::NoMatch: - break; - case OperatorKind::Other: - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported operator: %s\n", expression_operator.name); -#endif - return false; - } - - switch (*m_read_ptr++) { - case 'T': - return ParseTemplateParam(); - case 'L': - return ParseExpressionPrimary(); - case 's': - if (*m_read_ptr++ == 'r') - return ParseUnresolvedName(); - --m_read_ptr; - LLVM_FALLTHROUGH; - default: - return ParseExpressionPrimary(); - } - } - - // <template-arg> ::= <type> # - // type or template - // ::= X <expression> E # - // expression - // ::= <expr-primary> # - // simple expressions - // ::= J <template-arg>* E # - // argument pack - // ::= LZ <encoding> E # - // extension - - bool ParseTemplateArg() { - switch (*m_read_ptr) { - case 'J': -#ifdef DEBUG_FAILURES - printf("*** Template argument packs unsupported\n"); -#endif - return false; - case 'X': - ++m_read_ptr; - if (!ParseExpression()) - return false; - return Parse('E'); - case 'L': - ++m_read_ptr; - return ParseExpressionPrimary(); - default: - return ParseType(); - } - } - - // <template-args> ::= I <template-arg>* E - // extension, the abi says <template-arg>+ - - bool ParseTemplateArgs(bool record_template_args = false) { - if (record_template_args) - ResetTemplateArgs(); - - bool first_arg = true; - while (*m_read_ptr != 'E') { - if (first_arg) - first_arg = false; - else - WriteCommaSpace(); - - int template_start_cookie = GetStartCookie(); - if (!ParseTemplateArg()) - return false; - if (record_template_args) - EndTemplateArg(template_start_cookie); - } - ++m_read_ptr; - return true; - } - - // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> - // <unqualified-name> E - // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> - // <template-args> E - // - // <prefix> ::= <prefix> <unqualified-name> - // ::= <template-prefix> <template-args> - // ::= <template-param> - // ::= <decltype> - // ::= # empty - // ::= <substitution> - // ::= <prefix> <data-member-prefix> - // extension ::= L - // - // <template-prefix> ::= <prefix> <template unqualified-name> - // ::= <template-param> - // ::= <substitution> - // - // <unqualified-name> ::= <operator-name> - // ::= <ctor-dtor-name> - // ::= <source-name> - // ::= <unnamed-type-name> - - bool ParseNestedName(NameState &name_state, - bool parse_discriminator = false) { - int qualifiers = TryParseQualifiers(true, true); - bool first_part = true; - bool suppress_substitution = true; - int name_start_cookie = GetStartCookie(); - while (true) { - char next = *m_read_ptr; - if (next == 'E') { - ++m_read_ptr; - break; - } - - // Record a substitution candidate for all prefixes, but not the full name - if (suppress_substitution) - suppress_substitution = false; - else - EndSubstitution(name_start_cookie); - - if (next == 'I') { - ++m_read_ptr; - name_state.is_last_generic = true; - WriteTemplateStart(); - if (!ParseTemplateArgs(name_state.parse_function_params)) - return false; - WriteTemplateEnd(); - continue; - } - - if (first_part) - first_part = false; - else - WriteNamespaceSeparator(); - - name_state.is_last_generic = false; - switch (next) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - int name_start_cookie = GetStartCookie(); - if (!ParseSourceName()) - return false; - name_state.last_name_range = EndRange(name_start_cookie); - continue; - } - case 'S': - if (*++m_read_ptr == 't') { - WriteStdPrefix(); - ++m_read_ptr; - if (!ParseUnqualifiedName(name_state)) - return false; - } else { - if (!ParseSubstitution()) - return false; - suppress_substitution = true; - } - continue; - case 'T': - ++m_read_ptr; - if (!ParseTemplateParam()) - return false; - continue; - case 'C': - ++m_read_ptr; - if (!ParseCtor(name_state)) - return false; - continue; - case 'D': { - switch (*(m_read_ptr + 1)) { - case 't': - case 'T': -#ifdef DEBUG_FAILURES - printf("*** Decltype unsupported\n"); -#endif - return false; - } - ++m_read_ptr; - if (!ParseDtor(name_state)) - return false; - continue; - } - case 'U': - ++m_read_ptr; - if (!ParseUnnamedTypeName(name_state)) - return false; - continue; - case 'L': - ++m_read_ptr; - if (!ParseUnqualifiedName(name_state)) - return false; - continue; - default: - if (!ParseOperatorName(name_state)) - return false; - } - } - - if (parse_discriminator) - TryParseDiscriminator(); - if (name_state.parse_function_params && - !ParseFunctionArgs(name_state, name_start_cookie)) { - return false; - } - if (qualifiers) - WriteQualifiers(qualifiers); - return true; - } - - // <local-name> := Z <function encoding> E <entity name> [<discriminator>] - // := Z <function encoding> E s [<discriminator>] - // := Z <function encoding> Ed [ <parameter number> ] _ <entity - // name> - - bool ParseLocalName(bool parse_function_params) { - if (!ParseEncoding()) - return false; - if (!Parse('E')) - return false; - - switch (*m_read_ptr) { - case 's': - ++m_read_ptr; - TryParseDiscriminator(); // Optional and ignored - WRITE("::string literal"); - break; - case 'd': - ++m_read_ptr; - TryParseNumber(); // Optional and ignored - if (!Parse('_')) - return false; - WriteNamespaceSeparator(); - if (!ParseName()) - return false; - break; - default: - WriteNamespaceSeparator(); - if (!ParseName(parse_function_params, true)) - return false; - TryParseDiscriminator(); // Optional and ignored - } - return true; - } - - // <name> ::= <nested-name> - // ::= <local-name> - // ::= <unscoped-template-name> <template-args> - // ::= <unscoped-name> - - // <unscoped-template-name> ::= <unscoped-name> - // ::= <substitution> - - bool ParseName(bool parse_function_params = false, - bool parse_discriminator = false) { - NameState name_state = {parse_function_params, false, false, {0, 0}}; - int name_start_cookie = GetStartCookie(); - - switch (*m_read_ptr) { - case 'N': - ++m_read_ptr; - return ParseNestedName(name_state, parse_discriminator); - case 'Z': { - ++m_read_ptr; - if (!ParseLocalName(parse_function_params)) - return false; - break; - } - case 'L': - ++m_read_ptr; - LLVM_FALLTHROUGH; - default: { - if (!ParseUnscopedName(name_state)) - return false; - - if (*m_read_ptr == 'I') { - EndSubstitution(name_start_cookie); - - ++m_read_ptr; - name_state.is_last_generic = true; - WriteTemplateStart(); - if (!ParseTemplateArgs(parse_function_params)) - return false; - WriteTemplateEnd(); - } - break; - } - } - if (parse_discriminator) - TryParseDiscriminator(); - if (parse_function_params && - !ParseFunctionArgs(name_state, name_start_cookie)) { - return false; - } - return true; - } - - // <call-offset> ::= h <nv-offset> _ - // ::= v <v-offset> _ - // - // <nv-offset> ::= <offset number> - // # non-virtual base override - // - // <v-offset> ::= <offset number> _ <virtual offset number> - // # virtual base override, with vcall offset - - bool ParseCallOffset() { - switch (*m_read_ptr++) { - case 'h': - if (*m_read_ptr == 'n') - ++m_read_ptr; - if (TryParseNumber() == -1 || *m_read_ptr++ != '_') - break; - return true; - case 'v': - if (*m_read_ptr == 'n') - ++m_read_ptr; - if (TryParseNumber() == -1 || *m_read_ptr++ != '_') - break; - if (*m_read_ptr == 'n') - ++m_read_ptr; - if (TryParseNumber() == -1 || *m_read_ptr++ != '_') - break; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Malformed call offset\n"); -#endif - return false; - } - - // <special-name> ::= TV <type> # virtual table - // ::= TT <type> # VTT structure (construction vtable index) - // ::= TI <type> # typeinfo structure - // ::= TS <type> # typeinfo name (null-terminated byte - // string) - // ::= Tc <call-offset> <call-offset> <base encoding> - // # base is the nominal target function of thunk - // # first call-offset is 'this' adjustment - // # second call-offset is result adjustment - // ::= T <call-offset> <base encoding> - // # base is the nominal target function of thunk - // extension ::= TC <first type> <number> _ <second type> # construction - // vtable for second-in-first - - bool ParseSpecialNameT() { - switch (*m_read_ptr++) { - case 'V': - WRITE("vtable for "); - return ParseType(); - case 'T': - WRITE("VTT for "); - return ParseType(); - case 'I': - WRITE("typeinfo for "); - return ParseType(); - case 'S': - WRITE("typeinfo name for "); - return ParseType(); - case 'c': - case 'C': -#ifdef DEBUG_FAILURES - printf("*** Unsupported thunk or construction vtable name: %.3s\n", - m_read_ptr - 1); -#endif - return false; - default: - if (*--m_read_ptr == 'v') { - WRITE("virtual thunk to "); - } else { - WRITE("non-virtual thunk to "); - } - if (!ParseCallOffset()) - return false; - return ParseEncoding(); - } - } - - // <special-name> ::= GV <object name> # Guard variable for one-time - // initialization - // # No <type> - // extension ::= GR <object name> # reference temporary for object - - bool ParseSpecialNameG() { - switch (*m_read_ptr++) { - case 'V': - WRITE("guard variable for "); - if (!ParseName(true)) - return false; - break; - case 'R': - WRITE("reference temporary for "); - if (!ParseName(true)) - return false; - break; - default: -#ifdef DEBUG_FAILURES - printf("*** Unknown G encoding\n"); -#endif - return false; - } - return true; - } - - // <bare-function-type> ::= <signature type>+ # types are possible - // return type, then parameter types - - bool ParseFunctionArgs(NameState &name_state, int return_insert_cookie) { - char next = *m_read_ptr; - if (next == 'E' || next == '\0' || next == '.') - return true; - - // Clang has a bad habit of making unique manglings by just sticking numbers - // on the end of a symbol, - // which is ambiguous with malformed source name manglings - const char *before_clang_uniquing_test = m_read_ptr; - if (TryParseNumber()) { - if (*m_read_ptr == '\0') - return true; - m_read_ptr = before_clang_uniquing_test; - } - - if (name_state.is_last_generic && !name_state.has_no_return_type) { - int return_type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - Write(' '); - ReorderRange(EndRange(return_type_start_cookie), return_insert_cookie); - } - - Write('('); - bool first_param = true; - while (true) { - switch (*m_read_ptr) { - case '\0': - case 'E': - case '.': - break; - case 'v': - ++m_read_ptr; - continue; - case '_': - // Not a formal part of the mangling specification, but clang emits - // suffixes starting with _block_invoke - if (strncmp(m_read_ptr, "_block_invoke", 13) == 0) { - m_read_ptr += strlen(m_read_ptr); - break; - } - LLVM_FALLTHROUGH; - default: - if (first_param) - first_param = false; - else - WriteCommaSpace(); - - if (!ParseType()) - return false; - continue; - } - break; - } - Write(')'); - return true; - } - - // <encoding> ::= <function name> <bare-function-type> - // ::= <data name> - // ::= <special-name> - - bool ParseEncoding() { - switch (*m_read_ptr) { - case 'T': - ++m_read_ptr; - if (!ParseSpecialNameT()) - return false; - break; - case 'G': - ++m_read_ptr; - if (!ParseSpecialNameG()) - return false; - break; - default: - if (!ParseName(true)) - return false; - break; - } - return true; - } - - bool ParseMangling(const char *mangled_name, long mangled_name_length = 0) { - if (!mangled_name_length) - mangled_name_length = strlen(mangled_name); - m_read_end = mangled_name + mangled_name_length; - m_read_ptr = mangled_name; - m_write_ptr = m_buffer; - m_next_substitute_index = 0; - m_next_template_arg_index = m_rewrite_ranges_size - 1; - - if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z') { -#ifdef DEBUG_FAILURES - printf("*** Missing _Z prefix\n"); -#endif - return false; - } - if (!ParseEncoding()) - return false; - switch (*m_read_ptr) { - case '.': - Write(' '); - Write('('); - Write(m_read_ptr, m_read_end - m_read_ptr); - Write(')'); - LLVM_FALLTHROUGH; - case '\0': - return true; - default: -#ifdef DEBUG_FAILURES - printf("*** Unparsed mangled content\n"); -#endif - return false; - } - } - -private: - // External scratch storage used during demanglings - - char *m_buffer; - const char *m_buffer_end; - BufferRange *m_rewrite_ranges; - int m_rewrite_ranges_size; - bool m_owns_buffer; - bool m_owns_m_rewrite_ranges; - - // Internal state used during demangling - - const char *m_read_ptr; - const char *m_read_end; - char *m_write_ptr; - int m_next_template_arg_index; - int m_next_substitute_index; - std::function<void(const char *s)> m_builtins_hook; -}; - -} // Anonymous namespace - -// Public entry points referenced from Mangled.cpp -namespace lldb_private { -char *FastDemangle(const char *mangled_name) { - char buffer[16384]; - SymbolDemangler demangler(buffer, sizeof(buffer)); - return demangler.GetDemangledCopy(mangled_name); -} - -char *FastDemangle(const char *mangled_name, size_t mangled_name_length, - std::function<void(const char *s)> builtins_hook) { - char buffer[16384]; - SymbolDemangler demangler(buffer, sizeof(buffer), builtins_hook); - return demangler.GetDemangledCopy(mangled_name, mangled_name_length); -} -} // lldb_private namespace diff --git a/source/Core/FileLineResolver.cpp b/source/Core/FileLineResolver.cpp index db56cae9e9bc..36f37f4a14d5 100644 --- a/source/Core/FileLineResolver.cpp +++ b/source/Core/FileLineResolver.cpp @@ -10,10 +10,17 @@ #include "lldb/Core/FileLineResolver.h" // Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Core/FileSpecList.h" // for FileSpecList #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Stream.h" // for Stream + +#include <string> // for string + +namespace lldb_private { +class Address; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp index d4ce4b787aad..a69f490f9aed 100644 --- a/source/Core/FileSpecList.cpp +++ b/source/Core/FileSpecList.cpp @@ -9,13 +9,12 @@ #include "lldb/Core/FileSpecList.h" -// C Includes -// C++ Includes -#include <algorithm> +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Stream.h" -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Stream.h" +#include <utility> // for find + +#include <stdint.h> // for UINT32_MAX using namespace lldb_private; using namespace std; @@ -150,32 +149,23 @@ size_t FileSpecList::GetFilesMatchingPartialPath(const char *path, FileSpecList &matches) { #if 0 // FIXME: Just sketching... matches.Clear(); - FileSpec path_spec = FileSpec (path); - if (path_spec.Exists ()) - { - FileSpec::FileType type = path_spec.GetFileType(); - if (type == FileSpec::eFileTypeSymbolicLink) - // Shouldn't there be a Resolve on a file spec that real-path's it? - { - } - - if (type == FileSpec::eFileTypeRegular - || (type == FileSpec::eFileTypeDirectory && dir_okay)) - { - matches.Append (path_spec); - return 1; - } - else if (type == FileSpec::eFileTypeDirectory) - { - // Fill the match list with all the files in the directory: - } - else - { - return 0; - } - } - else - { + using namespace llvm::sys::fs; + file_status stats; + if (status(path, stats, false)) + return 0; + if (exists(stats)) { + if (is_symlink_file(stats)) { + // Shouldn't there be a method that realpath's a file? + } + if (is_regular_file(stats) || (is_directory(stats) && dir_okay)) { + matches.Append(FileSpec(path)); + return 1; + } else if (is_directory(stats)) { + // Fill the match list with all the files in the directory: + } else { + return 0; + } + } else { ConstString dir_name = path_spec.GetDirectory(); ConstString file_name = GetFilename(); if (dir_name == nullptr) diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp index 08166d208aee..835a1c54a0e0 100644 --- a/source/Core/FormatEntity.cpp +++ b/source/Core/FormatEntity.cpp @@ -9,33 +9,31 @@ #include "lldb/Core/FormatEntity.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" - -// Project includes #include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Core/RegisterValue.h" // for RegisterValue +#include "lldb/Core/StructuredData.h" // for StructuredData::O... #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/DataFormatters/FormatClasses.h" // for TypeNameSpecifier... #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/DataFormatters/ValueObjectPrinter.h" +#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryImpl::... #include "lldb/Expression/ExpressionVariable.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/CompilerType.h" // for CompilerType #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextS... #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -45,6 +43,36 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/ConstString.h" // for ConstString, oper... +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" // for Log +#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego... +#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StringList.h" // for StringList +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-forward.h" // for ValueObjectSP +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" // for Triple, Triple::O... +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <ctype.h> // for isxdigit +#include <inttypes.h> // for PRIu64, PRIx64 +#include <memory> // for shared_ptr, opera... +#include <stdio.h> // for sprintf +#include <stdlib.h> // for strtoul +#include <string.h> // for size_t, strchr +#include <type_traits> // for move +#include <utility> // for pair + +namespace lldb_private { +class ScriptInterpreter; +} +namespace lldb_private { +struct RegisterInfo; +} using namespace lldb; using namespace lldb_private; @@ -64,14 +92,14 @@ enum FileKind { FileError = 0, Basename, Dirname, Fullpath }; #define ENTRY_CHILDREN(n, t, f, c) \ { \ n, nullptr, FormatEntity::Entry::Type::t, \ - FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, \ - false \ + FormatEntity::Entry::FormatType::f, 0, \ + static_cast<uint32_t>(llvm::array_lengthof(c)), c, false \ } #define ENTRY_CHILDREN_KEEP_SEP(n, t, f, c) \ { \ n, nullptr, FormatEntity::Entry::Type::t, \ - FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, \ - true \ + FormatEntity::Entry::FormatType::f, 0, \ + static_cast<uint32_t>(llvm::array_lengthof(c)), c, true \ } #define ENTRY_STRING(n, s) \ { \ @@ -822,8 +850,8 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, StreamString bitfield_name; bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); - lldb::TypeNameSpecifierImplSP type_sp( - new TypeNameSpecifierImpl(bitfield_name.GetString(), false)); + auto type_sp = std::make_shared<TypeNameSpecifierImpl>( + bitfield_name.GetString(), false); if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp)) @@ -1187,7 +1215,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; if ((ostype == llvm::Triple::FreeBSD) || - (ostype == llvm::Triple::Linux)) { + (ostype == llvm::Triple::Linux) || + (ostype == llvm::Triple::NetBSD)) { format = "%" PRIu64; } } else { diff --git a/source/Core/History.cpp b/source/Core/History.cpp deleted file mode 100644 index 0466a83da519..000000000000 --- a/source/Core/History.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===-- History.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/History.h" - -// C Includes -#include <inttypes.h> -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Stream.h" - -using namespace lldb; -using namespace lldb_private; - -void HistorySourceUInt::DumpHistoryEvent(Stream &strm, HistoryEvent event) { - strm.Printf("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event)); -} diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp index 9c5e6ca80c20..b5dd0bd8a25f 100644 --- a/source/Core/IOHandler.cpp +++ b/source/Core/IOHandler.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include "lldb/Core/IOHandler.h" + // C Includes #ifndef LLDB_DISABLE_CURSES #include <curses.h> @@ -21,36 +23,55 @@ // Other libraries and framework includes // Project includes -#include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/IOHandler.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Host/File.h" // for File +#include "lldb/Host/Predicate.h" // for Predicate, ::eBroad... +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/StreamString.h" // for StreamString +#include "lldb/Utility/StringList.h" // for StringList +#include "lldb/lldb-forward.h" // for StreamFileSP + #ifndef LLDB_DISABLE_LIBEDIT #include "lldb/Host/Editline.h" #endif #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" +#ifndef LLDB_DISABLE_CURSES +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/State.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/ThreadPlan.h" -#ifndef LLDB_DISABLE_CURSES -#include "lldb/Core/ValueObject.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #endif +#include "llvm/ADT/StringRef.h" // for StringRef + #ifdef _MSC_VER -#include <Windows.h> +#include <windows.h> #endif +#include <memory> // for shared_ptr +#include <mutex> // for recursive_mutex + +#include <assert.h> // for assert +#include <ctype.h> // for isspace +#include <errno.h> // for EINTR, errno +#include <stdint.h> // for uint32_t, UINT32_MAX +#include <stdio.h> // for size_t, fprintf, feof +#include <string.h> // for strlen +#include <type_traits> // for move + using namespace lldb; using namespace lldb_private; diff --git a/source/Core/Listener.cpp b/source/Core/Listener.cpp index 3adb677f53d1..1afa11649b59 100644 --- a/source/Core/Listener.cpp +++ b/source/Core/Listener.cpp @@ -9,16 +9,17 @@ #include "lldb/Core/Listener.h" -// C Includes -// C++ Includes -#include <algorithm> - -// Other libraries and framework includes -// Project includes #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIBL... + +#include "llvm/ADT/Optional.h" // for Optional + +#include <algorithm> +#include <memory> // for make_shared +#include <utility> // for pair, make_pair using namespace lldb; using namespace lldb_private; @@ -352,11 +353,7 @@ bool Listener::GetEventInternal( uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); - if (log != nullptr) - log->Printf("%p Listener::GetEventInternal (timeout = %llu us) for %s", - static_cast<void *>(this), static_cast<unsigned long long>( - timeout ? timeout->count() : -1), - m_name.c_str()); + LLDB_LOG(log, "this = {0}, timeout = {1} for {2}", this, timeout, m_name); std::unique_lock<std::mutex> lock(m_events_mutex); diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp deleted file mode 100644 index b62df3c1fe97..000000000000 --- a/source/Core/Log.cpp +++ /dev/null @@ -1,399 +0,0 @@ -//===-- Log.cpp -------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/ThisThread.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Utility/NameMatches.h" - -// Other libraries and framework includes -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/Chrono.h" -#include "llvm/Support/Signals.h" -#include "llvm/Support/raw_ostream.h" - -// C Includes -// C++ Includes -#include <cstdarg> -#include <cstdio> -#include <cstdlib> -#include <map> -#include <mutex> -#include <string> - -using namespace lldb; -using namespace lldb_private; - -Log::Log() : m_stream_sp(), m_options(0), m_mask_bits(0) {} - -Log::Log(const StreamSP &stream_sp) - : m_stream_sp(stream_sp), m_options(0), m_mask_bits(0) {} - -Log::~Log() = default; - -Flags &Log::GetOptions() { return m_options; } - -const Flags &Log::GetOptions() const { return m_options; } - -Flags &Log::GetMask() { return m_mask_bits; } - -const Flags &Log::GetMask() const { return m_mask_bits; } - -void Log::PutCString(const char *cstr) { Printf("%s", cstr); } -void Log::PutString(llvm::StringRef str) { PutCString(str.str().c_str()); } - -//---------------------------------------------------------------------- -// Simple variable argument logging with flags. -//---------------------------------------------------------------------- -void Log::Printf(const char *format, ...) { - va_list args; - va_start(args, format); - VAPrintf(format, args); - va_end(args); -} - -//---------------------------------------------------------------------- -// All logging eventually boils down to this function call. If we have -// a callback registered, then we call the logging callback. If we have -// a valid file handle, we also log to the file. -//---------------------------------------------------------------------- -void Log::VAPrintf(const char *format, va_list args) { - // Make a copy of our stream shared pointer in case someone disables our - // log while we are logging and releases the stream - StreamSP stream_sp(m_stream_sp); - if (stream_sp) { - static uint32_t g_sequence_id = 0; - StreamString header; - - // Add a sequence ID if requested - if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE)) - header.Printf("%u ", ++g_sequence_id); - - // Timestamp if requested - if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) { - auto now = std::chrono::duration<double>( - std::chrono::system_clock::now().time_since_epoch()); - header.Printf("%.9f ", now.count()); - } - - // Add the process and thread if requested - if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD)) - header.Printf("[%4.4x/%4.4" PRIx64 "]: ", getpid(), - Host::GetCurrentThreadID()); - - // Add the thread name if requested - if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) { - llvm::SmallString<32> thread_name; - ThisThread::GetName(thread_name); - if (!thread_name.empty()) - header.Printf("%s ", thread_name.c_str()); - } - - header.PrintfVarArg(format, args); - header.PutCString("\n"); - - if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE)) { - std::string back_trace; - llvm::raw_string_ostream stream(back_trace); - llvm::sys::PrintStackTrace(stream); - stream.flush(); - header.PutCString(back_trace); - } - - if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) { - static std::recursive_mutex g_LogThreadedMutex; - std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex); - stream_sp->PutCString(header.GetString()); - stream_sp->Flush(); - } else { - stream_sp->PutCString(header.GetString()); - stream_sp->Flush(); - } - } -} - -//---------------------------------------------------------------------- -// Print debug strings if and only if the global debug option is set to -// a non-zero value. -//---------------------------------------------------------------------- -void Log::Debug(const char *format, ...) { - if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG)) - return; - - va_list args; - va_start(args, format); - VAPrintf(format, args); - va_end(args); -} - -//---------------------------------------------------------------------- -// Log only if all of the bits are set -//---------------------------------------------------------------------- -void Log::LogIf(uint32_t bits, const char *format, ...) { - if (!m_options.AllSet(bits)) - return; - - va_list args; - va_start(args, format); - VAPrintf(format, args); - va_end(args); -} - -//---------------------------------------------------------------------- -// Printing of errors that are not fatal. -//---------------------------------------------------------------------- -void Log::Error(const char *format, ...) { - va_list args; - va_start(args, format); - VAError(format, args); - va_end(args); -} - -void Log::VAError(const char *format, va_list args) { - char *arg_msg = nullptr; - ::vasprintf(&arg_msg, format, args); - - if (arg_msg == nullptr) - return; - - Printf("error: %s", arg_msg); - free(arg_msg); -} - -//---------------------------------------------------------------------- -// Printing of warnings that are not fatal only if verbose mode is -// enabled. -//---------------------------------------------------------------------- -void Log::Verbose(const char *format, ...) { - if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE)) - return; - - va_list args; - va_start(args, format); - VAPrintf(format, args); - va_end(args); -} - -//---------------------------------------------------------------------- -// Printing of warnings that are not fatal. -//---------------------------------------------------------------------- -void Log::Warning(const char *format, ...) { - char *arg_msg = nullptr; - va_list args; - va_start(args, format); - ::vasprintf(&arg_msg, format, args); - va_end(args); - - if (arg_msg == nullptr) - return; - - Printf("warning: %s", arg_msg); - free(arg_msg); -} - -typedef std::map<ConstString, Log::Callbacks> CallbackMap; -typedef CallbackMap::iterator CallbackMapIter; - -typedef std::map<ConstString, LogChannelSP> LogChannelMap; -typedef LogChannelMap::iterator LogChannelMapIter; - -// Surround our callback map with a singleton function so we don't have any -// global initializers. -static CallbackMap &GetCallbackMap() { - static CallbackMap g_callback_map; - return g_callback_map; -} - -static LogChannelMap &GetChannelMap() { - static LogChannelMap g_channel_map; - return g_channel_map; -} - -void Log::RegisterLogChannel(const ConstString &channel, - const Log::Callbacks &log_callbacks) { - GetCallbackMap().insert(std::make_pair(channel, log_callbacks)); -} - -bool Log::UnregisterLogChannel(const ConstString &channel) { - return GetCallbackMap().erase(channel) != 0; -} - -bool Log::GetLogChannelCallbacks(const ConstString &channel, - Log::Callbacks &log_callbacks) { - CallbackMap &callback_map = GetCallbackMap(); - CallbackMapIter pos = callback_map.find(channel); - if (pos != callback_map.end()) { - log_callbacks = pos->second; - return true; - } - ::memset(&log_callbacks, 0, sizeof(log_callbacks)); - return false; -} - -bool Log::EnableLogChannel(lldb::StreamSP &log_stream_sp, uint32_t log_options, - const char *channel, const char **categories, - Stream &error_stream) { - Log::Callbacks log_callbacks; - if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) { - log_callbacks.enable(log_stream_sp, log_options, categories, &error_stream); - return true; - } - - LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel)); - if (log_channel_sp) { - if (log_channel_sp->Enable(log_stream_sp, log_options, &error_stream, - categories)) { - return true; - } else { - error_stream.Printf("Invalid log channel '%s'.\n", channel); - return false; - } - } else { - error_stream.Printf("Invalid log channel '%s'.\n", channel); - return false; - } -} - -void Log::EnableAllLogChannels(StreamSP &log_stream_sp, uint32_t log_options, - const char **categories, Stream *feedback_strm) { - CallbackMap &callback_map = GetCallbackMap(); - CallbackMapIter pos, end = callback_map.end(); - - for (pos = callback_map.begin(); pos != end; ++pos) - pos->second.enable(log_stream_sp, log_options, categories, feedback_strm); - - LogChannelMap &channel_map = GetChannelMap(); - LogChannelMapIter channel_pos, channel_end = channel_map.end(); - for (channel_pos = channel_map.begin(); channel_pos != channel_end; - ++channel_pos) { - channel_pos->second->Enable(log_stream_sp, log_options, feedback_strm, - categories); - } -} - -void Log::AutoCompleteChannelName(const char *channel_name, - StringList &matches) { - LogChannelMap &map = GetChannelMap(); - LogChannelMapIter pos, end = map.end(); - for (pos = map.begin(); pos != end; ++pos) { - const char *pos_channel_name = pos->first.GetCString(); - if (channel_name && channel_name[0]) { - if (NameMatches(channel_name, eNameMatchStartsWith, pos_channel_name)) { - matches.AppendString(pos_channel_name); - } - } else - matches.AppendString(pos_channel_name); - } -} - -void Log::DisableAllLogChannels(Stream *feedback_strm) { - CallbackMap &callback_map = GetCallbackMap(); - CallbackMapIter pos, end = callback_map.end(); - const char *categories[] = {"all", nullptr}; - - for (pos = callback_map.begin(); pos != end; ++pos) - pos->second.disable(categories, feedback_strm); - - LogChannelMap &channel_map = GetChannelMap(); - LogChannelMapIter channel_pos, channel_end = channel_map.end(); - for (channel_pos = channel_map.begin(); channel_pos != channel_end; - ++channel_pos) - channel_pos->second->Disable(categories, feedback_strm); -} - -void Log::Initialize() { - Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories}; - Log::RegisterLogChannel(ConstString("lldb"), log_callbacks); -} - -void Log::Terminate() { DisableAllLogChannels(nullptr); } - -void Log::ListAllLogChannels(Stream *strm) { - CallbackMap &callback_map = GetCallbackMap(); - LogChannelMap &channel_map = GetChannelMap(); - - if (callback_map.empty() && channel_map.empty()) { - strm->PutCString("No logging channels are currently registered.\n"); - return; - } - - CallbackMapIter pos, end = callback_map.end(); - for (pos = callback_map.begin(); pos != end; ++pos) - pos->second.list_categories(strm); - - uint32_t idx = 0; - const char *name; - for (idx = 0; - (name = PluginManager::GetLogChannelCreateNameAtIndex(idx)) != nullptr; - ++idx) { - LogChannelSP log_channel_sp(LogChannel::FindPlugin(name)); - if (log_channel_sp) - log_channel_sp->ListCategories(strm); - } -} - -bool Log::GetVerbose() const { - // FIXME: This has to be centralized between the stream and the log... - if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) - return true; - - // Make a copy of our stream shared pointer in case someone disables our - // log while we are logging and releases the stream - StreamSP stream_sp(m_stream_sp); - if (stream_sp) - return stream_sp->GetVerbose(); - return false; -} - -//------------------------------------------------------------------ -// Returns true if the debug flag bit is set in this stream. -//------------------------------------------------------------------ -bool Log::GetDebug() const { - // Make a copy of our stream shared pointer in case someone disables our - // log while we are logging and releases the stream - StreamSP stream_sp(m_stream_sp); - if (stream_sp) - return stream_sp->GetDebug(); - return false; -} - -LogChannelSP LogChannel::FindPlugin(const char *plugin_name) { - LogChannelSP log_channel_sp; - LogChannelMap &channel_map = GetChannelMap(); - ConstString log_channel_name(plugin_name); - LogChannelMapIter pos = channel_map.find(log_channel_name); - if (pos == channel_map.end()) { - ConstString const_plugin_name(plugin_name); - LogChannelCreateInstance create_callback = - PluginManager::GetLogChannelCreateCallbackForPluginName( - const_plugin_name); - if (create_callback) { - log_channel_sp.reset(create_callback()); - if (log_channel_sp) { - // Cache the one and only loaded instance of each log channel - // plug-in after it has been loaded once. - channel_map[log_channel_name] = log_channel_sp; - } - } - } else { - // We have already loaded an instance of this log channel class, - // so just return the cached instance. - log_channel_sp = pos->second; - } - return log_channel_sp; -} - -LogChannel::LogChannel() : m_log_ap() {} - -LogChannel::~LogChannel() = default; diff --git a/source/Core/Logging.cpp b/source/Core/Logging.cpp deleted file mode 100644 index 4d63b60eeccd..000000000000 --- a/source/Core/Logging.cpp +++ /dev/null @@ -1,322 +0,0 @@ -//===-- Logging.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/Logging.h" - -// C Includes -// C++ Includes -#include <atomic> -#include <cstring> - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Interpreter/Args.h" - -using namespace lldb; -using namespace lldb_private; - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. - -static std::atomic<bool> g_log_enabled{false}; -static Log *g_log = nullptr; - -static Log *GetLog() { - if (!g_log_enabled) - return nullptr; - return g_log; -} - -uint32_t lldb_private::GetLogMask() { - Log *log(GetLog()); - if (log) - return log->GetMask().Get(); - return 0; -} - -bool lldb_private::IsLogVerbose() { - uint32_t mask = GetLogMask(); - return (mask & LIBLLDB_LOG_VERBOSE); -} - -Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) { - Log *log(GetLog()); - if (log && mask) { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return nullptr; - } - return log; -} - -void lldb_private::LogIfAllCategoriesSet(uint32_t mask, const char *format, - ...) { - Log *log(GetLogIfAllCategoriesSet(mask)); - if (log) { - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} - -void lldb_private::LogIfAnyCategoriesSet(uint32_t mask, const char *format, - ...) { - Log *log(GetLogIfAnyCategoriesSet(mask)); - if (log != nullptr) { - va_list args; - va_start(args, format); - log->VAPrintf(format, args); - va_end(args); - } -} - -Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) { - Log *log(GetLog()); - if (log != nullptr && mask && (mask & log->GetMask().Get())) - return log; - return nullptr; -} - -void lldb_private::DisableLog(const char **categories, Stream *feedback_strm) { - Log *log(GetLog()); - - if (log != nullptr) { - uint32_t flag_bits = 0; - if (categories && categories[0]) { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; categories[i] != nullptr; ++i) { - const char *arg = categories[i]; - - if (0 == ::strcasecmp(arg, "all")) - flag_bits &= ~LIBLLDB_LOG_ALL; - else if (0 == ::strcasecmp(arg, "api")) - flag_bits &= ~LIBLLDB_LOG_API; - else if (0 == ::strncasecmp(arg, "break", 5)) - flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS; - else if (0 == ::strcasecmp(arg, "commands")) - flag_bits &= ~LIBLLDB_LOG_COMMANDS; - else if (0 == ::strcasecmp(arg, "default")) - flag_bits &= ~LIBLLDB_LOG_DEFAULT; - else if (0 == ::strcasecmp(arg, "dyld")) - flag_bits &= ~LIBLLDB_LOG_DYNAMIC_LOADER; - else if (0 == ::strncasecmp(arg, "event", 5)) - flag_bits &= ~LIBLLDB_LOG_EVENTS; - else if (0 == ::strncasecmp(arg, "expr", 4)) - flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS; - else if (0 == ::strncasecmp(arg, "object", 6)) - flag_bits &= ~LIBLLDB_LOG_OBJECT; - else if (0 == ::strcasecmp(arg, "process")) - flag_bits &= ~LIBLLDB_LOG_PROCESS; - else if (0 == ::strcasecmp(arg, "platform")) - flag_bits &= ~LIBLLDB_LOG_PLATFORM; - else if (0 == ::strcasecmp(arg, "script")) - flag_bits &= ~LIBLLDB_LOG_SCRIPT; - else if (0 == ::strcasecmp(arg, "state")) - flag_bits &= ~LIBLLDB_LOG_STATE; - else if (0 == ::strcasecmp(arg, "step")) - flag_bits &= ~LIBLLDB_LOG_STEP; - else if (0 == ::strcasecmp(arg, "thread")) - flag_bits &= ~LIBLLDB_LOG_THREAD; - else if (0 == ::strcasecmp(arg, "target")) - flag_bits &= ~LIBLLDB_LOG_TARGET; - else if (0 == ::strcasecmp(arg, "verbose")) - flag_bits &= ~LIBLLDB_LOG_VERBOSE; - else if (0 == ::strncasecmp(arg, "watch", 5)) - flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS; - else if (0 == ::strncasecmp(arg, "temp", 4)) - flag_bits &= ~LIBLLDB_LOG_TEMPORARY; - else if (0 == ::strncasecmp(arg, "comm", 4)) - flag_bits &= ~LIBLLDB_LOG_COMMUNICATION; - else if (0 == ::strncasecmp(arg, "conn", 4)) - flag_bits &= ~LIBLLDB_LOG_CONNECTION; - else if (0 == ::strncasecmp(arg, "host", 4)) - flag_bits &= ~LIBLLDB_LOG_HOST; - else if (0 == ::strncasecmp(arg, "unwind", 6)) - flag_bits &= ~LIBLLDB_LOG_UNWIND; - else if (0 == ::strncasecmp(arg, "types", 5)) - flag_bits &= ~LIBLLDB_LOG_TYPES; - else if (0 == ::strncasecmp(arg, "symbol", 6)) - flag_bits &= ~LIBLLDB_LOG_SYMBOLS; - else if (0 == ::strcasecmp(arg, "system-runtime")) - flag_bits &= ~LIBLLDB_LOG_SYSTEM_RUNTIME; - else if (0 == ::strncasecmp(arg, "module", 6)) - flag_bits &= ~LIBLLDB_LOG_MODULES; - else if (0 == ::strncasecmp(arg, "mmap", 4)) - flag_bits &= ~LIBLLDB_LOG_MMAP; - else if (0 == ::strcasecmp(arg, "os")) - flag_bits &= ~LIBLLDB_LOG_OS; - else if (0 == ::strcasecmp(arg, "jit")) - flag_bits &= ~LIBLLDB_LOG_JIT_LOADER; - else if (0 == ::strcasecmp(arg, "language")) - flag_bits &= ~LIBLLDB_LOG_LANGUAGE; - else if (0 == ::strncasecmp(arg, "formatters", 10)) - flag_bits &= ~LIBLLDB_LOG_DATAFORMATTERS; - else if (0 == ::strncasecmp(arg, "demangle", 8)) - flag_bits &= ~LIBLLDB_LOG_DEMANGLE; - else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", - arg); - ListLogCategories(feedback_strm); - return; - } - } - } - log->GetMask().Reset(flag_bits); - if (flag_bits == 0) { - log->SetStream(lldb::StreamSP()); - g_log_enabled = false; - } - } -} - -Log *lldb_private::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, - const char **categories, Stream *feedback_strm) { - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the - // same. - uint32_t flag_bits; - if (g_log != nullptr) - flag_bits = g_log->GetMask().Get(); - else - flag_bits = 0; - - // Now make a new log with this stream if one was provided - if (log_stream_sp) { - if (g_log != nullptr) - g_log->SetStream(log_stream_sp); - else - g_log = new Log(log_stream_sp); - } - - if (g_log != nullptr) { - for (size_t i = 0; categories[i] != nullptr; ++i) { - const char *arg = categories[i]; - - if (0 == ::strcasecmp(arg, "all")) - flag_bits |= LIBLLDB_LOG_ALL; - else if (0 == ::strcasecmp(arg, "api")) - flag_bits |= LIBLLDB_LOG_API; - else if (0 == ::strncasecmp(arg, "break", 5)) - flag_bits |= LIBLLDB_LOG_BREAKPOINTS; - else if (0 == ::strcasecmp(arg, "commands")) - flag_bits |= LIBLLDB_LOG_COMMANDS; - else if (0 == ::strncasecmp(arg, "commu", 5)) - flag_bits |= LIBLLDB_LOG_COMMUNICATION; - else if (0 == ::strncasecmp(arg, "conn", 4)) - flag_bits |= LIBLLDB_LOG_CONNECTION; - else if (0 == ::strcasecmp(arg, "default")) - flag_bits |= LIBLLDB_LOG_DEFAULT; - else if (0 == ::strcasecmp(arg, "dyld")) - flag_bits |= LIBLLDB_LOG_DYNAMIC_LOADER; - else if (0 == ::strncasecmp(arg, "event", 5)) - flag_bits |= LIBLLDB_LOG_EVENTS; - else if (0 == ::strncasecmp(arg, "expr", 4)) - flag_bits |= LIBLLDB_LOG_EXPRESSIONS; - else if (0 == ::strncasecmp(arg, "host", 4)) - flag_bits |= LIBLLDB_LOG_HOST; - else if (0 == ::strncasecmp(arg, "mmap", 4)) - flag_bits |= LIBLLDB_LOG_MMAP; - else if (0 == ::strncasecmp(arg, "module", 6)) - flag_bits |= LIBLLDB_LOG_MODULES; - else if (0 == ::strncasecmp(arg, "object", 6)) - flag_bits |= LIBLLDB_LOG_OBJECT; - else if (0 == ::strcasecmp(arg, "os")) - flag_bits |= LIBLLDB_LOG_OS; - else if (0 == ::strcasecmp(arg, "platform")) - flag_bits |= LIBLLDB_LOG_PLATFORM; - else if (0 == ::strcasecmp(arg, "process")) - flag_bits |= LIBLLDB_LOG_PROCESS; - else if (0 == ::strcasecmp(arg, "script")) - flag_bits |= LIBLLDB_LOG_SCRIPT; - else if (0 == ::strcasecmp(arg, "state")) - flag_bits |= LIBLLDB_LOG_STATE; - else if (0 == ::strcasecmp(arg, "step")) - flag_bits |= LIBLLDB_LOG_STEP; - else if (0 == ::strncasecmp(arg, "symbol", 6)) - flag_bits |= LIBLLDB_LOG_SYMBOLS; - else if (0 == ::strcasecmp(arg, "system-runtime")) - flag_bits |= LIBLLDB_LOG_SYSTEM_RUNTIME; - else if (0 == ::strcasecmp(arg, "target")) - flag_bits |= LIBLLDB_LOG_TARGET; - else if (0 == ::strncasecmp(arg, "temp", 4)) - flag_bits |= LIBLLDB_LOG_TEMPORARY; - else if (0 == ::strcasecmp(arg, "thread")) - flag_bits |= LIBLLDB_LOG_THREAD; - else if (0 == ::strncasecmp(arg, "types", 5)) - flag_bits |= LIBLLDB_LOG_TYPES; - else if (0 == ::strncasecmp(arg, "unwind", 6)) - flag_bits |= LIBLLDB_LOG_UNWIND; - else if (0 == ::strcasecmp(arg, "verbose")) - flag_bits |= LIBLLDB_LOG_VERBOSE; - else if (0 == ::strncasecmp(arg, "watch", 5)) - flag_bits |= LIBLLDB_LOG_WATCHPOINTS; - else if (0 == ::strcasecmp(arg, "jit")) - flag_bits |= LIBLLDB_LOG_JIT_LOADER; - else if (0 == ::strcasecmp(arg, "language")) - flag_bits |= LIBLLDB_LOG_LANGUAGE; - else if (0 == ::strncasecmp(arg, "formatters", 10)) - flag_bits |= LIBLLDB_LOG_DATAFORMATTERS; - else if (0 == ::strncasecmp(arg, "demangle", 8)) - flag_bits |= LIBLLDB_LOG_DEMANGLE; - else { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories(feedback_strm); - return g_log; - } - } - - g_log->GetMask().Reset(flag_bits); - g_log->GetOptions().Reset(log_options); - } - g_log_enabled = true; - return g_log; -} - -void lldb_private::ListLogCategories(Stream *strm) { - strm->Printf( - "Logging categories for 'lldb':\n" - " all - turn on all available logging categories\n" - " api - enable logging of API calls and return values\n" - " break - log breakpoints\n" - " commands - log command argument parsing\n" - " communication - log communication activities\n" - " connection - log connection details\n" - " default - enable the default set of logging categories for liblldb\n" - " demangle - log mangled names to catch demangler crashes\n" - " dyld - log shared library related activities\n" - " events - log broadcaster, listener and event queue activities\n" - " expr - log expressions\n" - " formatters - log data formatters related activities\n" - " host - log host activities\n" - " jit - log JIT events in the target\n" - " language - log language runtime events\n" - " mmap - log mmap related activities\n" - " module - log module activities such as when modules are created, " - "destroyed, replaced, and more\n" - " object - log object construction/destruction for important objects\n" - " os - log OperatingSystem plugin related activities\n" - " platform - log platform events and activities\n" - " process - log process events and activities\n" - " script - log events about the script interpreter\n" - " state - log private and public process state changes\n" - " step - log step related activities\n" - " symbol - log symbol related issues and warnings\n" - " system-runtime - log system runtime events\n" - " target - log target events and activities\n" - " thread - log thread events and activities\n" - " types - log type system related activities\n" - " unwind - log stack unwind activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n"); -} diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index c2c63b665639..3d96340b911c 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -7,10 +7,11 @@ // //===----------------------------------------------------------------------===// -// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h -#include <cstddef> +#include "lldb/Core/Mangled.h" + #if defined(_WIN32) -#include "lldb/Host/windows/windows.h" +#include <windows.h> + #include <dbghelp.h> #pragma comment(lib, "dbghelp.lib") #endif @@ -18,29 +19,55 @@ #ifdef LLDB_USE_BUILTIN_DEMANGLER // Provide a fast-path demangler implemented in FastDemangle.cpp until it can // replace the existing C++ demangler with a complete implementation +#include "lldb/Utility/FastDemangle.h" #include "llvm/Demangle/Demangle.h" -#include "lldb/Core/FastDemangle.h" #else +// FreeBSD9-STABLE requires this to know about size_t in cxxabi. +#include <cstddef> #include <cxxabi.h> #endif -#include "llvm/ADT/DenseMap.h" +#include "lldb/Core/Timer.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" // for LanguageType #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Logging.h" -#include "lldb/Core/Mangled.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/Timer.h" -#include <ctype.h> + +#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/Support/Compiler.h" // for LLVM_PRETT... + +#include <mutex> // for mutex, loc... +#include <string> // for string +#include <utility> // for pair + #include <stdlib.h> #include <string.h> - using namespace lldb_private; +#if defined(_MSC_VER) +static DWORD safeUndecorateName(const char *Mangled, char *Demangled, + DWORD DemangledLength) { + static std::mutex M; + std::lock_guard<std::mutex> Lock(M); + return ::UnDecorateSymbolName( + Mangled, Demangled, DemangledLength, + UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected + // keywords + UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, + // etc keywords + UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications + UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc + // specifiers + UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords + ); +} +#endif + static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) { if (s) { if (s[0] == '?') @@ -253,17 +280,8 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { const size_t demangled_length = 2048; demangled_name = static_cast<char *>(::malloc(demangled_length)); ::ZeroMemory(demangled_name, demangled_length); - DWORD result = ::UnDecorateSymbolName( - mangled_name, demangled_name, demangled_length, - UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected - // keywords - UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, - // etc keywords - UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications - UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc - // specifiers - UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords - ); + DWORD result = + safeUndecorateName(mangled_name, demangled_name, demangled_length); if (log) { if (demangled_name && demangled_name[0]) log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, @@ -414,6 +432,14 @@ lldb::LanguageType Mangled::GuessLanguage() const { else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name)) return lldb::eLanguageTypeObjC; } + } else { + // ObjC names aren't really mangled, so they won't necessarily be in the + // mangled name slot. + ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown); + if (demangled_name + && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString())) + return lldb::eLanguageTypeObjC; + } return lldb::eLanguageTypeUnknown; } diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp index 28f140b41e1e..ddc9fca80671 100644 --- a/source/Core/Module.cpp +++ b/source/Core/Module.cpp @@ -9,46 +9,73 @@ #include "lldb/Core/Module.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/Support/Signals.h" -#include "llvm/Support/raw_os_ostream.h" - -// Project includes -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/AddressResolverFileLine.h" -#include "lldb/Core/DataBuffer.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/ModuleList.h" +#include "lldb/Core/Debugger.h" // for Debugger +#include "lldb/Core/FileSpecList.h" // for FileSpecList +#include "lldb/Core/Mangled.h" // for Mangled #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/SearchFilter.h" // for SearchFilt... #include "lldb/Core/Section.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" -#include "lldb/Host/Symbols.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/Function.h" // for Function #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" // for Symbol #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Symtab.h" // for Symtab +#include "lldb/Symbol/Type.h" // for Type +#include "lldb/Symbol/TypeList.h" // for TypeList #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Language.h" +#include "lldb/Target/Platform.h" // for Platform #include "lldb/Target/Process.h" -#include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAn... +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" + +#if defined(LLVM_ON_WIN32) +#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#endif +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "Plugins/ObjectFile/JIT/ObjectFileJIT.h" +#include "llvm/ADT/STLExtras.h" // for make_unique +#include "llvm/Support/Compiler.h" // for LLVM_PRETT... +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" // for raw_string... + +#include <assert.h> // for assert +#include <cstdint> // for uint32_t +#include <inttypes.h> // for PRIx64 +#include <map> // for map +#include <stdarg.h> // for va_end +#include <string.h> // for size_t +#include <type_traits> // for move +#include <utility> // for find, pair + +namespace lldb_private { +class CompilerDeclContext; +} +namespace lldb_private { +class VariableList; +} + using namespace lldb; using namespace lldb_private; @@ -303,8 +330,7 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, std::lock_guard<std::recursive_mutex> guard(m_mutex); if (process_sp) { m_did_load_objfile = true; - std::unique_ptr<DataBufferHeap> data_ap( - new DataBufferHeap(size_to_read, 0)); + auto data_ap = llvm::make_unique<DataBufferHeap>(size_to_read, 0); Error readmem_error; const size_t bytes_read = process_sp->ReadMemory(header_addr, data_ap->GetBytes(), @@ -719,10 +745,10 @@ Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask, } // Still try and get a basename in case someone specifies a name type mask - // of - // eFunctionNameTypeFull and a name like "A::func" + // of eFunctionNameTypeFull and a name like "A::func" if (basename.empty()) { - if (name_type_mask & eFunctionNameTypeFull) { + if (name_type_mask & eFunctionNameTypeFull && + !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) { CPlusPlusLanguage::MethodName cpp_method(name); basename = cpp_method.GetBasename(); if (basename.empty()) @@ -770,30 +796,39 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, } // If we have only full name matches we might have tried to set breakpoint on - // "func" - // and specified eFunctionNameTypeFull, but we might have found "a::func()", - // "a::b::func()", "c::func()", "func()" and "func". Only "func()" and "func" - // should - // end up matching. + // "func" and specified eFunctionNameTypeFull, but we might have found + // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only + // "func()" and "func" should end up matching. if (m_name_type_mask == eFunctionNameTypeFull) { SymbolContext sc; size_t i = start_idx; while (i < sc_list.GetSize()) { if (!sc_list.GetContextAtIndex(i, sc)) break; + // Make sure the mangled and demangled names don't match before we try + // to pull anything out + ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled)); ConstString full_name(sc.GetFunctionName()); - CPlusPlusLanguage::MethodName cpp_method(full_name); - if (cpp_method.IsValid()) { - if (cpp_method.GetContext().empty()) { - if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) { - sc_list.RemoveContextAtIndex(i); - continue; - } - } else { - std::string qualified_name = cpp_method.GetScopeQualifiedName(); - if (qualified_name.compare(m_name.GetCString()) != 0) { - sc_list.RemoveContextAtIndex(i); - continue; + if (mangled_name != m_name && full_name != m_name) + { + CPlusPlusLanguage::MethodName cpp_method(full_name); + if (cpp_method.IsValid()) { + if (cpp_method.GetContext().empty()) { + if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) { + sc_list.RemoveContextAtIndex(i); + continue; + } + } else { + std::string qualified_name; + llvm::StringRef anon_prefix("(anonymous namespace)"); + if (cpp_method.GetContext() == anon_prefix) + qualified_name = cpp_method.GetBasename().str(); + else + qualified_name = cpp_method.GetScopeQualifiedName(); + if (qualified_name.compare(m_name.GetCString()) != 0) { + sc_list.RemoveContextAtIndex(i); + continue; + } } } } @@ -1022,7 +1057,7 @@ size_t Module::FindTypes( // The "type_name_cstr" will have been modified if we have a valid type // class // prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(sc, ConstString(type_name_cstr), nullptr, append, + FindTypes_Impl(sc, ConstString(type_basename), nullptr, append, max_matches, searched_symbol_files, typesmap); typesmap.RemoveMismatchedTypes(type_class); num_matches = typesmap.GetSize(); @@ -1297,7 +1332,7 @@ void Module::SectionFileAddressesChanged() { SectionList *Module::GetUnifiedSectionList() { // Populate m_unified_sections_ap with sections from objfile. if (!m_sections_ap) - m_sections_ap.reset(new SectionList()); + m_sections_ap = llvm::make_unique<SectionList>(); return m_sections_ap.get(); } @@ -1430,7 +1465,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to // check this - if (file.IsDirectory()) { + if (llvm::sys::fs::is_directory(file.GetPath())) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); if (old_path.find(new_path) == 0) { @@ -1644,7 +1679,8 @@ Module::CreateJITModule(const lldb::ObjectFileJITDelegateSP &delegate_sp) { // to the module, so we need to control the creation carefully in // this static function ModuleSP module_sp(new Module()); - module_sp->m_objfile_sp.reset(new ObjectFileJIT(module_sp, delegate_sp)); + module_sp->m_objfile_sp = + std::make_shared<ObjectFileJIT>(module_sp, delegate_sp); if (module_sp->m_objfile_sp) { // Once we get the object file, update our module with the object file's // architecture since it might differ in vendor/os if some parts were @@ -1664,3 +1700,7 @@ bool Module::GetIsDynamicLinkEditor() { return false; } + +Error Module::LoadInMemory(Target &target, bool set_pc) { + return m_objfile_sp->LoadInMemory(target, set_pc); +} diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp index b980e15c0b37..da23329cc3b6 100644 --- a/source/Core/ModuleList.cpp +++ b/source/Core/ModuleList.cpp @@ -9,22 +9,54 @@ #include "lldb/Core/ModuleList.h" -// C Includes -// C++ Includes -#include <cstdint> -#include <mutex> - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" +#include "lldb/Core/ArchSpec.h" // for ArchSpec +#include "lldb/Core/FileSpecList.h" // for FileSpecList #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" -#include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolContext.h" // for SymbolContextList, SymbolCon... #include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAnyCategoriesSet +#include "lldb/Utility/UUID.h" // for UUID, operator!=, operator== +#include "lldb/lldb-defines.h" // for LLDB_INVALID_INDEX32 + +#if defined(LLVM_ON_WIN32) +#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#endif + +#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Threading.h" +#include "llvm/Support/raw_ostream.h" // for fs + +#include <chrono> // for operator!=, time_point +#include <memory> // for shared_ptr +#include <mutex> +#include <string> // for string +#include <utility> // for distance + +namespace lldb_private { +class Function; +} +namespace lldb_private { +class RegularExpression; +} +namespace lldb_private { +class Stream; +} +namespace lldb_private { +class SymbolFile; +} +namespace lldb_private { +class Target; +} +namespace lldb_private { +class TypeList; +} using namespace lldb; using namespace lldb_private; @@ -644,8 +676,8 @@ size_t ModuleList::GetIndexForModule(const Module *module) const { static ModuleList &GetSharedModuleList() { static ModuleList *g_shared_module_list = nullptr; - static std::once_flag g_once_flag; - std::call_once(g_once_flag, []() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { // NOTE: Intentionally leak the module list so a program doesn't have to // cleanup all modules and object files as it exits. This just wastes time // doing a bunch of cleanup that isn't required. @@ -764,7 +796,8 @@ Error ModuleList::GetSharedModule(const ModuleSpec &module_spec, auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx); if (!search_path_spec.ResolvePath()) continue; - if (!search_path_spec.Exists() || !search_path_spec.IsDirectory()) + namespace fs = llvm::sys::fs; + if (!fs::is_directory(search_path_spec.GetPath())) continue; search_path_spec.AppendPathComponent( module_spec.GetFileSpec().GetFilename().AsCString()); diff --git a/source/Core/Opcode.cpp b/source/Core/Opcode.cpp index 11b913841ecb..b4e691c1ddcd 100644 --- a/source/Core/Opcode.cpp +++ b/source/Core/Opcode.cpp @@ -9,17 +9,15 @@ #include "lldb/Core/Opcode.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/Triple.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" // for DataBufferSP -// Project includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Stream.h" -#include "lldb/Host/Endian.h" +#include <memory> // for make_shared + +#include <inttypes.h> // for PRIx64 using namespace lldb; using namespace lldb_private; @@ -132,7 +130,7 @@ uint32_t Opcode::GetData(DataExtractor &data) const { if (buf != nullptr) { DataBufferSP buffer_sp; - buffer_sp.reset(new DataBufferHeap(buf, byte_size)); + buffer_sp = std::make_shared<DataBufferHeap>(buf, byte_size); data.SetByteOrder(GetDataByteOrder()); data.SetData(buffer_sp); return byte_size; diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp index b7b6b9a54efe..bd4ba5995204 100644 --- a/source/Core/PluginManager.cpp +++ b/source/Core/PluginManager.cpp @@ -9,24 +9,35 @@ #include "lldb/Core/PluginManager.h" -// C Includes -// C++ Includes -#include <climits> +#include "lldb/Core/Debugger.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Interpreter/OptionValueProperties.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Error.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StringList.h" // for StringList + +#if defined(LLVM_ON_WIN32) +#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#endif + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DynamicLibrary.h" +#include "llvm/Support/FileSystem.h" // for file_type, file_... +#include "llvm/Support/raw_ostream.h" // for fs + +#include <map> // for map<>::const_ite... +#include <memory> // for shared_ptr #include <mutex> #include <string> +#include <utility> // for pair #include <vector> -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/DynamicLibrary.h" +#include <assert.h> // for assert -// Project includes -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Error.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Interpreter/OptionValueProperties.h" +namespace lldb_private { +class CommandInterpreter; +} using namespace lldb; using namespace lldb_private; @@ -79,18 +90,18 @@ template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) { } static FileSpec::EnumerateDirectoryResult -LoadPluginCallback(void *baton, FileSpec::FileType file_type, +LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) { // PluginManager *plugin_manager = (PluginManager *)baton; Error error; + namespace fs = llvm::sys::fs; // If we have a regular file, a symbolic link or unknown file type, try // and process the file. We must handle unknown as sometimes the directory // enumeration might be enumerating a file system that doesn't have correct // file type information. - if (file_type == FileSpec::eFileTypeRegular || - file_type == FileSpec::eFileTypeSymbolicLink || - file_type == FileSpec::eFileTypeUnknown) { + if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || + ft == fs::file_type::type_unknown) { FileSpec plugin_file_spec(file_spec); plugin_file_spec.ResolvePath(); @@ -135,9 +146,8 @@ LoadPluginCallback(void *baton, FileSpec::FileType file_type, } } - if (file_type == FileSpec::eFileTypeUnknown || - file_type == FileSpec::eFileTypeDirectory || - file_type == FileSpec::eFileTypeSymbolicLink) { + if (ft == fs::file_type::directory_file || + ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { // Try and recurse into anything that a directory or symbolic link. // We must also do this for unknown as sometimes the directory enumeration // might be enumerating a file system that doesn't have correct file type @@ -1167,93 +1177,6 @@ PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( return nullptr; } -#pragma mark LogChannel - -struct LogInstance { - LogInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - LogChannelCreateInstance create_callback; -}; - -typedef std::vector<LogInstance> LogInstances; - -static std::recursive_mutex &GetLogMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} - -static LogInstances &GetLogInstances() { - static LogInstances g_instances; - return g_instances; -} - -bool PluginManager::RegisterPlugin(const ConstString &name, - const char *description, - LogChannelCreateInstance create_callback) { - if (create_callback) { - LogInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> gard(GetLogMutex()); - GetLogInstances().push_back(instance); - } - return false; -} - -bool PluginManager::UnregisterPlugin(LogChannelCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> gard(GetLogMutex()); - LogInstances &instances = GetLogInstances(); - - LogInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; -} - -const char *PluginManager::GetLogChannelCreateNameAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> gard(GetLogMutex()); - LogInstances &instances = GetLogInstances(); - if (idx < instances.size()) - return instances[idx].name.GetCString(); - return nullptr; -} - -LogChannelCreateInstance -PluginManager::GetLogChannelCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> gard(GetLogMutex()); - LogInstances &instances = GetLogInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -LogChannelCreateInstance -PluginManager::GetLogChannelCreateCallbackForPluginName( - const ConstString &name) { - if (name) { - std::lock_guard<std::recursive_mutex> gard(GetLogMutex()); - LogInstances &instances = GetLogInstances(); - - LogInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; -} - #pragma mark Platform struct PlatformInstance { @@ -2403,7 +2326,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, g_property_name); if (!plugin_properties_sp && can_create) { - plugin_properties_sp.reset(new OptionValueProperties(g_property_name)); + plugin_properties_sp = + std::make_shared<OptionValueProperties>(g_property_name); parent_properties_sp->AppendProperty( g_property_name, ConstString("Settings specify to plugins."), true, plugin_properties_sp); @@ -2413,8 +2337,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins( lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name); if (!plugin_type_properties_sp && can_create) { - plugin_type_properties_sp.reset( - new OptionValueProperties(plugin_type_name)); + plugin_type_properties_sp = + std::make_shared<OptionValueProperties>(plugin_type_name); plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, true, plugin_type_properties_sp); } @@ -2437,7 +2361,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, plugin_type_name); if (!plugin_properties_sp && can_create) { - plugin_properties_sp.reset(new OptionValueProperties(plugin_type_name)); + plugin_properties_sp = + std::make_shared<OptionValueProperties>(plugin_type_name); parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc, true, plugin_properties_sp); } @@ -2446,8 +2371,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, g_property_name); if (!plugin_type_properties_sp && can_create) { - plugin_type_properties_sp.reset( - new OptionValueProperties(g_property_name)); + plugin_type_properties_sp = + std::make_shared<OptionValueProperties>(g_property_name); plugin_properties_sp->AppendProperty( g_property_name, ConstString("Settings specific to plugins"), true, plugin_type_properties_sp); diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp index 2bc0b9dd4743..26a7515febc3 100644 --- a/source/Core/RegisterValue.cpp +++ b/source/Core/RegisterValue.cpp @@ -9,22 +9,27 @@ #include "lldb/Core/RegisterValue.h" -// C Includes -// C++ Includes -#include <vector> +#include "lldb/Core/DumpDataExtractor.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-private-types.h" // for RegisterInfo, type128 -// Other libraries and framework includes #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -// Project includes -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/Args.h" +#include <cstdint> // for uint8_t, uint32_t, uint64_t +#include <string> // for string +#include <tuple> // for tie, tuple +#include <vector> + +#include <assert.h> // for assert +#include <inttypes.h> // for PRIx64 +#include <stdio.h> // for sscanf using namespace lldb; using namespace lldb_private; @@ -76,15 +81,15 @@ bool RegisterValue::Dump(Stream *s, const RegisterInfo *reg_info, if (format == eFormatDefault) format = reg_info->format; - data.Dump(s, - 0, // Offset in "data" - format, // Format to use when dumping - reg_info->byte_size, // item_byte_size - 1, // item_count - UINT32_MAX, // num_per_line - LLDB_INVALID_ADDRESS, // base_addr - 0, // item_bit_size - 0); // item_bit_offset + DumpDataExtractor(data, s, + 0, // Offset in "data" + format, // Format to use when dumping + reg_info->byte_size, // item_byte_size + 1, // item_count + UINT32_MAX, // num_per_line + LLDB_INVALID_ADDRESS, // base_addr + 0, // item_bit_size + 0); // item_bit_offset return true; } return false; diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp deleted file mode 100644 index 54e0231556db..000000000000 --- a/source/Core/RegularExpression.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//===-- RegularExpression.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/RegularExpression.h" - -// C Includes -// C++ Includes -#include <cstring> - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "lldb/Core/Error.h" - -//---------------------------------------------------------------------- -// Enable enhanced mode if it is available. This allows for things like -// \d for digit, \s for space, and many more, but it isn't available -// everywhere. -//---------------------------------------------------------------------- -#if defined(REG_ENHANCED) -#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED) -#else -#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED) -#endif - -using namespace lldb_private; - -RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() { - memset(&m_preg, 0, sizeof(m_preg)); -} - -//---------------------------------------------------------------------- -// Constructor that compiles "re" using "flags" and stores the -// resulting compiled regular expression into this object. -//---------------------------------------------------------------------- -RegularExpression::RegularExpression(llvm::StringRef str) - : m_re(), m_comp_err(1), m_preg() { - memset(&m_preg, 0, sizeof(m_preg)); - Compile(str); -} - -RegularExpression::RegularExpression(const RegularExpression &rhs) { - memset(&m_preg, 0, sizeof(m_preg)); - Compile(rhs.GetText()); -} - -const RegularExpression &RegularExpression:: -operator=(const RegularExpression &rhs) { - if (&rhs != this) - Compile(rhs.GetText()); - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -// -// Any previously compiled regular expression contained in this -// object will be freed. -//---------------------------------------------------------------------- -RegularExpression::~RegularExpression() { Free(); } - -//---------------------------------------------------------------------- -// Compile a regular expression using the supplied regular -// expression text and flags. The compiled regular expression lives -// in this object so that it can be readily used for regular -// expression matches. Execute() can be called after the regular -// expression is compiled. Any previously compiled regular -// expression contained in this object will be freed. -// -// RETURNS -// True if the regular expression compiles successfully, false -// otherwise. -//---------------------------------------------------------------------- -bool RegularExpression::Compile(llvm::StringRef str) { - Free(); - - if (!str.empty()) { - m_re = str; - m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS); - } else { - // No valid regular expression - m_comp_err = 1; - } - - return m_comp_err == 0; -} - -//---------------------------------------------------------------------- -// Execute a regular expression match using the compiled regular -// expression that is already in this object against the match -// string "s". If any parens are used for regular expression -// matches "match_count" should indicate the number of regmatch_t -// values that are present in "match_ptr". The regular expression -// will be executed using the "execute_flags". -//--------------------------------------------------------------------- -bool RegularExpression::Execute(llvm::StringRef str, Match *match) const { - int err = 1; - if (m_comp_err == 0) { - // Argument to regexec must be null-terminated. - std::string reg_str = str; - if (match) { - err = ::regexec(&m_preg, reg_str.c_str(), match->GetSize(), - match->GetData(), 0); - } else { - err = ::regexec(&m_preg, reg_str.c_str(), 0, nullptr, 0); - } - } - - if (err != 0) { - // The regular expression didn't compile, so clear the matches - if (match) - match->Clear(); - return false; - } - return true; -} - -bool RegularExpression::Match::GetMatchAtIndex(llvm::StringRef s, uint32_t idx, - std::string &match_str) const { - llvm::StringRef match_str_ref; - if (GetMatchAtIndex(s, idx, match_str_ref)) { - match_str = match_str_ref.str(); - return true; - } - return false; -} - -bool RegularExpression::Match::GetMatchAtIndex( - llvm::StringRef s, uint32_t idx, llvm::StringRef &match_str) const { - if (idx < m_matches.size()) { - if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1) - return false; - - if (m_matches[idx].rm_eo == m_matches[idx].rm_so) { - // Matched the empty string... - match_str = llvm::StringRef(); - return true; - } else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) { - match_str = s.substr(m_matches[idx].rm_so, - m_matches[idx].rm_eo - m_matches[idx].rm_so); - return true; - } - } - return false; -} - -bool RegularExpression::Match::GetMatchSpanningIndices( - llvm::StringRef s, uint32_t idx1, uint32_t idx2, - llvm::StringRef &match_str) const { - if (idx1 < m_matches.size() && idx2 < m_matches.size()) { - if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) { - // Matched the empty string... - match_str = llvm::StringRef(); - return true; - } else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) { - match_str = s.substr(m_matches[idx1].rm_so, - m_matches[idx2].rm_eo - m_matches[idx1].rm_so); - return true; - } - } - return false; -} - -//---------------------------------------------------------------------- -// Returns true if the regular expression compiled and is ready -// for execution. -//---------------------------------------------------------------------- -bool RegularExpression::IsValid() const { return m_comp_err == 0; } - -//---------------------------------------------------------------------- -// Returns the text that was used to compile the current regular -// expression. -//---------------------------------------------------------------------- -llvm::StringRef RegularExpression::GetText() const { return m_re; } - -//---------------------------------------------------------------------- -// Free any contained compiled regular expressions. -//---------------------------------------------------------------------- -void RegularExpression::Free() { - if (m_comp_err == 0) { - m_re.clear(); - regfree(&m_preg); - // Set a compile error since we no longer have a valid regex - m_comp_err = 1; - } -} - -size_t RegularExpression::GetErrorAsCString(char *err_str, - size_t err_str_max_len) const { - if (m_comp_err == 0) { - if (err_str && err_str_max_len) - *err_str = '\0'; - return 0; - } - - return ::regerror(m_comp_err, &m_preg, err_str, err_str_max_len); -} - -bool RegularExpression::operator<(const RegularExpression &rhs) const { - return (m_re < rhs.m_re); -} diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp index 2b99ec17b0a0..88ad430ddbae 100644 --- a/source/Core/Scalar.cpp +++ b/source/Core/Scalar.cpp @@ -9,24 +9,17 @@ #include "lldb/Core/Scalar.h" -// C Includes -// C++ Includes -#include <cinttypes> -#include <cmath> -#include <cstdio> +#include "lldb/Host/StringConvert.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-types.h" // for offset_t -// Other libraries and framework includes #include "llvm/ADT/SmallString.h" -// Project includes -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Stream.h" -#include "lldb/Host/Endian.h" -#include "lldb/Host/StringConvert.h" -#include "lldb/Interpreter/Args.h" - -#include "Plugins/Process/Utility/InstructionUtils.h" +#include <cinttypes> +#include <cstdio> using namespace lldb; using namespace lldb_private; diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp index 2dfb26910ee0..6d29e21c310e 100644 --- a/source/Core/SearchFilter.cpp +++ b/source/Core/SearchFilter.cpp @@ -7,16 +7,35 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes - -// Other libraries and framework includes -// Project includes #include "lldb/Core/SearchFilter.h" + +#include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Target/Target.h" -#include "lldb/lldb-private.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/lldb-enumerations.h" // for SymbolContextItem::eSymbolCo... + +#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable + +#include <memory> // for shared_ptr +#include <mutex> // for recursive_mutex, lock_guard +#include <string> // for string + +#include <inttypes.h> // for PRIu64 +#include <string.h> // for size_t, strcmp + +namespace lldb_private { +class Address; +} +namespace lldb_private { +class Function; +} using namespace lldb; using namespace lldb_private; @@ -153,7 +172,7 @@ SearchFilter::WrapOptionsDict(StructuredData::DictionarySP options_dict_sp) { if (!options_dict_sp || !options_dict_sp->IsValid()) return StructuredData::DictionarySP(); - StructuredData::DictionarySP type_dict_sp(new StructuredData::Dictionary()); + auto type_dict_sp = std::make_shared<StructuredData::Dictionary>(); type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetFilterName()); type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp); @@ -169,10 +188,10 @@ void SearchFilter::SerializeFileSpecList( if (num_modules == 0) return; - StructuredData::ArraySP module_array_sp(new StructuredData::Array()); + auto module_array_sp = std::make_shared<StructuredData::Array>(); for (size_t i = 0; i < num_modules; i++) { - module_array_sp->AddItem(StructuredData::StringSP( - new StructuredData::String(file_list.GetFileSpecAtIndex(i).GetPath()))); + module_array_sp->AddItem(std::make_shared<StructuredData::String>( + file_list.GetFileSpecAtIndex(i).GetPath())); } options_dict_sp->AddItem(GetKey(name), module_array_sp); } @@ -321,14 +340,14 @@ Searcher::CallbackReturn SearchFilter::DoFunctionIteration( SearchFilterSP SearchFilterForUnconstrainedSearches::CreateFromStructuredData( Target &target, const StructuredData::Dictionary &data_dict, Error &error) { // No options for an unconstrained search. - return SearchFilterSP( - new SearchFilterForUnconstrainedSearches(target.shared_from_this())); + return std::make_shared<SearchFilterForUnconstrainedSearches>( + target.shared_from_this()); } StructuredData::ObjectSP SearchFilterForUnconstrainedSearches::SerializeToStructuredData() { // The options dictionary is an empty dictionary: - StructuredData::DictionarySP result_sp(new StructuredData::Dictionary()); + auto result_sp = std::make_shared<StructuredData::Dictionary>(); return WrapOptionsDict(result_sp); } @@ -352,8 +371,7 @@ bool SearchFilterForUnconstrainedSearches::ModulePasses( lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint( Breakpoint &breakpoint) { - SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this)); - return ret_sp; + return std::make_shared<SearchFilterForUnconstrainedSearches>(*this); } //---------------------------------------------------------------------- @@ -433,13 +451,7 @@ void SearchFilterByModule::Search(Searcher &searcher) { void SearchFilterByModule::GetDescription(Stream *s) { s->PutCString(", module = "); - if (s->GetVerbose()) { - char buffer[2048]; - m_module_spec.GetPath(buffer, 2047); - s->PutCString(buffer); - } else { - s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>")); - } + s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>")); } uint32_t SearchFilterByModule::GetFilterRequiredItems() { @@ -450,8 +462,7 @@ void SearchFilterByModule::Dump(Stream *s) const {} lldb::SearchFilterSP SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) { - SearchFilterSP ret_sp(new SearchFilterByModule(*this)); - return ret_sp; + return std::make_shared<SearchFilterByModule>(*this); } SearchFilterSP SearchFilterByModule::CreateFromStructuredData( @@ -479,16 +490,15 @@ SearchFilterSP SearchFilterByModule::CreateFromStructuredData( } FileSpec module_spec(module, false); - return SearchFilterSP( - new SearchFilterByModule(target.shared_from_this(), module_spec)); + return std::make_shared<SearchFilterByModule>(target.shared_from_this(), + module_spec); } StructuredData::ObjectSP SearchFilterByModule::SerializeToStructuredData() { - StructuredData::DictionarySP options_dict_sp( - new StructuredData::Dictionary()); - StructuredData::ArraySP module_array_sp(new StructuredData::Array()); - module_array_sp->AddItem(StructuredData::StringSP( - new StructuredData::String(m_module_spec.GetPath()))); + auto options_dict_sp = std::make_shared<StructuredData::Dictionary>(); + auto module_array_sp = std::make_shared<StructuredData::Array>(); + module_array_sp->AddItem( + std::make_shared<StructuredData::String>(m_module_spec.GetPath())); options_dict_sp->AddItem(GetKey(OptionNames::ModList), module_array_sp); return WrapOptionsDict(options_dict_sp); } @@ -591,27 +601,15 @@ void SearchFilterByModuleList::GetDescription(Stream *s) { size_t num_modules = m_module_spec_list.GetSize(); if (num_modules == 1) { s->Printf(", module = "); - if (s->GetVerbose()) { - char buffer[2048]; - m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); - s->PutCString(buffer); - } else { - s->PutCString( - m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString( - "<Unknown>")); - } + s->PutCString( + m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString( + "<Unknown>")); } else { s->Printf(", modules(%" PRIu64 ") = ", (uint64_t)num_modules); for (size_t i = 0; i < num_modules; i++) { - if (s->GetVerbose()) { - char buffer[2048]; - m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); - s->PutCString(buffer); - } else { - s->PutCString( - m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString( - "<Unknown>")); - } + s->PutCString( + m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString( + "<Unknown>")); if (i != num_modules - 1) s->PutCString(", "); } @@ -626,8 +624,7 @@ void SearchFilterByModuleList::Dump(Stream *s) const {} lldb::SearchFilterSP SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) { - SearchFilterSP ret_sp(new SearchFilterByModuleList(*this)); - return ret_sp; + return std::make_shared<SearchFilterByModuleList>(*this); } SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( @@ -650,8 +647,8 @@ SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( } } - return SearchFilterSP( - new SearchFilterByModuleList(target.shared_from_this(), modules)); + return std::make_shared<SearchFilterByModuleList>(target.shared_from_this(), + modules); } void SearchFilterByModuleList::SerializeUnwrapped( @@ -661,8 +658,7 @@ void SearchFilterByModuleList::SerializeUnwrapped( } StructuredData::ObjectSP SearchFilterByModuleList::SerializeToStructuredData() { - StructuredData::DictionarySP options_dict_sp( - new StructuredData::Dictionary()); + auto options_dict_sp = std::make_shared<StructuredData::Dictionary>(); SerializeUnwrapped(options_dict_sp); return WrapOptionsDict(options_dict_sp); } @@ -736,14 +732,13 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( cus.Append(FileSpec(cu, false)); } - return SearchFilterSP(new SearchFilterByModuleListAndCU( - target.shared_from_this(), modules, cus)); + return std::make_shared<SearchFilterByModuleListAndCU>( + target.shared_from_this(), modules, cus); } StructuredData::ObjectSP SearchFilterByModuleListAndCU::SerializeToStructuredData() { - StructuredData::DictionarySP options_dict_sp( - new StructuredData::Dictionary()); + auto options_dict_sp = std::make_shared<StructuredData::Dictionary>(); SearchFilterByModuleList::SerializeUnwrapped(options_dict_sp); SerializeFileSpecList(options_dict_sp, OptionNames::CUList, m_cu_spec_list); return WrapOptionsDict(options_dict_sp); @@ -827,27 +822,15 @@ void SearchFilterByModuleListAndCU::GetDescription(Stream *s) { size_t num_modules = m_module_spec_list.GetSize(); if (num_modules == 1) { s->Printf(", module = "); - if (s->GetVerbose()) { - char buffer[2048]; - m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); - s->PutCString(buffer); - } else { - s->PutCString( - m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString( - "<Unknown>")); - } + s->PutCString( + m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString( + "<Unknown>")); } else if (num_modules > 0) { s->Printf(", modules(%" PRIu64 ") = ", static_cast<uint64_t>(num_modules)); for (size_t i = 0; i < num_modules; i++) { - if (s->GetVerbose()) { - char buffer[2048]; - m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); - s->PutCString(buffer); - } else { - s->PutCString( - m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString( - "<Unknown>")); - } + s->PutCString( + m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString( + "<Unknown>")); if (i != num_modules - 1) s->PutCString(", "); } @@ -862,6 +845,5 @@ void SearchFilterByModuleListAndCU::Dump(Stream *s) const {} lldb::SearchFilterSP SearchFilterByModuleListAndCU::DoCopyForBreakpoint(Breakpoint &breakpoint) { - SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this)); - return ret_sp; + return std::make_shared<SearchFilterByModuleListAndCU>(*this); } diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp index 95bcdada5377..f6428ced0164 100644 --- a/source/Core/Section.cpp +++ b/source/Core/Section.cpp @@ -8,15 +8,119 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/Section.h" +#include "lldb/Core/Address.h" // for Address #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConvertEnum.h" +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/VMRange.h" // for VMRange +#include <inttypes.h> // for PRIx64 +#include <limits> // for numeric_limits +#include <utility> // for distance + +namespace lldb_private { +class DataExtractor; +} using namespace lldb; using namespace lldb_private; +static const char *GetSectionTypeAsCString(lldb::SectionType sect_type) { + switch (sect_type) { + case eSectionTypeInvalid: + return "invalid"; + case eSectionTypeCode: + return "code"; + case eSectionTypeContainer: + return "container"; + case eSectionTypeData: + return "data"; + case eSectionTypeDataCString: + return "data-cstr"; + case eSectionTypeDataCStringPointers: + return "data-cstr-ptr"; + case eSectionTypeDataSymbolAddress: + return "data-symbol-addr"; + case eSectionTypeData4: + return "data-4-byte"; + case eSectionTypeData8: + return "data-8-byte"; + case eSectionTypeData16: + return "data-16-byte"; + case eSectionTypeDataPointers: + return "data-ptrs"; + case eSectionTypeDebug: + return "debug"; + case eSectionTypeZeroFill: + return "zero-fill"; + case eSectionTypeDataObjCMessageRefs: + return "objc-message-refs"; + case eSectionTypeDataObjCCFStrings: + return "objc-cfstrings"; + case eSectionTypeDWARFDebugAbbrev: + return "dwarf-abbrev"; + case eSectionTypeDWARFDebugAddr: + return "dwarf-addr"; + case eSectionTypeDWARFDebugAranges: + return "dwarf-aranges"; + case eSectionTypeDWARFDebugFrame: + return "dwarf-frame"; + case eSectionTypeDWARFDebugInfo: + return "dwarf-info"; + case eSectionTypeDWARFDebugLine: + return "dwarf-line"; + case eSectionTypeDWARFDebugLoc: + return "dwarf-loc"; + case eSectionTypeDWARFDebugMacInfo: + return "dwarf-macinfo"; + case eSectionTypeDWARFDebugMacro: + return "dwarf-macro"; + case eSectionTypeDWARFDebugPubNames: + return "dwarf-pubnames"; + case eSectionTypeDWARFDebugPubTypes: + return "dwarf-pubtypes"; + case eSectionTypeDWARFDebugRanges: + return "dwarf-ranges"; + case eSectionTypeDWARFDebugStr: + return "dwarf-str"; + case eSectionTypeDWARFDebugStrOffsets: + return "dwarf-str-offsets"; + case eSectionTypeELFSymbolTable: + return "elf-symbol-table"; + case eSectionTypeELFDynamicSymbols: + return "elf-dynamic-symbols"; + case eSectionTypeELFRelocationEntries: + return "elf-relocation-entries"; + case eSectionTypeELFDynamicLinkInfo: + return "elf-dynamic-link-info"; + case eSectionTypeDWARFAppleNames: + return "apple-names"; + case eSectionTypeDWARFAppleTypes: + return "apple-types"; + case eSectionTypeDWARFAppleNamespaces: + return "apple-namespaces"; + case eSectionTypeDWARFAppleObjC: + return "apple-objc"; + case eSectionTypeEHFrame: + return "eh-frame"; + case eSectionTypeARMexidx: + return "ARM.exidx"; + case eSectionTypeARMextab: + return "ARM.extab"; + case eSectionTypeCompactUnwind: + return "compact-unwind"; + case eSectionTypeGoSymtab: + return "go-symtab"; + case eSectionTypeAbsoluteAddress: + return "absolute"; + case eSectionTypeOther: + return "regular"; + } + return "unknown"; +} + Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file, user_id_t sect_id, const ConstString &name, SectionType sect_type, addr_t file_addr, addr_t byte_size, diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp index 603fe5711498..b284ff1dbaaa 100644 --- a/source/Core/SourceManager.cpp +++ b/source/Core/SourceManager.cpp @@ -9,21 +9,40 @@ #include "lldb/Core/SourceManager.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/DataBuffer.h" +#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/Debugger.h" +#include "lldb/Core/FormatEntity.h" // for FormatEntity #include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" +#include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" +#include "lldb/Symbol/LineEntry.h" // for LineEntry #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/PathMappingList.h" // for PathMappingList #include "lldb/Target/Target.h" -#include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" // for StopShowColumn::eStopSho... + +#include "llvm/ADT/Twine.h" // for Twine + +#include <memory> +#include <utility> // for pair + +#include <assert.h> // for assert +#include <stdio.h> // for size_t, NULL, snprintf + +namespace lldb_private { +class ExecutionContext; +} +namespace lldb_private { +class ValueObject; +} using namespace lldb; using namespace lldb_private; @@ -74,9 +93,9 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { // If file_sp is no good or it points to a non-existent file, reset it. if (!file_sp || !file_sp->GetFileSpec().Exists()) { if (target_sp) - file_sp.reset(new File(file_spec, target_sp.get())); + file_sp = std::make_shared<File>(file_spec, target_sp.get()); else - file_sp.reset(new File(file_spec, debugger_sp)); + file_sp = std::make_shared<File>(file_spec, debugger_sp); if (debugger_sp) debugger_sp->GetSourceFileCache().AddSourceFile(file_sp); @@ -404,7 +423,7 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, } if (m_mod_time != llvm::sys::TimePoint<>()) - m_data_sp = m_file_spec.ReadFileContents(); + m_data_sp = DataBufferLLVM::CreateFromPath(m_file_spec.GetPath()); } uint32_t SourceManager::File::GetLineOffset(uint32_t line) { @@ -482,7 +501,7 @@ void SourceManager::File::UpdateIfNeeded() { if (curr_mod_time != llvm::sys::TimePoint<>() && m_mod_time != curr_mod_time) { m_mod_time = curr_mod_time; - m_data_sp = m_file_spec.ReadFileContents(); + m_data_sp = DataBufferLLVM::CreateFromPath(m_file_spec.GetPath()); m_offsets.clear(); } } diff --git a/source/Core/State.cpp b/source/Core/State.cpp index 80497dd77b87..4697ca4b5f17 100644 --- a/source/Core/State.cpp +++ b/source/Core/State.cpp @@ -12,7 +12,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/State.h" -#include <stdio.h> using namespace lldb; using namespace lldb_private; @@ -44,10 +43,7 @@ const char *lldb_private::StateAsCString(StateType state) { case eStateSuspended: return "suspended"; } - static char unknown_state_string[64]; - snprintf(unknown_state_string, sizeof(unknown_state_string), "StateType = %i", - state); - return unknown_state_string; + return "unknown"; } const char *lldb_private::GetPermissionsAsCString(uint32_t permissions) { diff --git a/source/Core/Stream.cpp b/source/Core/Stream.cpp deleted file mode 100644 index 2f9c650ee5b0..000000000000 --- a/source/Core/Stream.cpp +++ /dev/null @@ -1,630 +0,0 @@ -//===-- Stream.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/Stream.h" -#include "lldb/Host/Endian.h" -#include "lldb/Host/PosixApi.h" -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <inttypes.h> - -using namespace lldb; -using namespace lldb_private; - -Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) - : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0) {} - -Stream::Stream() - : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0) {} - -//------------------------------------------------------------------ -// Destructor -//------------------------------------------------------------------ -Stream::~Stream() {} - -ByteOrder Stream::SetByteOrder(ByteOrder byte_order) { - ByteOrder old_byte_order = m_byte_order; - m_byte_order = byte_order; - return old_byte_order; -} - -//------------------------------------------------------------------ -// Put an offset "uval" out to the stream using the printf format -// in "format". -//------------------------------------------------------------------ -void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); } - -//------------------------------------------------------------------ -// Put an SLEB128 "uval" out to the stream using the printf format -// in "format". -//------------------------------------------------------------------ -size_t Stream::PutSLEB128(int64_t sval) { - size_t bytes_written = 0; - if (m_flags.Test(eBinary)) { - bool more = true; - while (more) { - uint8_t byte = sval & 0x7fu; - sval >>= 7; - /* sign bit of byte is 2nd high order bit (0x40) */ - if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40))) - more = false; - else - // more bytes to come - byte |= 0x80u; - bytes_written += Write(&byte, 1); - } - } else { - bytes_written = Printf("0x%" PRIi64, sval); - } - - return bytes_written; -} - -//------------------------------------------------------------------ -// Put an ULEB128 "uval" out to the stream using the printf format -// in "format". -//------------------------------------------------------------------ -size_t Stream::PutULEB128(uint64_t uval) { - size_t bytes_written = 0; - if (m_flags.Test(eBinary)) { - do { - - uint8_t byte = uval & 0x7fu; - uval >>= 7; - if (uval != 0) { - // more bytes to come - byte |= 0x80u; - } - bytes_written += Write(&byte, 1); - } while (uval != 0); - } else { - bytes_written = Printf("0x%" PRIx64, uval); - } - return bytes_written; -} - -//------------------------------------------------------------------ -// Print a raw NULL terminated C string to the stream. -//------------------------------------------------------------------ -size_t Stream::PutCString(llvm::StringRef str) { - size_t bytes_written = 0; - bytes_written = Write(str.data(), str.size()); - - // when in binary mode, emit the NULL terminator - if (m_flags.Test(eBinary)) - bytes_written += PutChar('\0'); - return bytes_written; -} - -//------------------------------------------------------------------ -// Print a double quoted NULL terminated C string to the stream -// using the printf format in "format". -//------------------------------------------------------------------ -void Stream::QuotedCString(const char *cstr, const char *format) { - Printf(format, cstr); -} - -//------------------------------------------------------------------ -// Put an address "addr" out to the stream with optional prefix -// and suffix strings. -//------------------------------------------------------------------ -void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix, - const char *suffix) { - if (prefix == NULL) - prefix = ""; - if (suffix == NULL) - suffix = ""; - // int addr_width = m_addr_size << 1; - // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix); - Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix); -} - -//------------------------------------------------------------------ -// Put an address range out to the stream with optional prefix -// and suffix strings. -//------------------------------------------------------------------ -void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, - uint32_t addr_size, const char *prefix, - const char *suffix) { - if (prefix && prefix[0]) - PutCString(prefix); - Address(lo_addr, addr_size, "["); - Address(hi_addr, addr_size, "-", ")"); - if (suffix && suffix[0]) - PutCString(suffix); -} - -size_t Stream::PutChar(char ch) { return Write(&ch, 1); } - -//------------------------------------------------------------------ -// Print some formatted output to the stream. -//------------------------------------------------------------------ -size_t Stream::Printf(const char *format, ...) { - va_list args; - va_start(args, format); - size_t result = PrintfVarArg(format, args); - va_end(args); - return result; -} - -//------------------------------------------------------------------ -// Print some formatted output to the stream. -//------------------------------------------------------------------ -size_t Stream::PrintfVarArg(const char *format, va_list args) { - char str[1024]; - va_list args_copy; - - va_copy(args_copy, args); - - size_t bytes_written = 0; - // Try and format our string into a fixed buffer first and see if it fits - size_t length = ::vsnprintf(str, sizeof(str), format, args); - if (length < sizeof(str)) { - // Include the NULL termination byte for binary output - if (m_flags.Test(eBinary)) - length += 1; - // The formatted string fit into our stack based buffer, so we can just - // append that to our packet - bytes_written = Write(str, length); - } else { - // Our stack buffer wasn't big enough to contain the entire formatted - // string, so lets let vasprintf create the string for us! - char *str_ptr = NULL; - length = ::vasprintf(&str_ptr, format, args_copy); - if (str_ptr) { - // Include the NULL termination byte for binary output - if (m_flags.Test(eBinary)) - length += 1; - bytes_written = Write(str_ptr, length); - ::free(str_ptr); - } - } - va_end(args_copy); - return bytes_written; -} - -//------------------------------------------------------------------ -// Print and End of Line character to the stream -//------------------------------------------------------------------ -size_t Stream::EOL() { return PutChar('\n'); } - -//------------------------------------------------------------------ -// Indent the current line using the current indentation level and -// print an optional string following the indentation spaces. -//------------------------------------------------------------------ -size_t Stream::Indent(const char *s) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : ""); -} - -size_t Stream::Indent(llvm::StringRef str) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", str.str().c_str()); -} - -//------------------------------------------------------------------ -// Stream a character "ch" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(char ch) { - PutChar(ch); - return *this; -} - -//------------------------------------------------------------------ -// Stream the NULL terminated C string out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(const char *s) { - Printf("%s", s); - return *this; -} - -Stream &Stream::operator<<(llvm::StringRef str) { - Write(str.data(), str.size()); - return *this; -} - -//------------------------------------------------------------------ -// Stream the pointer value out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(const void *p) { - Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p); - return *this; -} - -//------------------------------------------------------------------ -// Stream a uint8_t "uval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(uint8_t uval) { - PutHex8(uval); - return *this; -} - -//------------------------------------------------------------------ -// Stream a uint16_t "uval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(uint16_t uval) { - PutHex16(uval, m_byte_order); - return *this; -} - -//------------------------------------------------------------------ -// Stream a uint32_t "uval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(uint32_t uval) { - PutHex32(uval, m_byte_order); - return *this; -} - -//------------------------------------------------------------------ -// Stream a uint64_t "uval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(uint64_t uval) { - PutHex64(uval, m_byte_order); - return *this; -} - -//------------------------------------------------------------------ -// Stream a int8_t "sval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(int8_t sval) { - Printf("%i", (int)sval); - return *this; -} - -//------------------------------------------------------------------ -// Stream a int16_t "sval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(int16_t sval) { - Printf("%i", (int)sval); - return *this; -} - -//------------------------------------------------------------------ -// Stream a int32_t "sval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(int32_t sval) { - Printf("%i", (int)sval); - return *this; -} - -//------------------------------------------------------------------ -// Stream a int64_t "sval" out to this stream. -//------------------------------------------------------------------ -Stream &Stream::operator<<(int64_t sval) { - Printf("%" PRIi64, sval); - return *this; -} - -//------------------------------------------------------------------ -// Get the current indentation level -//------------------------------------------------------------------ -int Stream::GetIndentLevel() const { return m_indent_level; } - -//------------------------------------------------------------------ -// Set the current indentation level -//------------------------------------------------------------------ -void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; } - -//------------------------------------------------------------------ -// Increment the current indentation level -//------------------------------------------------------------------ -void Stream::IndentMore(int amount) { m_indent_level += amount; } - -//------------------------------------------------------------------ -// Decrement the current indentation level -//------------------------------------------------------------------ -void Stream::IndentLess(int amount) { - if (m_indent_level >= amount) - m_indent_level -= amount; - else - m_indent_level = 0; -} - -//------------------------------------------------------------------ -// Get the address size in bytes -//------------------------------------------------------------------ -uint32_t Stream::GetAddressByteSize() const { return m_addr_size; } - -//------------------------------------------------------------------ -// Set the address size in bytes -//------------------------------------------------------------------ -void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; } - -//------------------------------------------------------------------ -// Returns true if the verbose flag bit is set in this stream. -//------------------------------------------------------------------ -bool Stream::GetVerbose() const { return m_flags.Test(eVerbose); } - -//------------------------------------------------------------------ -// Returns true if the debug flag bit is set in this stream. -//------------------------------------------------------------------ -bool Stream::GetDebug() const { return m_flags.Test(eDebug); } - -//------------------------------------------------------------------ -// The flags get accessor -//------------------------------------------------------------------ -Flags &Stream::GetFlags() { return m_flags; } - -//------------------------------------------------------------------ -// The flags const get accessor -//------------------------------------------------------------------ -const Flags &Stream::GetFlags() const { return m_flags; } - -//------------------------------------------------------------------ -// The byte order get accessor -//------------------------------------------------------------------ - -lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; } - -size_t Stream::PrintfAsRawHex8(const char *format, ...) { - va_list args; - va_list args_copy; - va_start(args, format); - va_copy(args_copy, args); // Copy this so we - - char str[1024]; - size_t bytes_written = 0; - // Try and format our string into a fixed buffer first and see if it fits - size_t length = ::vsnprintf(str, sizeof(str), format, args); - if (length < sizeof(str)) { - // The formatted string fit into our stack based buffer, so we can just - // append that to our packet - for (size_t i = 0; i < length; ++i) - bytes_written += _PutHex8(str[i], false); - } else { - // Our stack buffer wasn't big enough to contain the entire formatted - // string, so lets let vasprintf create the string for us! - char *str_ptr = NULL; - length = ::vasprintf(&str_ptr, format, args_copy); - if (str_ptr) { - for (size_t i = 0; i < length; ++i) - bytes_written += _PutHex8(str_ptr[i], false); - ::free(str_ptr); - } - } - va_end(args); - va_end(args_copy); - - return bytes_written; -} - -size_t Stream::PutNHex8(size_t n, uint8_t uvalue) { - size_t bytes_written = 0; - for (size_t i = 0; i < n; ++i) - bytes_written += _PutHex8(uvalue, m_flags.Test(eAddPrefix)); - return bytes_written; -} - -size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) { - size_t bytes_written = 0; - if (m_flags.Test(eBinary)) { - bytes_written = Write(&uvalue, 1); - } else { - if (add_prefix) - PutCString("0x"); - - static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5', - '6', '7', '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f'}; - char nibble_chars[2]; - nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf]; - nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf]; - bytes_written = Write(nibble_chars, sizeof(nibble_chars)); - } - return bytes_written; -} - -size_t Stream::PutHex8(uint8_t uvalue) { - return _PutHex8(uvalue, m_flags.Test(eAddPrefix)); -} - -size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - bool add_prefix = m_flags.Test(eAddPrefix); - size_t bytes_written = 0; - if (byte_order == eByteOrderLittle) { - for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } else { - for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); - --byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } - return bytes_written; -} - -size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - bool add_prefix = m_flags.Test(eAddPrefix); - size_t bytes_written = 0; - if (byte_order == eByteOrderLittle) { - for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } else { - for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); - --byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } - return bytes_written; -} - -size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - bool add_prefix = m_flags.Test(eAddPrefix); - size_t bytes_written = 0; - if (byte_order == eByteOrderLittle) { - for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } else { - for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); - --byte, add_prefix = false) - bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix); - } - return bytes_written; -} - -size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size, - lldb::ByteOrder byte_order) { - switch (byte_size) { - case 1: - return PutHex8((uint8_t)uvalue); - case 2: - return PutHex16((uint16_t)uvalue); - case 4: - return PutHex32((uint32_t)uvalue); - case 8: - return PutHex64(uvalue); - } - return 0; -} - -size_t Stream::PutPointer(void *ptr) { - return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(), - endian::InlHostByteOrder()); -} - -size_t Stream::PutFloat(float f, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order); -} - -size_t Stream::PutDouble(double d, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order); -} - -size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) { - if (byte_order == eByteOrderInvalid) - byte_order = m_byte_order; - - return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order); -} - -size_t Stream::PutRawBytes(const void *s, size_t src_len, - ByteOrder src_byte_order, ByteOrder dst_byte_order) { - if (src_byte_order == eByteOrderInvalid) - src_byte_order = m_byte_order; - - if (dst_byte_order == eByteOrderInvalid) - dst_byte_order = m_byte_order; - - size_t bytes_written = 0; - const uint8_t *src = (const uint8_t *)s; - bool binary_was_set = m_flags.Test(eBinary); - if (!binary_was_set) - m_flags.Set(eBinary); - if (src_byte_order == dst_byte_order) { - for (size_t i = 0; i < src_len; ++i) - bytes_written += _PutHex8(src[i], false); - } else { - for (size_t i = src_len - 1; i < src_len; --i) - bytes_written += _PutHex8(src[i], false); - } - if (!binary_was_set) - m_flags.Clear(eBinary); - - return bytes_written; -} - -size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len, - ByteOrder src_byte_order, - ByteOrder dst_byte_order) { - if (src_byte_order == eByteOrderInvalid) - src_byte_order = m_byte_order; - - if (dst_byte_order == eByteOrderInvalid) - dst_byte_order = m_byte_order; - - size_t bytes_written = 0; - const uint8_t *src = (const uint8_t *)s; - bool binary_is_set = m_flags.Test(eBinary); - m_flags.Clear(eBinary); - if (src_byte_order == dst_byte_order) { - for (size_t i = 0; i < src_len; ++i) - bytes_written += _PutHex8(src[i], false); - } else { - for (size_t i = src_len - 1; i < src_len; --i) - bytes_written += _PutHex8(src[i], false); - } - if (binary_is_set) - m_flags.Set(eBinary); - - return bytes_written; -} - -size_t Stream::PutCStringAsRawHex8(const char *s) { - size_t bytes_written = 0; - bool binary_is_set = m_flags.Test(eBinary); - m_flags.Clear(eBinary); - do { - bytes_written += _PutHex8(*s, false); - ++s; - } while (*s); - if (binary_is_set) - m_flags.Set(eBinary); - return bytes_written; -} - -void Stream::UnitTest(Stream *s) { - s->PutHex8(0x12); - - s->PutChar(' '); - s->PutHex16(0x3456, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex16(0x3456, eByteOrderBig); - s->PutChar(' '); - s->PutHex16(0x3456, eByteOrderLittle); - - s->PutChar(' '); - s->PutHex32(0x789abcde, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex32(0x789abcde, eByteOrderBig); - s->PutChar(' '); - s->PutHex32(0x789abcde, eByteOrderLittle); - - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, eByteOrderBig); - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, eByteOrderLittle); - - const char *hola = "Hello World!!!"; - s->PutChar(' '); - s->PutCString(hola); - - s->PutChar(' '); - s->Write(hola, 5); - - s->PutChar(' '); - s->PutCStringAsRawHex8(hola); - - s->PutChar(' '); - s->PutCStringAsRawHex8("01234"); - - s->PutChar(' '); - s->Printf("pid=%i", 12733); - - s->PutChar(' '); - s->PrintfAsRawHex8("pid=%i", 12733); - s->PutChar('\n'); -} diff --git a/source/Core/StreamAsynchronousIO.cpp b/source/Core/StreamAsynchronousIO.cpp index 1f7e634dfe33..aae8636bff09 100644 --- a/source/Core/StreamAsynchronousIO.cpp +++ b/source/Core/StreamAsynchronousIO.cpp @@ -10,7 +10,7 @@ #include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/Debugger.h" -#include "lldb/lldb-private.h" +#include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderBig using namespace lldb; using namespace lldb_private; diff --git a/source/Core/StreamCallback.cpp b/source/Core/StreamCallback.cpp deleted file mode 100644 index de784101e969..000000000000 --- a/source/Core/StreamCallback.cpp +++ /dev/null @@ -1,50 +0,0 @@ -//===-- StreamCallback.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <stdio.h> - -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Event.h" -#include "lldb/Core/StreamCallback.h" -#include "lldb/Host/Host.h" -#include "lldb/lldb-private.h" - -using namespace lldb; -using namespace lldb_private; - -StreamCallback::StreamCallback(lldb::LogOutputCallback callback, void *baton) - : Stream(0, 4, eByteOrderBig), m_callback(callback), m_baton(baton), - m_accumulated_data(), m_collection_mutex() {} - -StreamCallback::~StreamCallback() {} - -StreamString &StreamCallback::FindStreamForThread(lldb::tid_t cur_tid) { - std::lock_guard<std::mutex> guard(m_collection_mutex); - collection::iterator iter = m_accumulated_data.find(cur_tid); - if (iter == m_accumulated_data.end()) { - std::pair<collection::iterator, bool> ret; - ret = m_accumulated_data.insert( - std::pair<lldb::tid_t, StreamString>(cur_tid, StreamString())); - iter = ret.first; - } - return (*iter).second; -} - -void StreamCallback::Flush() { - lldb::tid_t cur_tid = Host::GetCurrentThreadID(); - StreamString &out_stream = FindStreamForThread(cur_tid); - m_callback(out_stream.GetData(), m_baton); - out_stream.Clear(); -} - -size_t StreamCallback::Write(const void *s, size_t length) { - lldb::tid_t cur_tid = Host::GetCurrentThreadID(); - FindStreamForThread(cur_tid).Write(s, length); - return length; -} diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp index f8c7fb9a84dc..f59415485021 100644 --- a/source/Core/StreamFile.cpp +++ b/source/Core/StreamFile.cpp @@ -9,12 +9,7 @@ #include "lldb/Core/StreamFile.h" -// C Includes #include <stdio.h> -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Error.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Core/StreamGDBRemote.cpp b/source/Core/StreamGDBRemote.cpp deleted file mode 100644 index a371d1316c7c..000000000000 --- a/source/Core/StreamGDBRemote.cpp +++ /dev/null @@ -1,42 +0,0 @@ -//===-- StreamGDBRemote.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/StreamGDBRemote.h" -#include <stdio.h> - -using namespace lldb; -using namespace lldb_private; - -StreamGDBRemote::StreamGDBRemote() : StreamString() {} - -StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size, - ByteOrder byte_order) - : StreamString(flags, addr_size, byte_order) {} - -StreamGDBRemote::~StreamGDBRemote() {} - -int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) { - int bytes_written = 0; - const uint8_t *src = (const uint8_t *)s; - bool binary_is_set = m_flags.Test(eBinary); - m_flags.Clear(eBinary); - while (src_len) { - uint8_t byte = *src; - src++; - src_len--; - if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) { - bytes_written += PutChar(0x7d); - byte ^= 0x20; - } - bytes_written += PutChar(byte); - }; - if (binary_is_set) - m_flags.Set(eBinary); - return bytes_written; -} diff --git a/source/Core/StreamString.cpp b/source/Core/StreamString.cpp deleted file mode 100644 index 461648815f18..000000000000 --- a/source/Core/StreamString.cpp +++ /dev/null @@ -1,65 +0,0 @@ -//===-- StreamString.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/StreamString.h" -#include <stdio.h> - -using namespace lldb; -using namespace lldb_private; - -StreamString::StreamString() : Stream(0, 4, eByteOrderBig) {} - -StreamString::StreamString(uint32_t flags, uint32_t addr_size, - ByteOrder byte_order) - : Stream(flags, addr_size, byte_order), m_packet() {} - -StreamString::~StreamString() {} - -void StreamString::Flush() { - // Nothing to do when flushing a buffer based stream... -} - -size_t StreamString::Write(const void *s, size_t length) { - m_packet.append(reinterpret_cast<const char *>(s), length); - return length; -} - -void StreamString::Clear() { m_packet.clear(); } - -bool StreamString::Empty() const { return GetSize() == 0; } - -size_t StreamString::GetSize() const { return m_packet.size(); } - -size_t StreamString::GetSizeOfLastLine() const { - const size_t length = m_packet.size(); - size_t last_line_begin_pos = m_packet.find_last_of("\r\n"); - if (last_line_begin_pos == std::string::npos) { - return length; - } else { - ++last_line_begin_pos; - return length - last_line_begin_pos; - } -} - -llvm::StringRef StreamString::GetString() const { return m_packet; } - -void StreamString::FillLastLineToColumn(uint32_t column, char fill_char) { - const size_t length = m_packet.size(); - size_t last_line_begin_pos = m_packet.find_last_of("\r\n"); - if (last_line_begin_pos == std::string::npos) { - last_line_begin_pos = 0; - } else { - ++last_line_begin_pos; - } - - const size_t line_columns = length - last_line_begin_pos; - if (column > line_columns) { - m_packet.append(column - line_columns, fill_char); - } -} diff --git a/source/Core/StringList.cpp b/source/Core/StringList.cpp deleted file mode 100644 index d2c4ac6775aa..000000000000 --- a/source/Core/StringList.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//===-- StringList.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/StringList.h" - -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/FileSpec.h" - -#include <string> - -using namespace lldb_private; - -StringList::StringList() : m_strings() {} - -StringList::StringList(const char *str) : m_strings() { - if (str) - m_strings.push_back(str); -} - -StringList::StringList(const char **strv, int strc) : m_strings() { - for (int i = 0; i < strc; ++i) { - if (strv[i]) - m_strings.push_back(strv[i]); - } -} - -StringList::~StringList() {} - -void StringList::AppendString(const char *str) { - if (str) - m_strings.push_back(str); -} - -void StringList::AppendString(const std::string &s) { m_strings.push_back(s); } - -void StringList::AppendString(std::string &&s) { m_strings.push_back(s); } - -void StringList::AppendString(const char *str, size_t str_len) { - if (str) - m_strings.push_back(std::string(str, str_len)); -} - -void StringList::AppendString(llvm::StringRef str) { - m_strings.push_back(str.str()); -} - -void StringList::AppendList(const char **strv, int strc) { - for (int i = 0; i < strc; ++i) { - if (strv[i]) - m_strings.push_back(strv[i]); - } -} - -void StringList::AppendList(StringList strings) { - size_t len = strings.GetSize(); - - for (size_t i = 0; i < len; ++i) - m_strings.push_back(strings.GetStringAtIndex(i)); -} - -bool StringList::ReadFileLines(FileSpec &input_file) { - return input_file.ReadFileLines(m_strings); -} - -size_t StringList::GetSize() const { return m_strings.size(); } - -size_t StringList::GetMaxStringLength() const { - size_t max_length = 0; - for (const auto &s : m_strings) { - const size_t len = s.size(); - if (max_length < len) - max_length = len; - } - return max_length; -} - -const char *StringList::GetStringAtIndex(size_t idx) const { - if (idx < m_strings.size()) - return m_strings[idx].c_str(); - return NULL; -} - -void StringList::Join(const char *separator, Stream &strm) { - size_t size = GetSize(); - - if (size == 0) - return; - - for (uint32_t i = 0; i < size; ++i) { - if (i > 0) - strm.PutCString(separator); - strm.PutCString(GetStringAtIndex(i)); - } -} - -void StringList::Clear() { m_strings.clear(); } - -void StringList::LongestCommonPrefix(std::string &common_prefix) { - common_prefix.clear(); - if (m_strings.empty()) - return; - - auto args = llvm::makeArrayRef(m_strings); - llvm::StringRef prefix = args.front(); - for (auto arg : args.drop_front()) { - size_t count = 0; - for (count = 0; count < std::min(prefix.size(), arg.size()); ++count) { - if (prefix[count] != arg[count]) - break; - } - prefix = prefix.take_front(count); - } - common_prefix = prefix; -} - -void StringList::InsertStringAtIndex(size_t idx, const char *str) { - if (str) { - if (idx < m_strings.size()) - m_strings.insert(m_strings.begin() + idx, str); - else - m_strings.push_back(str); - } -} - -void StringList::InsertStringAtIndex(size_t idx, const std::string &str) { - if (idx < m_strings.size()) - m_strings.insert(m_strings.begin() + idx, str); - else - m_strings.push_back(str); -} - -void StringList::InsertStringAtIndex(size_t idx, std::string &&str) { - if (idx < m_strings.size()) - m_strings.insert(m_strings.begin() + idx, str); - else - m_strings.push_back(str); -} - -void StringList::DeleteStringAtIndex(size_t idx) { - if (idx < m_strings.size()) - m_strings.erase(m_strings.begin() + idx); -} - -size_t StringList::SplitIntoLines(const std::string &lines) { - return SplitIntoLines(lines.c_str(), lines.size()); -} - -size_t StringList::SplitIntoLines(const char *lines, size_t len) { - const size_t orig_size = m_strings.size(); - - if (len == 0) - return 0; - - const char *k_newline_chars = "\r\n"; - const char *p = lines; - const char *end = lines + len; - while (p < end) { - size_t count = strcspn(p, k_newline_chars); - if (count == 0) { - if (p[count] == '\r' || p[count] == '\n') - m_strings.push_back(std::string()); - else - break; - } else { - if (p + count > end) - count = end - p; - m_strings.push_back(std::string(p, count)); - } - if (p[count] == '\r' && p[count + 1] == '\n') - count++; // Skip an extra newline char for the DOS newline - count++; // Skip the newline character - p += count; - } - return m_strings.size() - orig_size; -} - -void StringList::RemoveBlankLines() { - if (GetSize() == 0) - return; - - size_t idx = 0; - while (idx < m_strings.size()) { - if (m_strings[idx].empty()) - DeleteStringAtIndex(idx); - else - idx++; - } -} - -std::string StringList::CopyList(const char *item_preamble, - const char *items_sep) const { - StreamString strm; - for (size_t i = 0; i < GetSize(); i++) { - if (i && items_sep && items_sep[0]) - strm << items_sep; - if (item_preamble) - strm << item_preamble; - strm << GetStringAtIndex(i); - } - return strm.GetString(); -} - -StringList &StringList::operator<<(const char *str) { - AppendString(str); - return *this; -} - -StringList &StringList::operator<<(const std::string &str) { - AppendString(str); - return *this; -} - -StringList &StringList::operator<<(StringList strings) { - AppendList(strings); - return *this; -} - -StringList &StringList::operator=(const std::vector<std::string> &rhs) { - Clear(); - for (const auto &s : rhs) - m_strings.push_back(s); - - return *this; -} - -size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches, - size_t &exact_idx) const { - matches.Clear(); - exact_idx = SIZE_MAX; - if (s.empty()) { - // No string, so it matches everything - matches = *this; - return matches.GetSize(); - } - - const size_t s_len = s.size(); - const size_t num_strings = m_strings.size(); - - for (size_t i = 0; i < num_strings; ++i) { - if (m_strings[i].find(s) == 0) { - if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len) - exact_idx = matches.GetSize(); - matches.AppendString(m_strings[i]); - } - } - return matches.GetSize(); -} - -void StringList::LogDump(Log *log, const char *name) { - if (!log) - return; - - StreamString strm; - if (name) - strm.Printf("Begin %s:\n", name); - for (const auto &s : m_strings) { - strm.Indent(); - strm.Printf("%s\n", s.c_str()); - } - if (name) - strm.Printf("End %s.\n", name); - - log->Debug("%s", strm.GetData()); -} diff --git a/source/Core/StructuredData.cpp b/source/Core/StructuredData.cpp index 1e190f52314e..649c4615ad4f 100644 --- a/source/Core/StructuredData.cpp +++ b/source/Core/StructuredData.cpp @@ -9,17 +9,26 @@ #include "lldb/Core/StructuredData.h" -#include <errno.h> -#include <inttypes.h> -#include <stdlib.h> - -#include "lldb/Core/DataBuffer.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/StreamString.h" #include "lldb/Host/File.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/StringConvert.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/JSON.h" +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" // for FilePermissions::eFilePermiss... +#include "lldb/lldb-forward.h" // for DataBufferSP + +#include "llvm/ADT/STLExtras.h" // for make_unique + +#include <limits> // for numeric_limits + +#include <errno.h> +#include <inttypes.h> +#include <stdio.h> // for printf +#include <stdlib.h> +#include <sys/types.h> // for off_t using namespace lldb_private; @@ -70,10 +79,8 @@ StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Error &error) { static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) { // The "JSONParser::Token::ObjectStart" token should have already been - // consumed - // by the time this function is called - std::unique_ptr<StructuredData::Dictionary> dict_up( - new StructuredData::Dictionary()); + // consumed by the time this function is called + auto dict_up = llvm::make_unique<StructuredData::Dictionary>(); std::string value; std::string key; @@ -105,7 +112,7 @@ static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) { // The "JSONParser::Token::ObjectStart" token should have already been // consumed // by the time this function is called - std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array()); + auto array_up = llvm::make_unique<StructuredData::Array>(); std::string value; std::string key; @@ -142,26 +149,26 @@ static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) { bool success = false; uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); if (success) - return StructuredData::ObjectSP(new StructuredData::Integer(uval)); + return std::make_shared<StructuredData::Integer>(uval); } break; case JSONParser::Token::Float: { bool success = false; double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); if (success) - return StructuredData::ObjectSP(new StructuredData::Float(val)); + return std::make_shared<StructuredData::Float>(val); } break; case JSONParser::Token::String: - return StructuredData::ObjectSP(new StructuredData::String(value)); + return std::make_shared<StructuredData::String>(value); case JSONParser::Token::True: case JSONParser::Token::False: - return StructuredData::ObjectSP( - new StructuredData::Boolean(token == JSONParser::Token::True)); + return std::make_shared<StructuredData::Boolean>(token == + JSONParser::Token::True); case JSONParser::Token::Null: - return StructuredData::ObjectSP(new StructuredData::Null()); + return std::make_shared<StructuredData::Null>(); default: break; diff --git a/source/Core/Timer.cpp b/source/Core/Timer.cpp index ca1a2b749ec3..60da39b7f199 100644 --- a/source/Core/Timer.cpp +++ b/source/Core/Timer.cpp @@ -8,14 +8,18 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/Timer.h" +#include "lldb/Host/Host.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-types.h" // for thread_key_t + #include <algorithm> #include <map> #include <mutex> +#include <utility> // for pair #include <vector> -#include "lldb/Core/Stream.h" -#include "lldb/Host/Host.h" - +#include <assert.h> // for assert +#include <stdarg.h> // for va_end, va_list, va_start #include <stdio.h> using namespace lldb_private; diff --git a/source/Core/UUID.cpp b/source/Core/UUID.cpp deleted file mode 100644 index a08a748821de..000000000000 --- a/source/Core/UUID.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//===-- UUID.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/UUID.h" -// C Includes -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -// C++ Includes -#include <string> - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Stream.h" - -namespace lldb_private { - -UUID::UUID() : m_num_uuid_bytes(16) { ::memset(m_uuid, 0, sizeof(m_uuid)); } - -UUID::UUID(const UUID &rhs) { - m_num_uuid_bytes = rhs.m_num_uuid_bytes; - ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid)); -} - -UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) { - SetBytes(uuid_bytes, num_uuid_bytes); -} - -const UUID &UUID::operator=(const UUID &rhs) { - if (this != &rhs) { - m_num_uuid_bytes = rhs.m_num_uuid_bytes; - ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid)); - } - return *this; -} - -UUID::~UUID() {} - -void UUID::Clear() { - m_num_uuid_bytes = 16; - ::memset(m_uuid, 0, sizeof(m_uuid)); -} - -const void *UUID::GetBytes() const { return m_uuid; } - -std::string UUID::GetAsString(const char *separator) const { - std::string result; - char buf[256]; - if (!separator) - separator = "-"; - const uint8_t *u = (const uint8_t *)GetBytes(); - if (sizeof(buf) > - (size_t)snprintf(buf, sizeof(buf), "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2." - "2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%" - "2.2X%2.2X%2.2X", - u[0], u[1], u[2], u[3], separator, u[4], u[5], separator, - u[6], u[7], separator, u[8], u[9], separator, u[10], - u[11], u[12], u[13], u[14], u[15])) { - result.append(buf); - if (m_num_uuid_bytes == 20) { - if (sizeof(buf) > (size_t)snprintf(buf, sizeof(buf), - "%s%2.2X%2.2X%2.2X%2.2X", separator, - u[16], u[17], u[18], u[19])) - result.append(buf); - } - } - return result; -} - -void UUID::Dump(Stream *s) const { - const uint8_t *u = (const uint8_t *)GetBytes(); - s->Printf("%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%" - "2.2X%2.2X%2.2X%2.2X", - u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10], - u[11], u[12], u[13], u[14], u[15]); - if (m_num_uuid_bytes == 20) { - s->Printf("-%2.2X%2.2X%2.2X%2.2X", u[16], u[17], u[18], u[19]); - } -} - -bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) { - if (uuid_bytes) { - switch (num_uuid_bytes) { - case 20: - m_num_uuid_bytes = 20; - break; - case 16: - m_num_uuid_bytes = 16; - m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0; - break; - default: - // Unsupported UUID byte size - m_num_uuid_bytes = 0; - break; - } - - if (m_num_uuid_bytes > 0) { - ::memcpy(m_uuid, uuid_bytes, m_num_uuid_bytes); - return true; - } - } - ::memset(m_uuid, 0, sizeof(m_uuid)); - return false; -} - -size_t UUID::GetByteSize() { return m_num_uuid_bytes; } - -bool UUID::IsValid() const { - return m_uuid[0] || m_uuid[1] || m_uuid[2] || m_uuid[3] || m_uuid[4] || - m_uuid[5] || m_uuid[6] || m_uuid[7] || m_uuid[8] || m_uuid[9] || - m_uuid[10] || m_uuid[11] || m_uuid[12] || m_uuid[13] || m_uuid[14] || - m_uuid[15] || m_uuid[16] || m_uuid[17] || m_uuid[18] || m_uuid[19]; -} - -static inline int xdigit_to_int(char ch) { - ch = tolower(ch); - if (ch >= 'a' && ch <= 'f') - return 10 + ch - 'a'; - return ch - '0'; -} - -llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p, - ValueType &uuid_bytes, - uint32_t &bytes_decoded, - uint32_t num_uuid_bytes) { - ::memset(uuid_bytes, 0, sizeof(uuid_bytes)); - size_t uuid_byte_idx = 0; - while (!p.empty()) { - if (isxdigit(p[0]) && isxdigit(p[1])) { - int hi_nibble = xdigit_to_int(p[0]); - int lo_nibble = xdigit_to_int(p[1]); - // Translate the two hex nibble characters into a byte - uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble; - - // Skip both hex digits - p = p.drop_front(2); - - // Increment the byte that we are decoding within the UUID value - // and break out if we are done - if (++uuid_byte_idx == num_uuid_bytes) - break; - } else if (p.front() == '-') { - // Skip dashes - p = p.drop_front(); - } else { - // UUID values can only consist of hex characters and '-' chars - break; - } - } - - // Clear trailing bytes to 0. - for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++) - uuid_bytes[i] = 0; - bytes_decoded = uuid_byte_idx; - return p; -} -size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) { - if (cstr == NULL) - return 0; - - llvm::StringRef orig(cstr); - llvm::StringRef p = orig; - - // Skip leading whitespace characters - p = p.ltrim(); - - uint32_t bytes_decoded = 0; - llvm::StringRef rest = - UUID::DecodeUUIDBytesFromString(p, m_uuid, bytes_decoded, num_uuid_bytes); - - // If we successfully decoded a UUID, return the amount of characters that - // were consumed - if (bytes_decoded == num_uuid_bytes) { - m_num_uuid_bytes = num_uuid_bytes; - return orig.size() - rest.size(); - } - - // Else return zero to indicate we were not able to parse a UUID value - return 0; -} -} - -bool lldb_private::operator==(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) == 0; -} - -bool lldb_private::operator!=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) != 0; -} - -bool lldb_private::operator<(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) < 0; -} - -bool lldb_private::operator<=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) <= 0; -} - -bool lldb_private::operator>(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) > 0; -} - -bool lldb_private::operator>=(const lldb_private::UUID &lhs, - const lldb_private::UUID &rhs) { - return ::memcmp(lhs.GetBytes(), rhs.GetBytes(), - sizeof(lldb_private::UUID::ValueType)) >= 0; -} diff --git a/source/Core/UserID.cpp b/source/Core/UserID.cpp deleted file mode 100644 index 5446154c1d27..000000000000 --- a/source/Core/UserID.cpp +++ /dev/null @@ -1,21 +0,0 @@ -//===-- UserID.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/UserID.h" -#include "lldb/Core/Stream.h" - -#include <inttypes.h> - -using namespace lldb; -using namespace lldb_private; - -Stream &lldb_private::operator<<(Stream &strm, const UserID &uid) { - strm.Printf("{0x%8.8" PRIx64 "}", uid.GetID()); - return strm; -} diff --git a/source/Core/UserSettingsController.cpp b/source/Core/UserSettingsController.cpp index 92c3c8440d15..59a88ccdb931 100644 --- a/source/Core/UserSettingsController.cpp +++ b/source/Core/UserSettingsController.cpp @@ -1,5 +1,4 @@ -//====-- UserSettingsController.cpp ------------------------------*- C++ -//-*-===// +//====-- UserSettingsController.cpp ------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -8,17 +7,26 @@ // //===----------------------------------------------------------------------===// -#include <algorithm> -#include <string.h> - -#include "lldb/Core/Error.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/UserSettingsController.h" -#include "lldb/Interpreter/CommandInterpreter.h" + #include "lldb/Interpreter/OptionValueProperties.h" -#include "lldb/Interpreter/OptionValueString.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" + +#include <memory> // for shared_ptr + +namespace lldb_private { +class CommandInterpreter; +} +namespace lldb_private { +class ConstString; +} +namespace lldb_private { +class ExecutionContext; +} +namespace lldb_private { +class Property; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/VMRange.cpp b/source/Core/VMRange.cpp deleted file mode 100644 index 8d21f4b1273c..000000000000 --- a/source/Core/VMRange.cpp +++ /dev/null @@ -1,97 +0,0 @@ -//===-- VMRange.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/lldb-private.h" - -#include "lldb/Core/Stream.h" -#include "lldb/Core/VMRange.h" -#include <algorithm> - -using namespace lldb; -using namespace lldb_private; - -bool VMRange::ContainsValue(const VMRange::collection &coll, - lldb::addr_t value) { - ValueInRangeUnaryPredicate in_range_predicate(value); - VMRange::const_iterator pos; - VMRange::const_iterator end = coll.end(); - pos = std::find_if(coll.begin(), end, in_range_predicate); - if (pos != end) - return true; - return false; -} - -bool VMRange::ContainsRange(const VMRange::collection &coll, - const VMRange &range) { - RangeInRangeUnaryPredicate in_range_predicate(range); - VMRange::const_iterator pos; - VMRange::const_iterator end = coll.end(); - pos = std::find_if(coll.begin(), end, in_range_predicate); - if (pos != end) - return true; - return false; -} - -size_t VMRange::FindRangeIndexThatContainsValue(const VMRange::collection &coll, - lldb::addr_t value) { - ValueInRangeUnaryPredicate in_range_predicate(value); - VMRange::const_iterator begin = coll.begin(); - VMRange::const_iterator end = coll.end(); - VMRange::const_iterator pos = std::find_if(begin, end, in_range_predicate); - if (pos != end) - return std::distance(begin, pos); - return UINT32_MAX; -} - -void VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const { - s->AddressRange(offset + GetBaseAddress(), offset + GetEndAddress(), - addr_width); -} - -bool lldb_private::operator==(const VMRange &lhs, const VMRange &rhs) { - return lhs.GetBaseAddress() == rhs.GetBaseAddress() && - lhs.GetEndAddress() == rhs.GetEndAddress(); -} - -bool lldb_private::operator!=(const VMRange &lhs, const VMRange &rhs) { - return lhs.GetBaseAddress() != rhs.GetBaseAddress() || - lhs.GetEndAddress() != rhs.GetEndAddress(); -} - -bool lldb_private::operator<(const VMRange &lhs, const VMRange &rhs) { - if (lhs.GetBaseAddress() < rhs.GetBaseAddress()) - return true; - else if (lhs.GetBaseAddress() > rhs.GetBaseAddress()) - return false; - return lhs.GetEndAddress() < rhs.GetEndAddress(); -} - -bool lldb_private::operator<=(const VMRange &lhs, const VMRange &rhs) { - if (lhs.GetBaseAddress() < rhs.GetBaseAddress()) - return true; - else if (lhs.GetBaseAddress() > rhs.GetBaseAddress()) - return false; - return lhs.GetEndAddress() <= rhs.GetEndAddress(); -} - -bool lldb_private::operator>(const VMRange &lhs, const VMRange &rhs) { - if (lhs.GetBaseAddress() > rhs.GetBaseAddress()) - return true; - else if (lhs.GetBaseAddress() < rhs.GetBaseAddress()) - return false; - return lhs.GetEndAddress() > rhs.GetEndAddress(); -} - -bool lldb_private::operator>=(const VMRange &lhs, const VMRange &rhs) { - if (lhs.GetBaseAddress() > rhs.GetBaseAddress()) - return true; - else if (lhs.GetBaseAddress() < rhs.GetBaseAddress()) - return false; - return lhs.GetEndAddress() >= rhs.GetEndAddress(); -} diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp index a480c3cf375a..9aaddf77021c 100644 --- a/source/Core/Value.cpp +++ b/source/Core/Value.cpp @@ -9,16 +9,10 @@ #include "lldb/Core/Value.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Module.h" #include "lldb/Core/State.h" -#include "lldb/Core/Stream.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -28,6 +22,20 @@ #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" // for InlHostByteOrder +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-forward.h" // for DataBufferSP, ModuleSP +#include "lldb/lldb-types.h" // for addr_t + +#include <memory> // for make_shared +#include <string> // for string + +#include <inttypes.h> // for PRIx64 using namespace lldb; using namespace lldb_private; @@ -538,7 +546,8 @@ Error Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, // Make sure we have enough room within "data", and if we don't make // something large enough that does if (!data.ValidOffsetForDataOfSize(data_offset, byte_size)) { - DataBufferSP data_sp(new DataBufferHeap(data_offset + byte_size, '\0')); + auto data_sp = + std::make_shared<DataBufferHeap>(data_offset + byte_size, '\0'); data.SetData(data_sp); } diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index fc2312d60d57..381763dab8e1 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -9,52 +9,67 @@ #include "lldb/Core/ValueObject.h" -// C Includes -#include <stdlib.h> - -// C++ Includes -// Other libraries and framework includes -#include "llvm/Support/raw_ostream.h" - -// Project includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" +#include "lldb/Core/Address.h" // for Address #include "lldb/Core/Module.h" -#include "lldb/Core/StreamString.h" +#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectDynamicValue.h" -#include "lldb/Core/ValueObjectList.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Core/ValueObjectSyntheticFilter.h" - #include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/DataFormatters/FormatManager.h" // for FormatManager #include "lldb/DataFormatters/StringPrinter.h" +#include "lldb/DataFormatters/TypeFormat.h" // for TypeFormatImpl_F... +#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryOptions +#include "lldb/DataFormatters/TypeValidator.h" // for TypeValidatorImp... #include "lldb/DataFormatters/ValueObjectPrinter.h" - -#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" -#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" - -#include "lldb/Host/Endian.h" - -#include "lldb/Interpreter/CommandInterpreter.h" - +#include "lldb/Expression/ExpressionVariable.h" // for ExpressionVariable #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/Declaration.h" // for Declaration +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Symbol/Type.h" - #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StackFrame.h" // for StackFrame #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadList.h" // for ThreadList +#include "lldb/Utility/DataBuffer.h" // for DataBuffer +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Flags.h" // for Flags +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCateg... +#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-private-types.h" // for RegisterInfo + +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <algorithm> // for min +#include <cstdint> // for uint32_t, uint64_t +#include <cstdlib> // for size_t, NULL +#include <memory> // for shared_ptr, oper... +#include <tuple> // for tie, tuple + +#include <assert.h> // for assert +#include <inttypes.h> // for PRIu64, PRIx64 +#include <stdio.h> // for snprintf +#include <string.h> // for memcpy, memcmp + +namespace lldb_private { +class ExecutionContextScope; +} +namespace lldb_private { +class SymbolContextScope; +} using namespace lldb; using namespace lldb_private; @@ -2889,6 +2904,11 @@ ValueObjectSP ValueObject::Dereference(Error &error) { child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, language_flags); } + } else if (HasSyntheticValue()) { + m_deref_valobj = + GetSyntheticValue() + ->GetChildMemberWithName(ConstString("$$dereference$$"), true) + .get(); } if (m_deref_valobj) { @@ -2957,6 +2977,10 @@ ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) { return ValueObjectCast::Create(*this, GetName(), compiler_type); } +lldb::ValueObjectSP ValueObject::Clone(const ConstString &new_name) { + return ValueObjectCast::Create(*this, new_name, GetCompilerType()); +} + ValueObjectSP ValueObject::CastPointerType(const char *name, CompilerType &compiler_type) { ValueObjectSP valobj_sp; diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp index 300aeae3b33a..aa4cf60c1f9e 100644 --- a/source/Core/ValueObjectCast.cpp +++ b/source/Core/ValueObjectCast.cpp @@ -9,27 +9,16 @@ #include "lldb/Core/ValueObjectCast.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/Module.h" +#include "lldb/Core/Scalar.h" // for operator!=, Scalar #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectList.h" - #include "lldb/Symbol/CompilerType.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/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Utility/Error.h" // for Error + +namespace lldb_private { +class ConstString; +} using namespace lldb_private; diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp index 9b2bdd1e468c..eeb28c960a3a 100644 --- a/source/Core/ValueObjectChild.cpp +++ b/source/Core/ValueObjectChild.cpp @@ -9,18 +9,21 @@ #include "lldb/Core/ValueObjectChild.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ValueObjectList.h" - +#include "lldb/Core/Scalar.h" // for Scalar +#include "lldb/Core/Value.h" // for Value, Value::ValueType::e... #include "lldb/Symbol/CompilerType.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" +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Flags.h" // for Flags +#include "lldb/lldb-forward.h" // for ProcessSP, ModuleSP + +#include <functional> // for _Func_impl<>::_Mybase +#include <memory> // for shared_ptr +#include <vector> // for vector + +#include <stdio.h> // for snprintf, size_t +#include <string.h> // for strlen using namespace lldb_private; diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp index f78574ef7ee3..cf437ce6f7d5 100644 --- a/source/Core/ValueObjectConstResult.cpp +++ b/source/Core/ValueObjectConstResult.cpp @@ -9,22 +9,19 @@ #include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ValueObjectChild.h" -#include "lldb/Core/ValueObjectConstResultChild.h" +#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectDynamicValue.h" -#include "lldb/Core/ValueObjectList.h" - #include "lldb/Symbol/CompilerType.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/ExecutionContextScope.h" // for ExecutionContextScope #include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" +#include "lldb/Utility/DataBuffer.h" // for DataBuffer +#include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap +#include "lldb/Utility/DataExtractor.h" + +namespace lldb_private { +class Module; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ValueObjectConstResultCast.cpp b/source/Core/ValueObjectConstResultCast.cpp index 32451468c183..f575bebd7110 100644 --- a/source/Core/ValueObjectConstResultCast.cpp +++ b/source/Core/ValueObjectConstResultCast.cpp @@ -9,10 +9,15 @@ #include "lldb/Core/ValueObjectConstResultCast.h" -#include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/ValueObjectList.h" - -#include "lldb/Symbol/ClangASTContext.h" +namespace lldb_private { +class DataExtractor; +} +namespace lldb_private { +class Error; +} +namespace lldb_private { +class ValueObject; +} using namespace lldb_private; diff --git a/source/Core/ValueObjectConstResultChild.cpp b/source/Core/ValueObjectConstResultChild.cpp index c4c9c63c765d..9c6ad8becf3b 100644 --- a/source/Core/ValueObjectConstResultChild.cpp +++ b/source/Core/ValueObjectConstResultChild.cpp @@ -1,5 +1,4 @@ -//===-- ValueObjectConstResultChild.cpp ------------------------------*- C++ -//-*-===// +//===-- ValueObjectConstResultChild.cpp --------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -10,10 +9,16 @@ #include "lldb/Core/ValueObjectConstResultChild.h" -#include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/ValueObjectList.h" - -#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressType +namespace lldb_private { +class DataExtractor; +} +namespace lldb_private { +class Error; +} +namespace lldb_private { +class ValueObject; +} using namespace lldb_private; diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp index 0e4f73f13b52..ed25ea8071a2 100644 --- a/source/Core/ValueObjectConstResultImpl.cpp +++ b/source/Core/ValueObjectConstResultImpl.cpp @@ -1,5 +1,4 @@ -//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++ -//-*-===// +//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -10,24 +9,26 @@ #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/ValueObjectChild.h" +#include "lldb/Core/Scalar.h" // for Scalar +#include "lldb/Core/Value.h" // for Value, Value::Val... +#include "lldb/Core/ValueObject.h" // for ValueObject #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectConstResultCast.h" #include "lldb/Core/ValueObjectConstResultChild.h" -#include "lldb/Core/ValueObjectList.h" -#include "lldb/Core/ValueObjectMemory.h" - #include "lldb/Symbol/CompilerType.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" +#include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap +#include "lldb/Utility/Endian.h" // for InlHostByteOrder +#include "lldb/Utility/SharingPtr.h" // for SharingPtr + +#include <string> // for string + +namespace lldb_private { +class DataExtractor; +} +namespace lldb_private { +class Error; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp index 1fb32d4e86a3..59bbc025f994 100644 --- a/source/Core/ValueObjectDynamicValue.cpp +++ b/source/Core/ValueObjectDynamicValue.cpp @@ -1,5 +1,4 @@ -//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -//-*-===// +//===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -10,28 +9,26 @@ #include "lldb/Core/ValueObjectDynamicValue.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/Module.h" +#include "lldb/Core/ArchSpec.h" // for ArchSpec +#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectList.h" - #include "lldb/Symbol/CompilerType.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/LanguageRuntime.h" #include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet +#include "lldb/lldb-types.h" // for addr_t, offset_t + +#include <string.h> // for strcmp, size_t +namespace lldb_private { +class Declaration; +} using namespace lldb_private; diff --git a/source/Core/ValueObjectList.cpp b/source/Core/ValueObjectList.cpp index 7eae49744413..00aee798c0e3 100644 --- a/source/Core/ValueObjectList.cpp +++ b/source/Core/ValueObjectList.cpp @@ -9,15 +9,11 @@ #include "lldb/Core/ValueObjectList.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/ValueObjectChild.h" -#include "lldb/Core/ValueObjectRegister.h" -#include "lldb/Core/ValueObjectVariable.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" +#include "lldb/Core/ValueObject.h" // for ValueObject +#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/SharingPtr.h" // for SharingPtr + +#include <utility> // for back_insert_iterator, back_ins... using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp index 18f3c94c522b..0fb8f0d2de03 100644 --- a/source/Core/ValueObjectMemory.cpp +++ b/source/Core/ValueObjectMemory.cpp @@ -9,25 +9,24 @@ #include "lldb/Core/ValueObjectMemory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Module.h" +#include "lldb/Core/ArchSpec.h" // for ArchSpec +#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectList.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/RegisterContext.h" #include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Error.h" // for Error +#include "lldb/lldb-types.h" // for addr_t +#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable + +#include <assert.h> // for assert +#include <memory> // for shared_ptr + +namespace lldb_private { +class ExecutionContextScope; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp index 80e00e4007c4..6469340201e5 100644 --- a/source/Core/ValueObjectRegister.cpp +++ b/source/Core/ValueObjectRegister.cpp @@ -9,19 +9,28 @@ #include "lldb/Core/ValueObjectRegister.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Core/Scalar.h" // for Scalar +#include "lldb/Core/Value.h" // for Value, Value::ContextType:... #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeSystem.h" // for TypeSystem #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" // for StackFrame #include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Stream.h" // for Stream + +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <assert.h> // for assert +#include <memory> // for shared_ptr + +namespace lldb_private { +class ExecutionContextScope; +} using namespace lldb; using namespace lldb_private; diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp index 592f1ea56bdf..f0fd76ed09fc 100644 --- a/source/Core/ValueObjectSyntheticFilter.cpp +++ b/source/Core/ValueObjectSyntheticFilter.cpp @@ -7,15 +7,22 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ValueObjectSyntheticFilter.h" -#include "lldb/Core/Log.h" +#include "lldb/Core/Value.h" // for Value #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/Target/ExecutionContext.h" // for ExecutionContext +#include "lldb/Utility/Error.h" // for Error +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet +#include "lldb/Utility/SharingPtr.h" // for SharingPtr + +#include "llvm/ADT/STLExtras.h" + +namespace lldb_private { +class Declaration; +} using namespace lldb_private; @@ -124,7 +131,7 @@ lldb::ValueType ValueObjectSynthetic::GetValueType() const { void ValueObjectSynthetic::CreateSynthFilter() { m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent)); if (!m_synth_filter_ap.get()) - m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent)); + m_synth_filter_ap = llvm::make_unique<DummySyntheticFrontEnd>(*m_parent); } bool ValueObjectSynthetic::UpdateValue() { diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp index f8eedc30e709..169f8f0f6c28 100644 --- a/source/Core/ValueObjectVariable.cpp +++ b/source/Core/ValueObjectVariable.cpp @@ -9,28 +9,44 @@ #include "lldb/Core/ValueObjectVariable.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes +#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Module.h" #include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" -#include "lldb/Core/ValueObjectList.h" - +#include "lldb/Expression/DWARFExpression.h" // for DWARFExpression +#include "lldb/Symbol/Declaration.h" // for Declaration #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" - #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Error.h" // for Error +#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressTy... +#include "lldb/lldb-types.h" // for addr_t + +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <assert.h> // for assert +#include <memory> // for shared_ptr +namespace lldb_private { +class ExecutionContextScope; +} +namespace lldb_private { +class StackFrame; +} +namespace lldb_private { +struct RegisterInfo; +} using namespace lldb_private; lldb::ValueObjectSP |