1 //===-- source/Host/windows/Host.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 <stdio.h> 12 #include "lldb/Host/windows/windows.h" 13 #include "lldb/Host/windows/AutoHandle.h" 14 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Core/Error.h" 19 #include "lldb/Core/Log.h" 20 #include "lldb/Target/Process.h" 21 22 #include "lldb/Host/Host.h" 23 #include "lldb/Core/DataBufferHeap.h" 24 #include "lldb/Core/DataExtractor.h" 25 #include "lldb/Core/StreamFile.h" 26 27 // Windows includes 28 #include <TlHelp32.h> 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 namespace 34 { 35 bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) 36 { 37 // Open the PE File as a binary file, and parse just enough information to determine the 38 // machine type. 39 File imageBinary( 40 executable.GetPath().c_str(), 41 File::eOpenOptionRead, 42 lldb::eFilePermissionsUserRead); 43 imageBinary.SeekFromStart(0x3c); 44 int32_t peOffset = 0; 45 uint32_t peHead = 0; 46 uint16_t machineType = 0; 47 size_t readSize = sizeof(peOffset); 48 imageBinary.Read(&peOffset, readSize); 49 imageBinary.SeekFromStart(peOffset); 50 imageBinary.Read(&peHead, readSize); 51 if (peHead != 0x00004550) // "PE\0\0", little-endian 52 return false; // Error: Can't find PE header 53 readSize = 2; 54 imageBinary.Read(&machineType, readSize); 55 triple.setVendor(llvm::Triple::PC); 56 triple.setOS(llvm::Triple::Win32); 57 triple.setArch(llvm::Triple::UnknownArch); 58 if (machineType == 0x8664) 59 triple.setArch(llvm::Triple::x86_64); 60 else if (machineType == 0x14c) 61 triple.setArch(llvm::Triple::x86); 62 63 return true; 64 } 65 66 bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) 67 { 68 // Get the process image path. MAX_PATH isn't long enough, paths can actually be up to 32KB. 69 std::vector<char> buffer(32768); 70 DWORD dwSize = buffer.size(); 71 if (!::QueryFullProcessImageNameA(handle.get(), 0, &buffer[0], &dwSize)) 72 return false; 73 path.assign(&buffer[0]); 74 return true; 75 } 76 77 void GetProcessExecutableAndTriple(const AutoHandle &handle, ProcessInstanceInfo &process) 78 { 79 // We may not have permissions to read the path from the process. So start off by 80 // setting the executable file to whatever Toolhelp32 gives us, and then try to 81 // enhance this with more detailed information, but fail gracefully. 82 std::string executable; 83 llvm::Triple triple; 84 triple.setVendor(llvm::Triple::PC); 85 triple.setOS(llvm::Triple::Win32); 86 triple.setArch(llvm::Triple::UnknownArch); 87 if (GetExecutableForProcess(handle, executable)) 88 { 89 FileSpec executableFile(executable.c_str(), false); 90 process.SetExecutableFile(executableFile, true); 91 GetTripleForProcess(executableFile, triple); 92 } 93 process.SetArchitecture(ArchSpec(triple)); 94 95 // TODO(zturner): Add the ability to get the process user name. 96 } 97 } 98 99 lldb::DataBufferSP 100 Host::GetAuxvData(lldb_private::Process *process) 101 { 102 return 0; 103 } 104 105 lldb::tid_t 106 Host::GetCurrentThreadID() 107 { 108 return lldb::tid_t(::GetCurrentThreadId()); 109 } 110 111 lldb::thread_t 112 Host::GetCurrentThread () 113 { 114 return lldb::thread_t(::GetCurrentThread()); 115 } 116 117 lldb::thread_key_t 118 Host::ThreadLocalStorageCreate(ThreadLocalStorageCleanupCallback callback) 119 { 120 return TlsAlloc(); 121 } 122 123 void* 124 Host::ThreadLocalStorageGet(lldb::thread_key_t key) 125 { 126 return ::TlsGetValue (key); 127 } 128 129 void 130 Host::ThreadLocalStorageSet(lldb::thread_key_t key, void *value) 131 { 132 ::TlsSetValue (key, value); 133 } 134 135 void 136 Host::Kill(lldb::pid_t pid, int signo) 137 { 138 TerminateProcess((HANDLE) pid, 1); 139 } 140 141 142 const char * 143 Host::GetSignalAsCString(int signo) 144 { 145 return NULL; 146 } 147 148 FileSpec 149 Host::GetModuleFileSpecForHostAddress (const void *host_addr) 150 { 151 FileSpec module_filespec; 152 153 HMODULE hmodule = NULL; 154 if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)host_addr, &hmodule)) 155 return module_filespec; 156 157 std::vector<char> buffer(MAX_PATH); 158 DWORD chars_copied = 0; 159 do { 160 chars_copied = ::GetModuleFileName(hmodule, &buffer[0], buffer.size()); 161 if (chars_copied == buffer.size() && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) 162 buffer.resize(buffer.size() * 2); 163 } while (chars_copied >= buffer.size()); 164 165 module_filespec.SetFile(&buffer[0], false); 166 return module_filespec; 167 } 168 169 uint32_t 170 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) 171 { 172 process_infos.Clear(); 173 174 AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); 175 if (!snapshot.IsValid()) 176 return 0; 177 178 PROCESSENTRY32 pe = {0}; 179 pe.dwSize = sizeof(PROCESSENTRY32); 180 if (Process32First(snapshot.get(), &pe)) 181 { 182 do 183 { 184 AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr); 185 186 ProcessInstanceInfo process; 187 process.SetExecutableFile(FileSpec(pe.szExeFile, false), true); 188 process.SetProcessID(pe.th32ProcessID); 189 process.SetParentProcessID(pe.th32ParentProcessID); 190 GetProcessExecutableAndTriple(handle, process); 191 192 if (match_info.MatchAllProcesses() || match_info.Matches(process)) 193 process_infos.Append(process); 194 } while (Process32Next(snapshot.get(), &pe)); 195 } 196 return process_infos.GetSize(); 197 } 198 199 bool 200 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 201 { 202 process_info.Clear(); 203 204 AutoHandle handle(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid), 205 nullptr); 206 if (!handle.IsValid()) 207 return false; 208 209 process_info.SetProcessID(pid); 210 GetProcessExecutableAndTriple(handle, process_info); 211 212 // Need to read the PEB to get parent process and command line arguments. 213 return true; 214 } 215 216 HostThread 217 Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals) 218 { 219 return HostThread(); 220 }