1 // 2 // Copyright 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // system_utils.h: declaration of OS-specific utility functions 8 9 #ifndef COMMON_SYSTEM_UTILS_H_ 10 #define COMMON_SYSTEM_UTILS_H_ 11 12 #include "common/Optional.h" 13 #include "common/angleutils.h" 14 15 #include <functional> 16 #include <string> 17 #include <string_view> 18 19 namespace angle 20 { 21 std::string GetExecutableName(); 22 std::string GetExecutablePath(); 23 std::string GetExecutableDirectory(); 24 std::string GetModuleDirectory(); 25 const char *GetSharedLibraryExtension(); 26 const char *GetExecutableExtension(); 27 char GetPathSeparator(); 28 Optional<std::string> GetCWD(); 29 bool SetCWD(const char *dirName); 30 bool SetEnvironmentVar(const char *variableName, const char *value); 31 bool UnsetEnvironmentVar(const char *variableName); 32 bool GetBoolEnvironmentVar(const char *variableName); 33 std::string GetEnvironmentVar(const char *variableName); 34 std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, 35 const char *propertyName); 36 std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, 37 const char *propertyName); 38 std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName); 39 const char *GetPathSeparatorForEnvironmentVar(); 40 bool PrependPathToEnvironmentVar(const char *variableName, const char *path); 41 bool IsDirectory(const char *filename); 42 bool IsFullPath(std::string dirName); 43 std::string GetRootDirectory(); 44 std::string ConcatenatePath(std::string first, std::string second); 45 46 // Get absolute time in seconds. Use this function to get an absolute time with an unknown origin. 47 double GetCurrentSystemTime(); 48 // Get CPU time for current process in seconds. 49 double GetCurrentProcessCpuTime(); 50 51 // Run an application and get the output. Gets a nullptr-terminated set of args to execute the 52 // application with, and returns the stdout and stderr outputs as well as the exit code. 53 // 54 // Pass nullptr for stdoutOut/stderrOut if you don't need to capture. exitCodeOut is required. 55 // 56 // Returns false if it fails to actually execute the application. 57 bool RunApp(const std::vector<const char *> &args, 58 std::string *stdoutOut, 59 std::string *stderrOut, 60 int *exitCodeOut); 61 62 // Use SYSTEM_DIR to bypass loading ANGLE libraries with the same name as system DLLS 63 // (e.g. opengl32.dll) 64 enum class SearchType 65 { 66 // Try to find the library in the same directory as the current module 67 ModuleDir, 68 // Load the library from the system directories 69 SystemDir, 70 // Get a reference to an already loaded shared library. 71 AlreadyLoaded, 72 }; 73 74 void *OpenSystemLibrary(const char *libraryName, SearchType searchType); 75 void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType); 76 void *OpenSystemLibraryAndGetError(const char *libraryName, 77 SearchType searchType, 78 std::string *errorOut); 79 void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, 80 SearchType searchType, 81 std::string *errorOut); 82 83 void *GetLibrarySymbol(void *libraryHandle, const char *symbolName); 84 std::string GetLibraryPath(void *libraryHandle); 85 void CloseSystemLibrary(void *libraryHandle); 86 87 class Library : angle::NonCopyable 88 { 89 public: Library()90 Library() {} Library(void * libraryHandle)91 Library(void *libraryHandle) : mLibraryHandle(libraryHandle) {} ~Library()92 ~Library() { close(); } 93 open(const char * libraryName,SearchType searchType)94 ANGLE_NO_DISCARD bool open(const char *libraryName, SearchType searchType) 95 { 96 close(); 97 mLibraryHandle = OpenSystemLibrary(libraryName, searchType); 98 return mLibraryHandle != nullptr; 99 } 100 openWithExtension(const char * libraryName,SearchType searchType)101 ANGLE_NO_DISCARD bool openWithExtension(const char *libraryName, SearchType searchType) 102 { 103 close(); 104 mLibraryHandle = OpenSystemLibraryWithExtension(libraryName, searchType); 105 return mLibraryHandle != nullptr; 106 } 107 openAndGetError(const char * libraryName,SearchType searchType,std::string * errorOut)108 ANGLE_NO_DISCARD bool openAndGetError(const char *libraryName, 109 SearchType searchType, 110 std::string *errorOut) 111 { 112 close(); 113 mLibraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut); 114 return mLibraryHandle != nullptr; 115 } 116 openWithExtensionAndGetError(const char * libraryName,SearchType searchType,std::string * errorOut)117 ANGLE_NO_DISCARD bool openWithExtensionAndGetError(const char *libraryName, 118 SearchType searchType, 119 std::string *errorOut) 120 { 121 close(); 122 mLibraryHandle = 123 OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut); 124 return mLibraryHandle != nullptr; 125 } 126 close()127 void close() 128 { 129 if (mLibraryHandle) 130 { 131 CloseSystemLibrary(mLibraryHandle); 132 mLibraryHandle = nullptr; 133 } 134 } 135 getSymbol(const char * symbolName)136 void *getSymbol(const char *symbolName) { return GetLibrarySymbol(mLibraryHandle, symbolName); } 137 getNative()138 void *getNative() const { return mLibraryHandle; } 139 getPath()140 std::string getPath() const { return GetLibraryPath(mLibraryHandle); } 141 142 template <typename FuncT> getAs(const char * symbolName,FuncT * funcOut)143 void getAs(const char *symbolName, FuncT *funcOut) 144 { 145 *funcOut = reinterpret_cast<FuncT>(getSymbol(symbolName)); 146 } 147 148 private: 149 void *mLibraryHandle = nullptr; 150 }; 151 152 Library *OpenSharedLibrary(const char *libraryName, SearchType searchType); 153 Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType); 154 Library *OpenSharedLibraryAndGetError(const char *libraryName, 155 SearchType searchType, 156 std::string *errorOut); 157 Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName, 158 SearchType searchType, 159 std::string *errorOut); 160 161 // Returns true if the process is currently being debugged. 162 bool IsDebuggerAttached(); 163 164 // Calls system APIs to break into the debugger. 165 void BreakDebugger(); 166 167 uint64_t GetProcessMemoryUsageKB(); 168 169 bool ProtectMemory(uintptr_t start, size_t size); 170 bool UnprotectMemory(uintptr_t start, size_t size); 171 172 size_t GetPageSize(); 173 174 // Return type of the PageFaultCallback 175 enum class PageFaultHandlerRangeType 176 { 177 // The memory address was known by the page fault handler 178 InRange, 179 // The memory address was not in the page fault handler's range 180 // and the signal will be forwarded to the default page handler. 181 OutOfRange, 182 }; 183 184 using PageFaultCallback = std::function<PageFaultHandlerRangeType(uintptr_t)>; 185 186 class PageFaultHandler : angle::NonCopyable 187 { 188 public: 189 PageFaultHandler(PageFaultCallback callback); 190 virtual ~PageFaultHandler(); 191 192 // Registers OS level page fault handler for memory protection signals 193 // and enables reception on PageFaultCallback 194 virtual bool enable() = 0; 195 196 // Unregisters OS level page fault handler and deactivates PageFaultCallback 197 virtual bool disable() = 0; 198 199 protected: 200 PageFaultCallback mCallback; 201 }; 202 203 // Creates single instance page fault handler 204 PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback); 205 206 #ifdef ANGLE_PLATFORM_WINDOWS 207 // Convert an UTF-16 wstring to an UTF-8 string. 208 std::string Narrow(const std::wstring_view &utf16); 209 210 // Convert an UTF-8 string to an UTF-16 wstring. 211 std::wstring Widen(const std::string_view &utf8); 212 #endif 213 } // namespace angle 214 215 #endif // COMMON_SYSTEM_UTILS_H_ 216