diff options
Diffstat (limited to 'lldb/source/Plugins/Process')
11 files changed, 198 insertions, 9 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index d29a5e8c993..770794569f7 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -876,7 +876,7 @@ bool ProcessFreeBSD::IsAThreadRunning() { return is_running; } -const DataBufferSP ProcessFreeBSD::GetAuxvData() { +lldb_private::DataExtractor ProcessFreeBSD::GetAuxvData() { // If we're the local platform, we can ask the host for auxv data. PlatformSP platform_sp = GetTarget().GetPlatform(); assert(platform_sp && platform_sp->IsHost()); @@ -890,7 +890,7 @@ const DataBufferSP ProcessFreeBSD::GetAuxvData() { buf_sp.reset(); } - return buf_sp; + return DataExtractor(buf_sp, GetByteOrder(), GetAddressByteSize()); } struct EmulatorBaton { diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h index 293f7b854b4..8c1b78cda9a 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h @@ -127,7 +127,7 @@ public: size_t PutSTDIN(const char *buf, size_t len, lldb_private::Status &error) override; - const lldb::DataBufferSP GetAuxvData() override; + const lldb_private::DataExtractor GetAuxvData() override; // ProcessFreeBSD internal API. diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index a55dc41bed0..81d257e95e1 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -2082,3 +2082,18 @@ Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid, return error; } + +llvm::Optional<uint64_t> +NativeProcessLinux::GetAuxValue(enum AuxVector::EntryType type) { + if (m_aux_vector == nullptr) { + auto buffer_or_error = GetAuxvData(); + if (!buffer_or_error) + return llvm::None; + DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(), + buffer_or_error.get()->getBufferSize(), + GetByteOrder(), GetAddressByteSize()); + m_aux_vector = llvm::make_unique<AuxVector>(auxv_data); + } + + return m_aux_vector->GetAuxValue(type); +} diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index 006ae000168..0a67af0a0a4 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -12,6 +12,7 @@ #include <csignal> #include <unordered_set> +#include "Plugins/Process/Utility/AuxVector.h" #include "lldb/Host/Debug.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/linux/Support.h" @@ -102,6 +103,8 @@ public: return getProcFile(GetID(), "auxv"); } + llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type); + lldb::user_id_t StartTrace(const TraceOptions &config, Status &error) override; @@ -132,6 +135,7 @@ protected: private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; + std::unique_ptr<AuxVector> m_aux_vector; LazyBool m_supports_mem_region = eLazyBoolCalculate; std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache; diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.cpp b/lldb/source/Plugins/Process/Utility/AuxVector.cpp new file mode 100644 index 00000000000..aab164ff93a --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/AuxVector.cpp @@ -0,0 +1,96 @@ +//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "AuxVector.h" + +AuxVector::AuxVector(const lldb_private::DataExtractor &data) { + ParseAuxv(data); +} + +void AuxVector::ParseAuxv(const lldb_private::DataExtractor &data) { + lldb::offset_t offset = 0; + const size_t value_type_size = data.GetAddressByteSize() * 2; + while (data.ValidOffsetForDataOfSize(offset, value_type_size)) { + // We're not reading an address but an int that could be 32 or 64 bit + // depending on the address size, which is what GetAddress does. + const uint64_t type = data.GetAddress(&offset); + const uint64_t value = data.GetAddress(&offset); + if (type == AUXV_AT_NULL) + break; + if (type == AUXV_AT_IGNORE) + continue; + + m_auxv_entries[type] = value; + } +} + +llvm::Optional<uint64_t> +AuxVector::GetAuxValue(enum EntryType entry_type) const { + auto it = m_auxv_entries.find(static_cast<uint64_t>(entry_type)); + if (it != m_auxv_entries.end()) + return it->second; + return llvm::None; +} + +void AuxVector::DumpToLog(lldb_private::Log *log) const { + if (!log) + return; + + log->PutCString("AuxVector: "); + for (auto entry : m_auxv_entries) { + log->Printf(" %s [%" PRIu64 "]: %" PRIx64, + GetEntryName(static_cast<EntryType>(entry.first)), entry.first, + entry.second); + } +} + +const char *AuxVector::GetEntryName(EntryType type) const { + const char *name = "AT_???"; + +#define ENTRY_NAME(_type) \ + _type: \ + name = &#_type[5] + switch (type) { + case ENTRY_NAME(AUXV_AT_NULL); break; + case ENTRY_NAME(AUXV_AT_IGNORE); break; + case ENTRY_NAME(AUXV_AT_EXECFD); break; + case ENTRY_NAME(AUXV_AT_PHDR); break; + case ENTRY_NAME(AUXV_AT_PHENT); break; + case ENTRY_NAME(AUXV_AT_PHNUM); break; + case ENTRY_NAME(AUXV_AT_PAGESZ); break; + case ENTRY_NAME(AUXV_AT_BASE); break; + case ENTRY_NAME(AUXV_AT_FLAGS); break; + case ENTRY_NAME(AUXV_AT_ENTRY); break; + case ENTRY_NAME(AUXV_AT_NOTELF); break; + case ENTRY_NAME(AUXV_AT_UID); break; + case ENTRY_NAME(AUXV_AT_EUID); break; + case ENTRY_NAME(AUXV_AT_GID); break; + case ENTRY_NAME(AUXV_AT_EGID); break; + case ENTRY_NAME(AUXV_AT_CLKTCK); break; + case ENTRY_NAME(AUXV_AT_PLATFORM); break; + case ENTRY_NAME(AUXV_AT_HWCAP); break; + case ENTRY_NAME(AUXV_AT_FPUCW); break; + case ENTRY_NAME(AUXV_AT_DCACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_ICACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_UCACHEBSIZE); break; + case ENTRY_NAME(AUXV_AT_IGNOREPPC); break; + case ENTRY_NAME(AUXV_AT_SECURE); break; + case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break; + case ENTRY_NAME(AUXV_AT_RANDOM); break; + case ENTRY_NAME(AUXV_AT_EXECFN); break; + case ENTRY_NAME(AUXV_AT_SYSINFO); break; + case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break; + case ENTRY_NAME(AUXV_AT_L1I_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE); break; + case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE); break; + } +#undef ENTRY_NAME + + return name; +} diff --git a/lldb/source/Plugins/Process/Utility/AuxVector.h b/lldb/source/Plugins/Process/Utility/AuxVector.h new file mode 100644 index 00000000000..c16be68aedb --- /dev/null +++ b/lldb/source/Plugins/Process/Utility/AuxVector.h @@ -0,0 +1,73 @@ +//===-- AuxVector.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_AuxVector_H_ +#define liblldb_AuxVector_H_ + +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include <unordered_map> + +class AuxVector { + +public: + AuxVector(const lldb_private::DataExtractor &data); + + /// Constants describing the type of entry. + /// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX + /// information. Added AUXV prefix to avoid potential conflicts with system- + /// defined macros + enum EntryType { + AUXV_AT_NULL = 0, ///< End of auxv. + AUXV_AT_IGNORE = 1, ///< Ignore entry. + AUXV_AT_EXECFD = 2, ///< File descriptor of program. + AUXV_AT_PHDR = 3, ///< Program headers. + AUXV_AT_PHENT = 4, ///< Size of program header. + AUXV_AT_PHNUM = 5, ///< Number of program headers. + AUXV_AT_PAGESZ = 6, ///< Page size. + AUXV_AT_BASE = 7, ///< Interpreter base address. + AUXV_AT_FLAGS = 8, ///< Flags. + AUXV_AT_ENTRY = 9, ///< Program entry point. + AUXV_AT_NOTELF = 10, ///< Set if program is not an ELF. + AUXV_AT_UID = 11, ///< UID. + AUXV_AT_EUID = 12, ///< Effective UID. + AUXV_AT_GID = 13, ///< GID. + AUXV_AT_EGID = 14, ///< Effective GID. + AUXV_AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)). + AUXV_AT_PLATFORM = 15, ///< String identifying platform. + AUXV_AT_HWCAP = + 16, ///< Machine dependent hints about processor capabilities. + AUXV_AT_FPUCW = 18, ///< Used FPU control word. + AUXV_AT_DCACHEBSIZE = 19, ///< Data cache block size. + AUXV_AT_ICACHEBSIZE = 20, ///< Instruction cache block size. + AUXV_AT_UCACHEBSIZE = 21, ///< Unified cache block size. + AUXV_AT_IGNOREPPC = 22, ///< Entry should be ignored. + AUXV_AT_SECURE = 23, ///< Boolean, was exec setuid-like? + AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms. + AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes. + AUXV_AT_EXECFN = 31, ///< Filename of executable. + AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system + /// calls and other nice things. + AUXV_AT_SYSINFO_EHDR = 33, + AUXV_AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches. + AUXV_AT_L1D_CACHESHAPE = 35, + AUXV_AT_L2_CACHESHAPE = 36, + AUXV_AT_L3_CACHESHAPE = 37, + }; + + llvm::Optional<uint64_t> GetAuxValue(enum EntryType entry_type) const; + void DumpToLog(lldb_private::Log *log) const; + const char *GetEntryName(EntryType type) const; + +private: + void ParseAuxv(const lldb_private::DataExtractor &data); + + std::unordered_map<uint64_t, uint64_t> m_auxv_entries; +}; + +#endif diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt index e36ce4dec98..9ed2d020a4c 100644 --- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt @@ -1,4 +1,5 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN + AuxVector.cpp DynamicRegisterInfo.cpp FreeBSDSignals.cpp GDBRemoteSignals.cpp diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index f40ff130cf5..980169e16c5 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -894,11 +894,11 @@ ArchSpec ProcessElfCore::GetArchitecture() { return arch; } -const lldb::DataBufferSP ProcessElfCore::GetAuxvData() { +DataExtractor ProcessElfCore::GetAuxvData() { const uint8_t *start = m_auxv.GetDataStart(); size_t len = m_auxv.GetByteSize(); lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len)); - return buffer; + return DataExtractor(buffer, GetByteOrder(), GetAddressByteSize()); } bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) { diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 6828f5a42ff..829fe9ac719 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -97,7 +97,7 @@ public: lldb_private::ArchSpec GetArchitecture(); // Returns AUXV structure found in the core file - const lldb::DataBufferSP GetAuxvData() override; + lldb_private::DataExtractor GetAuxvData() override; bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override; diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index c4df4e716d0..194e79085a0 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4046,7 +4046,7 @@ Status ProcessGDBRemote::SendEventData(const char *data) { return error; } -const DataBufferSP ProcessGDBRemote::GetAuxvData() { +DataExtractor ProcessGDBRemote::GetAuxvData() { DataBufferSP buf; if (m_gdb_comm.GetQXferAuxvReadSupported()) { std::string response_string; @@ -4056,7 +4056,7 @@ const DataBufferSP ProcessGDBRemote::GetAuxvData() { buf = std::make_shared<DataBufferHeap>(response_string.c_str(), response_string.length()); } - return buf; + return DataExtractor(buf, GetByteOrder(), GetAddressByteSize()); } StructuredData::ObjectSP diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index a82b0950a6e..83c4807ed59 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -324,7 +324,7 @@ protected: bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec); - const lldb::DataBufferSP GetAuxvData() override; + DataExtractor GetAuxvData() override; StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid); |