1254721Semaste//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste#include <fcntl.h> 12254721Semaste#include <sys/stat.h> 13254721Semaste#include <sys/types.h> 14254721Semaste 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste#include "lldb/Core/DataBufferHeap.h" 18254721Semaste#include "lldb/Core/DataExtractor.h" 19254721Semaste#include "lldb/Core/Log.h" 20254721Semaste#include "lldb/Target/Process.h" 21254721Semaste 22263363Semaste#if defined(__linux__) || defined(__FreeBSD__) 23254721Semaste#include "Plugins/Process/elf-core/ProcessElfCore.h" 24254721Semaste#endif 25254721Semaste 26254721Semaste#include "AuxVector.h" 27254721Semaste 28254721Semasteusing namespace lldb; 29254721Semasteusing namespace lldb_private; 30254721Semaste 31254721Semastestatic bool 32254721SemasteGetMaxU64(DataExtractor &data, 33254721Semaste lldb::offset_t *offset_ptr, 34254721Semaste uint64_t *value, 35254721Semaste unsigned int byte_size) 36254721Semaste{ 37254721Semaste lldb::offset_t saved_offset = *offset_ptr; 38254721Semaste *value = data.GetMaxU64(offset_ptr, byte_size); 39254721Semaste return *offset_ptr != saved_offset; 40254721Semaste} 41254721Semaste 42254721Semastestatic bool 43254721SemasteParseAuxvEntry(DataExtractor &data, 44254721Semaste AuxVector::Entry &entry, 45254721Semaste lldb::offset_t *offset_ptr, 46254721Semaste unsigned int byte_size) 47254721Semaste{ 48254721Semaste if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size)) 49254721Semaste return false; 50254721Semaste 51254721Semaste if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size)) 52254721Semaste return false; 53254721Semaste 54254721Semaste return true; 55254721Semaste} 56254721Semaste 57254721SemasteDataBufferSP 58254721SemasteAuxVector::GetAuxvData() 59254721Semaste{ 60263363Semaste#if defined(__linux__) || defined(__FreeBSD__) 61254721Semaste if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 62254721Semaste return static_cast<ProcessElfCore *>(m_process)->GetAuxvData(); 63254721Semaste#endif 64254721Semaste return lldb_private::Host::GetAuxvData(m_process); 65254721Semaste} 66254721Semaste 67254721Semastevoid 68254721SemasteAuxVector::ParseAuxv(DataExtractor &data) 69254721Semaste{ 70254721Semaste const unsigned int byte_size = m_process->GetAddressByteSize(); 71254721Semaste lldb::offset_t offset = 0; 72254721Semaste 73254721Semaste for (;;) 74254721Semaste { 75254721Semaste Entry entry; 76254721Semaste 77254721Semaste if (!ParseAuxvEntry(data, entry, &offset, byte_size)) 78254721Semaste break; 79254721Semaste 80254721Semaste if (entry.type == AT_NULL) 81254721Semaste break; 82254721Semaste 83254721Semaste if (entry.type == AT_IGNORE) 84254721Semaste continue; 85254721Semaste 86254721Semaste m_auxv.push_back(entry); 87254721Semaste } 88254721Semaste} 89254721Semaste 90254721SemasteAuxVector::AuxVector(Process *process) 91254721Semaste : m_process(process) 92254721Semaste{ 93254721Semaste DataExtractor data; 94254721Semaste Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 95254721Semaste 96254721Semaste data.SetData(GetAuxvData()); 97254721Semaste data.SetByteOrder(m_process->GetByteOrder()); 98254721Semaste data.SetAddressByteSize(m_process->GetAddressByteSize()); 99254721Semaste 100254721Semaste ParseAuxv(data); 101254721Semaste 102254721Semaste if (log) 103254721Semaste DumpToLog(log); 104254721Semaste} 105254721Semaste 106254721SemasteAuxVector::iterator 107254721SemasteAuxVector::FindEntry(EntryType type) const 108254721Semaste{ 109254721Semaste for (iterator I = begin(); I != end(); ++I) 110254721Semaste { 111254721Semaste if (I->type == static_cast<uint64_t>(type)) 112254721Semaste return I; 113254721Semaste } 114254721Semaste 115254721Semaste return end(); 116254721Semaste} 117254721Semaste 118254721Semastevoid 119254721SemasteAuxVector::DumpToLog(Log *log) const 120254721Semaste{ 121254721Semaste if (!log) 122254721Semaste return; 123254721Semaste 124254721Semaste log->PutCString("AuxVector: "); 125254721Semaste for (iterator I = begin(); I != end(); ++I) 126254721Semaste { 127254721Semaste log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value); 128254721Semaste } 129254721Semaste} 130254721Semaste 131254721Semasteconst char * 132254721SemasteAuxVector::GetEntryName(EntryType type) 133254721Semaste{ 134254721Semaste const char *name = "AT_???"; 135254721Semaste 136254721Semaste#define ENTRY_NAME(_type) _type: name = #_type 137254721Semaste switch (type) 138254721Semaste { 139254721Semaste case ENTRY_NAME(AT_NULL); break; 140254721Semaste case ENTRY_NAME(AT_IGNORE); break; 141254721Semaste case ENTRY_NAME(AT_EXECFD); break; 142254721Semaste case ENTRY_NAME(AT_PHDR); break; 143254721Semaste case ENTRY_NAME(AT_PHENT); break; 144254721Semaste case ENTRY_NAME(AT_PHNUM); break; 145254721Semaste case ENTRY_NAME(AT_PAGESZ); break; 146254721Semaste case ENTRY_NAME(AT_BASE); break; 147254721Semaste case ENTRY_NAME(AT_FLAGS); break; 148254721Semaste case ENTRY_NAME(AT_ENTRY); break; 149254721Semaste case ENTRY_NAME(AT_NOTELF); break; 150254721Semaste case ENTRY_NAME(AT_UID); break; 151254721Semaste case ENTRY_NAME(AT_EUID); break; 152254721Semaste case ENTRY_NAME(AT_GID); break; 153254721Semaste case ENTRY_NAME(AT_EGID); break; 154254721Semaste case ENTRY_NAME(AT_CLKTCK); break; 155254721Semaste case ENTRY_NAME(AT_PLATFORM); break; 156254721Semaste case ENTRY_NAME(AT_HWCAP); break; 157254721Semaste case ENTRY_NAME(AT_FPUCW); break; 158254721Semaste case ENTRY_NAME(AT_DCACHEBSIZE); break; 159254721Semaste case ENTRY_NAME(AT_ICACHEBSIZE); break; 160254721Semaste case ENTRY_NAME(AT_UCACHEBSIZE); break; 161254721Semaste case ENTRY_NAME(AT_IGNOREPPC); break; 162254721Semaste case ENTRY_NAME(AT_SECURE); break; 163254721Semaste case ENTRY_NAME(AT_BASE_PLATFORM); break; 164254721Semaste case ENTRY_NAME(AT_RANDOM); break; 165254721Semaste case ENTRY_NAME(AT_EXECFN); break; 166254721Semaste case ENTRY_NAME(AT_SYSINFO); break; 167254721Semaste case ENTRY_NAME(AT_SYSINFO_EHDR); break; 168254721Semaste case ENTRY_NAME(AT_L1I_CACHESHAPE); break; 169254721Semaste case ENTRY_NAME(AT_L1D_CACHESHAPE); break; 170254721Semaste case ENTRY_NAME(AT_L2_CACHESHAPE); break; 171254721Semaste case ENTRY_NAME(AT_L3_CACHESHAPE); break; 172254721Semaste } 173254721Semaste#undef ENTRY_NAME 174254721Semaste 175254721Semaste return name; 176254721Semaste} 177254721Semaste 178