1//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// C Includes 11#include <fcntl.h> 12#include <sys/stat.h> 13#include <sys/types.h> 14 15// C++ Includes 16// Other libraries and framework includes 17#include "lldb/Core/DataBufferHeap.h" 18#include "lldb/Core/DataExtractor.h" 19#include "lldb/Core/Log.h" 20#include "lldb/Target/Process.h" 21 22#if defined(__linux__) or defined(__FreeBSD__) 23#include "Plugins/Process/elf-core/ProcessElfCore.h" 24#endif 25 26#include "AuxVector.h" 27 28using namespace lldb; 29using namespace lldb_private; 30 31static bool 32GetMaxU64(DataExtractor &data, 33 lldb::offset_t *offset_ptr, 34 uint64_t *value, 35 unsigned int byte_size) 36{ 37 lldb::offset_t saved_offset = *offset_ptr; 38 *value = data.GetMaxU64(offset_ptr, byte_size); 39 return *offset_ptr != saved_offset; 40} 41 42static bool 43ParseAuxvEntry(DataExtractor &data, 44 AuxVector::Entry &entry, 45 lldb::offset_t *offset_ptr, 46 unsigned int byte_size) 47{ 48 if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size)) 49 return false; 50 51 if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size)) 52 return false; 53 54 return true; 55} 56 57DataBufferSP 58AuxVector::GetAuxvData() 59{ 60#if defined(__linux__) or defined(__FreeBSD__) 61 if (m_process->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) 62 return static_cast<ProcessElfCore *>(m_process)->GetAuxvData(); 63#endif 64 return lldb_private::Host::GetAuxvData(m_process); 65} 66 67void 68AuxVector::ParseAuxv(DataExtractor &data) 69{ 70 const unsigned int byte_size = m_process->GetAddressByteSize(); 71 lldb::offset_t offset = 0; 72 73 for (;;) 74 { 75 Entry entry; 76 77 if (!ParseAuxvEntry(data, entry, &offset, byte_size)) 78 break; 79 80 if (entry.type == AT_NULL) 81 break; 82 83 if (entry.type == AT_IGNORE) 84 continue; 85 86 m_auxv.push_back(entry); 87 } 88} 89 90AuxVector::AuxVector(Process *process) 91 : m_process(process) 92{ 93 DataExtractor data; 94 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 95 96 data.SetData(GetAuxvData()); 97 data.SetByteOrder(m_process->GetByteOrder()); 98 data.SetAddressByteSize(m_process->GetAddressByteSize()); 99 100 ParseAuxv(data); 101 102 if (log) 103 DumpToLog(log); 104} 105 106AuxVector::iterator 107AuxVector::FindEntry(EntryType type) const 108{ 109 for (iterator I = begin(); I != end(); ++I) 110 { 111 if (I->type == static_cast<uint64_t>(type)) 112 return I; 113 } 114 115 return end(); 116} 117 118void 119AuxVector::DumpToLog(Log *log) const 120{ 121 if (!log) 122 return; 123 124 log->PutCString("AuxVector: "); 125 for (iterator I = begin(); I != end(); ++I) 126 { 127 log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value); 128 } 129} 130 131const char * 132AuxVector::GetEntryName(EntryType type) 133{ 134 const char *name = "AT_???"; 135 136#define ENTRY_NAME(_type) _type: name = #_type 137 switch (type) 138 { 139 case ENTRY_NAME(AT_NULL); break; 140 case ENTRY_NAME(AT_IGNORE); break; 141 case ENTRY_NAME(AT_EXECFD); break; 142 case ENTRY_NAME(AT_PHDR); break; 143 case ENTRY_NAME(AT_PHENT); break; 144 case ENTRY_NAME(AT_PHNUM); break; 145 case ENTRY_NAME(AT_PAGESZ); break; 146 case ENTRY_NAME(AT_BASE); break; 147 case ENTRY_NAME(AT_FLAGS); break; 148 case ENTRY_NAME(AT_ENTRY); break; 149 case ENTRY_NAME(AT_NOTELF); break; 150 case ENTRY_NAME(AT_UID); break; 151 case ENTRY_NAME(AT_EUID); break; 152 case ENTRY_NAME(AT_GID); break; 153 case ENTRY_NAME(AT_EGID); break; 154 case ENTRY_NAME(AT_CLKTCK); break; 155 case ENTRY_NAME(AT_PLATFORM); break; 156 case ENTRY_NAME(AT_HWCAP); break; 157 case ENTRY_NAME(AT_FPUCW); break; 158 case ENTRY_NAME(AT_DCACHEBSIZE); break; 159 case ENTRY_NAME(AT_ICACHEBSIZE); break; 160 case ENTRY_NAME(AT_UCACHEBSIZE); break; 161 case ENTRY_NAME(AT_IGNOREPPC); break; 162 case ENTRY_NAME(AT_SECURE); break; 163 case ENTRY_NAME(AT_BASE_PLATFORM); break; 164 case ENTRY_NAME(AT_RANDOM); break; 165 case ENTRY_NAME(AT_EXECFN); break; 166 case ENTRY_NAME(AT_SYSINFO); break; 167 case ENTRY_NAME(AT_SYSINFO_EHDR); break; 168 case ENTRY_NAME(AT_L1I_CACHESHAPE); break; 169 case ENTRY_NAME(AT_L1D_CACHESHAPE); break; 170 case ENTRY_NAME(AT_L2_CACHESHAPE); break; 171 case ENTRY_NAME(AT_L3_CACHESHAPE); break; 172 } 173#undef ENTRY_NAME 174 175 return name; 176} 177 178