diff options
Diffstat (limited to 'source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp')
-rw-r--r-- | source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp new file mode 100644 index 000000000000..2604ae670164 --- /dev/null +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp @@ -0,0 +1,177 @@ +//===-- AuxVector.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> +#include <sys/types.h> + +// C++ Includes +// Other libraries and framework includes +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" + +#if defined(__linux__) or defined(__FreeBSD__) +#include "Plugins/Process/elf-core/ProcessElfCore.h" +#endif + +#include "AuxVector.h" + +using namespace lldb; +using namespace lldb_private; + +static bool +GetMaxU64(DataExtractor &data, + lldb::offset_t *offset_ptr, + uint64_t *value, + unsigned int byte_size) +{ + lldb::offset_t saved_offset = *offset_ptr; + *value = data.GetMaxU64(offset_ptr, byte_size); + return *offset_ptr != saved_offset; +} + +static bool +ParseAuxvEntry(DataExtractor &data, + AuxVector::Entry &entry, + lldb::offset_t *offset_ptr, + unsigned int byte_size) +{ + if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size)) + return false; + + if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size)) + return false; + + return true; +} + +DataBufferSP +AuxVector::GetAuxvData() +{ +#if defined(__linux__) or defined(__FreeBSD__) + if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) + return static_cast<ProcessElfCore *>(m_process)->GetAuxvData(); +#endif + return lldb_private::Host::GetAuxvData(m_process); +} + +void +AuxVector::ParseAuxv(DataExtractor &data) +{ + const unsigned int byte_size = m_process->GetAddressByteSize(); + lldb::offset_t offset = 0; + + for (;;) + { + Entry entry; + + if (!ParseAuxvEntry(data, entry, &offset, byte_size)) + break; + + if (entry.type == AT_NULL) + break; + + if (entry.type == AT_IGNORE) + continue; + + m_auxv.push_back(entry); + } +} + +AuxVector::AuxVector(Process *process) + : m_process(process) +{ + DataExtractor data; + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + + data.SetData(GetAuxvData()); + data.SetByteOrder(m_process->GetByteOrder()); + data.SetAddressByteSize(m_process->GetAddressByteSize()); + + ParseAuxv(data); + + if (log) + DumpToLog(log); +} + +AuxVector::iterator +AuxVector::FindEntry(EntryType type) const +{ + for (iterator I = begin(); I != end(); ++I) + { + if (I->type == static_cast<uint64_t>(type)) + return I; + } + + return end(); +} + +void +AuxVector::DumpToLog(Log *log) const +{ + if (!log) + return; + + log->PutCString("AuxVector: "); + for (iterator I = begin(); I != end(); ++I) + { + log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value); + } +} + +const char * +AuxVector::GetEntryName(EntryType type) +{ + const char *name = "AT_???"; + +#define ENTRY_NAME(_type) _type: name = #_type + switch (type) + { + case ENTRY_NAME(AT_NULL); break; + case ENTRY_NAME(AT_IGNORE); break; + case ENTRY_NAME(AT_EXECFD); break; + case ENTRY_NAME(AT_PHDR); break; + case ENTRY_NAME(AT_PHENT); break; + case ENTRY_NAME(AT_PHNUM); break; + case ENTRY_NAME(AT_PAGESZ); break; + case ENTRY_NAME(AT_BASE); break; + case ENTRY_NAME(AT_FLAGS); break; + case ENTRY_NAME(AT_ENTRY); break; + case ENTRY_NAME(AT_NOTELF); break; + case ENTRY_NAME(AT_UID); break; + case ENTRY_NAME(AT_EUID); break; + case ENTRY_NAME(AT_GID); break; + case ENTRY_NAME(AT_EGID); break; + case ENTRY_NAME(AT_CLKTCK); break; + case ENTRY_NAME(AT_PLATFORM); break; + case ENTRY_NAME(AT_HWCAP); break; + case ENTRY_NAME(AT_FPUCW); break; + case ENTRY_NAME(AT_DCACHEBSIZE); break; + case ENTRY_NAME(AT_ICACHEBSIZE); break; + case ENTRY_NAME(AT_UCACHEBSIZE); break; + case ENTRY_NAME(AT_IGNOREPPC); break; + case ENTRY_NAME(AT_SECURE); break; + case ENTRY_NAME(AT_BASE_PLATFORM); break; + case ENTRY_NAME(AT_RANDOM); break; + case ENTRY_NAME(AT_EXECFN); break; + case ENTRY_NAME(AT_SYSINFO); break; + case ENTRY_NAME(AT_SYSINFO_EHDR); break; + case ENTRY_NAME(AT_L1I_CACHESHAPE); break; + case ENTRY_NAME(AT_L1D_CACHESHAPE); break; + case ENTRY_NAME(AT_L2_CACHESHAPE); break; + case ENTRY_NAME(AT_L3_CACHESHAPE); break; + } +#undef ENTRY_NAME + + return name; +} + |