| // | |
| // Copyright 2014 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // system_utils.h: declaration of OS-specific utility functions | |
| #ifndef COMMON_SYSTEM_UTILS_H_ | |
| #define COMMON_SYSTEM_UTILS_H_ | |
| #include "common/Optional.h" | |
| #include "common/angleutils.h" | |
| #include <functional> | |
| #include <string> | |
| #include <string_view> | |
| namespace angle | |
| { | |
| std::string GetExecutableName(); | |
| std::string GetExecutablePath(); | |
| std::string GetExecutableDirectory(); | |
| std::string GetModuleDirectory(); | |
| const char *GetSharedLibraryExtension(); | |
| const char *GetExecutableExtension(); | |
| char GetPathSeparator(); | |
| Optional<std::string> GetCWD(); | |
| bool SetCWD(const char *dirName); | |
| bool SetEnvironmentVar(const char *variableName, const char *value); | |
| bool UnsetEnvironmentVar(const char *variableName); | |
| bool GetBoolEnvironmentVar(const char *variableName); | |
| std::string GetEnvironmentVar(const char *variableName); | |
| std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, | |
| const char *propertyName); | |
| std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName, | |
| const char *propertyName); | |
| std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName); | |
| const char *GetPathSeparatorForEnvironmentVar(); | |
| bool PrependPathToEnvironmentVar(const char *variableName, const char *path); | |
| bool IsDirectory(const char *filename); | |
| bool IsFullPath(std::string dirName); | |
| std::string GetRootDirectory(); | |
| std::string ConcatenatePath(std::string first, std::string second); | |
| // Get absolute time in seconds. Use this function to get an absolute time with an unknown origin. | |
| double GetCurrentSystemTime(); | |
| // Get CPU time for current process in seconds. | |
| double GetCurrentProcessCpuTime(); | |
| // Run an application and get the output. Gets a nullptr-terminated set of args to execute the | |
| // application with, and returns the stdout and stderr outputs as well as the exit code. | |
| // | |
| // Pass nullptr for stdoutOut/stderrOut if you don't need to capture. exitCodeOut is required. | |
| // | |
| // Returns false if it fails to actually execute the application. | |
| bool RunApp(const std::vector<const char *> &args, | |
| std::string *stdoutOut, | |
| std::string *stderrOut, | |
| int *exitCodeOut); | |
| // Use SYSTEM_DIR to bypass loading ANGLE libraries with the same name as system DLLS | |
| // (e.g. opengl32.dll) | |
| enum class SearchType | |
| { | |
| // Try to find the library in the same directory as the current module | |
| ModuleDir, | |
| // Load the library from the system directories | |
| SystemDir, | |
| // Get a reference to an already loaded shared library. | |
| AlreadyLoaded, | |
| }; | |
| void *OpenSystemLibrary(const char *libraryName, SearchType searchType); | |
| void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType); | |
| void *OpenSystemLibraryAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut); | |
| void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut); | |
| void *GetLibrarySymbol(void *libraryHandle, const char *symbolName); | |
| std::string GetLibraryPath(void *libraryHandle); | |
| void CloseSystemLibrary(void *libraryHandle); | |
| class Library : angle::NonCopyable | |
| { | |
| public: | |
| Library() {} | |
| Library(void *libraryHandle) : mLibraryHandle(libraryHandle) {} | |
| ~Library() { close(); } | |
| ANGLE_NO_DISCARD bool open(const char *libraryName, SearchType searchType) | |
| { | |
| close(); | |
| mLibraryHandle = OpenSystemLibrary(libraryName, searchType); | |
| return mLibraryHandle != nullptr; | |
| } | |
| ANGLE_NO_DISCARD bool openWithExtension(const char *libraryName, SearchType searchType) | |
| { | |
| close(); | |
| mLibraryHandle = OpenSystemLibraryWithExtension(libraryName, searchType); | |
| return mLibraryHandle != nullptr; | |
| } | |
| ANGLE_NO_DISCARD bool openAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut) | |
| { | |
| close(); | |
| mLibraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut); | |
| return mLibraryHandle != nullptr; | |
| } | |
| ANGLE_NO_DISCARD bool openWithExtensionAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut) | |
| { | |
| close(); | |
| mLibraryHandle = | |
| OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut); | |
| return mLibraryHandle != nullptr; | |
| } | |
| void close() | |
| { | |
| if (mLibraryHandle) | |
| { | |
| CloseSystemLibrary(mLibraryHandle); | |
| mLibraryHandle = nullptr; | |
| } | |
| } | |
| void *getSymbol(const char *symbolName) { return GetLibrarySymbol(mLibraryHandle, symbolName); } | |
| void *getNative() const { return mLibraryHandle; } | |
| std::string getPath() const { return GetLibraryPath(mLibraryHandle); } | |
| template <typename FuncT> | |
| void getAs(const char *symbolName, FuncT *funcOut) | |
| { | |
| *funcOut = reinterpret_cast<FuncT>(getSymbol(symbolName)); | |
| } | |
| private: | |
| void *mLibraryHandle = nullptr; | |
| }; | |
| Library *OpenSharedLibrary(const char *libraryName, SearchType searchType); | |
| Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType); | |
| Library *OpenSharedLibraryAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut); | |
| Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName, | |
| SearchType searchType, | |
| std::string *errorOut); | |
| // Returns true if the process is currently being debugged. | |
| bool IsDebuggerAttached(); | |
| // Calls system APIs to break into the debugger. | |
| void BreakDebugger(); | |
| uint64_t GetProcessMemoryUsageKB(); | |
| bool ProtectMemory(uintptr_t start, size_t size); | |
| bool UnprotectMemory(uintptr_t start, size_t size); | |
| size_t GetPageSize(); | |
| // Return type of the PageFaultCallback | |
| enum class PageFaultHandlerRangeType | |
| { | |
| // The memory address was known by the page fault handler | |
| InRange, | |
| // The memory address was not in the page fault handler's range | |
| // and the signal will be forwarded to the default page handler. | |
| OutOfRange, | |
| }; | |
| using PageFaultCallback = std::function<PageFaultHandlerRangeType(uintptr_t)>; | |
| class PageFaultHandler : angle::NonCopyable | |
| { | |
| public: | |
| PageFaultHandler(PageFaultCallback callback); | |
| virtual ~PageFaultHandler(); | |
| // Registers OS level page fault handler for memory protection signals | |
| // and enables reception on PageFaultCallback | |
| virtual bool enable() = 0; | |
| // Unregisters OS level page fault handler and deactivates PageFaultCallback | |
| virtual bool disable() = 0; | |
| protected: | |
| PageFaultCallback mCallback; | |
| }; | |
| // Creates single instance page fault handler | |
| PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback); | |
| #ifdef ANGLE_PLATFORM_WINDOWS | |
| // Convert an UTF-16 wstring to an UTF-8 string. | |
| std::string Narrow(const std::wstring_view &utf16); | |
| // Convert an UTF-8 string to an UTF-16 wstring. | |
| std::wstring Widen(const std::string_view &utf8); | |
| #endif | |
| } // namespace angle | |
| #endif // COMMON_SYSTEM_UTILS_H_ |