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 GetMaxU64(DataExtractor &data, lldb::offset_t *offset_ptr, 32 uint64_t *value, unsigned int byte_size) { 33 lldb::offset_t saved_offset = *offset_ptr; 34 *value = data.GetMaxU64(offset_ptr, byte_size); 35 return *offset_ptr != saved_offset; 36 } 37 38 static bool ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry, 39 lldb::offset_t *offset_ptr, unsigned int byte_size) { 40 if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size)) 41 return false; 42 43 if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size)) 44 return false; 45 46 return true; 47 } 48 49 DataBufferSP AuxVector::GetAuxvData() { 50 if (m_process) 51 return m_process->GetAuxvData(); 52 else 53 return DataBufferSP(); 54 } 55 56 void AuxVector::ParseAuxv(DataExtractor &data) { 57 const unsigned int byte_size = m_process->GetAddressByteSize(); 58 lldb::offset_t offset = 0; 59 60 for (;;) { 61 Entry entry; 62 63 if (!ParseAuxvEntry(data, entry, &offset, byte_size)) 64 break; 65 66 if (entry.type == AT_NULL) 67 break; 68 69 if (entry.type == AT_IGNORE) 70 continue; 71 72 m_auxv.push_back(entry); 73 } 74 } 75 76 AuxVector::AuxVector(Process *process) : m_process(process) { 77 DataExtractor data; 78 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); 79 80 data.SetData(GetAuxvData()); 81 data.SetByteOrder(m_process->GetByteOrder()); 82 data.SetAddressByteSize(m_process->GetAddressByteSize()); 83 84 ParseAuxv(data); 85 86 if (log) 87 DumpToLog(log); 88 } 89 90 AuxVector::iterator AuxVector::FindEntry(EntryType type) const { 91 for (iterator I = begin(); I != end(); ++I) { 92 if (I->type == static_cast<uint64_t>(type)) 93 return I; 94 } 95 96 return end(); 97 } 98 99 void AuxVector::DumpToLog(Log *log) const { 100 if (!log) 101 return; 102 103 log->PutCString("AuxVector: "); 104 for (iterator I = begin(); I != end(); ++I) { 105 log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, 106 I->value); 107 } 108 } 109 110 const char *AuxVector::GetEntryName(EntryType type) { 111 const char *name = "AT_???"; 112 113 #define ENTRY_NAME(_type) \ 114 _type: \ 115 name = #_type 116 switch (type) { 117 case ENTRY_NAME(AT_NULL); break; 118 case ENTRY_NAME(AT_IGNORE); break; 119 case ENTRY_NAME(AT_EXECFD); break; 120 case ENTRY_NAME(AT_PHDR); break; 121 case ENTRY_NAME(AT_PHENT); break; 122 case ENTRY_NAME(AT_PHNUM); break; 123 case ENTRY_NAME(AT_PAGESZ); break; 124 case ENTRY_NAME(AT_BASE); break; 125 case ENTRY_NAME(AT_FLAGS); break; 126 case ENTRY_NAME(AT_ENTRY); break; 127 case ENTRY_NAME(AT_NOTELF); break; 128 case ENTRY_NAME(AT_UID); break; 129 case ENTRY_NAME(AT_EUID); break; 130 case ENTRY_NAME(AT_GID); break; 131 case ENTRY_NAME(AT_EGID); break; 132 case ENTRY_NAME(AT_CLKTCK); break; 133 case ENTRY_NAME(AT_PLATFORM); break; 134 case ENTRY_NAME(AT_HWCAP); break; 135 case ENTRY_NAME(AT_FPUCW); break; 136 case ENTRY_NAME(AT_DCACHEBSIZE); break; 137 case ENTRY_NAME(AT_ICACHEBSIZE); break; 138 case ENTRY_NAME(AT_UCACHEBSIZE); break; 139 case ENTRY_NAME(AT_IGNOREPPC); break; 140 case ENTRY_NAME(AT_SECURE); break; 141 case ENTRY_NAME(AT_BASE_PLATFORM); break; 142 case ENTRY_NAME(AT_RANDOM); break; 143 case ENTRY_NAME(AT_EXECFN); break; 144 case ENTRY_NAME(AT_SYSINFO); break; 145 case ENTRY_NAME(AT_SYSINFO_EHDR); break; 146 case ENTRY_NAME(AT_L1I_CACHESHAPE); break; 147 case ENTRY_NAME(AT_L1D_CACHESHAPE); break; 148 case ENTRY_NAME(AT_L2_CACHESHAPE); break; 149 case ENTRY_NAME(AT_L3_CACHESHAPE); break; 150 } 151 #undef ENTRY_NAME 152 153 return name; 154 } 155