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__) || defined(__FreeBSD__) 23 #include "Plugins/Process/elf-core/ProcessElfCore.h" 24 #endif 25 26 #include "AuxVector.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 static bool 32 GetMaxU64(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 42 static bool 43 ParseAuxvEntry(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 57 DataBufferSP 58 AuxVector::GetAuxvData() 59 { 60 if (m_process) 61 return m_process->GetAuxvData (); 62 else 63 return DataBufferSP (); 64 } 65 66 void 67 AuxVector::ParseAuxv(DataExtractor &data) 68 { 69 const unsigned int byte_size = m_process->GetAddressByteSize(); 70 lldb::offset_t offset = 0; 71 72 for (;;) 73 { 74 Entry entry; 75 76 if (!ParseAuxvEntry(data, entry, &offset, byte_size)) 77 break; 78 79 if (entry.type == AT_NULL) 80 break; 81 82 if (entry.type == AT_IGNORE) 83 continue; 84 85 m_auxv.push_back(entry); 86 } 87 } 88 89 AuxVector::AuxVector(Process *process) 90 : m_process(process) 91 { 92 DataExtractor data; 93 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 94 95 data.SetData(GetAuxvData()); 96 data.SetByteOrder(m_process->GetByteOrder()); 97 data.SetAddressByteSize(m_process->GetAddressByteSize()); 98 99 ParseAuxv(data); 100 101 if (log) 102 DumpToLog(log); 103 } 104 105 AuxVector::iterator 106 AuxVector::FindEntry(EntryType type) const 107 { 108 for (iterator I = begin(); I != end(); ++I) 109 { 110 if (I->type == static_cast<uint64_t>(type)) 111 return I; 112 } 113 114 return end(); 115 } 116 117 void 118 AuxVector::DumpToLog(Log *log) const 119 { 120 if (!log) 121 return; 122 123 log->PutCString("AuxVector: "); 124 for (iterator I = begin(); I != end(); ++I) 125 { 126 log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value); 127 } 128 } 129 130 const char * 131 AuxVector::GetEntryName(EntryType type) 132 { 133 const char *name = "AT_???"; 134 135 #define ENTRY_NAME(_type) _type: name = #_type 136 switch (type) 137 { 138 case ENTRY_NAME(AT_NULL); break; 139 case ENTRY_NAME(AT_IGNORE); break; 140 case ENTRY_NAME(AT_EXECFD); break; 141 case ENTRY_NAME(AT_PHDR); break; 142 case ENTRY_NAME(AT_PHENT); break; 143 case ENTRY_NAME(AT_PHNUM); break; 144 case ENTRY_NAME(AT_PAGESZ); break; 145 case ENTRY_NAME(AT_BASE); break; 146 case ENTRY_NAME(AT_FLAGS); break; 147 case ENTRY_NAME(AT_ENTRY); break; 148 case ENTRY_NAME(AT_NOTELF); break; 149 case ENTRY_NAME(AT_UID); break; 150 case ENTRY_NAME(AT_EUID); break; 151 case ENTRY_NAME(AT_GID); break; 152 case ENTRY_NAME(AT_EGID); break; 153 case ENTRY_NAME(AT_CLKTCK); break; 154 case ENTRY_NAME(AT_PLATFORM); break; 155 case ENTRY_NAME(AT_HWCAP); break; 156 case ENTRY_NAME(AT_FPUCW); break; 157 case ENTRY_NAME(AT_DCACHEBSIZE); break; 158 case ENTRY_NAME(AT_ICACHEBSIZE); break; 159 case ENTRY_NAME(AT_UCACHEBSIZE); break; 160 case ENTRY_NAME(AT_IGNOREPPC); break; 161 case ENTRY_NAME(AT_SECURE); break; 162 case ENTRY_NAME(AT_BASE_PLATFORM); break; 163 case ENTRY_NAME(AT_RANDOM); break; 164 case ENTRY_NAME(AT_EXECFN); break; 165 case ENTRY_NAME(AT_SYSINFO); break; 166 case ENTRY_NAME(AT_SYSINFO_EHDR); break; 167 case ENTRY_NAME(AT_L1I_CACHESHAPE); break; 168 case ENTRY_NAME(AT_L1D_CACHESHAPE); break; 169 case ENTRY_NAME(AT_L2_CACHESHAPE); break; 170 case ENTRY_NAME(AT_L3_CACHESHAPE); break; 171 } 172 #undef ENTRY_NAME 173 174 return name; 175 } 176 177