#include "util/test_utils.h"
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <cstdarg>
#include <cstring>
#include <iostream>
#include "common/debug.h"
#include "common/platform.h"
#include "common/system_utils.h"
#if !defined(ANGLE_PLATFORM_FUCHSIA)
# include <sys/resource.h>
#endif
#if defined(ANGLE_PLATFORM_MACOS)
# include <crt_externs.h>
#endif
namespace angle
{
namespace
{
#if defined(ANGLE_PLATFORM_MACOS)
constexpr char kSkipFileHookingArg[] = "--skip-file-hooking";
#endif
struct ScopedPipe
{ … };
enum class ReadResult
{ … };
ReadResult ReadFromFile(int fd, std::string *out)
{ … }
void ReadEntireFile(int fd, std::string *out)
{ … }
class PosixProcess : public Process
{ … };
}
void Sleep(unsigned int milliseconds)
{ … }
void SetLowPriorityProcess()
{ … }
void WriteDebugMessage(const char *format, ...)
{ … }
bool StabilizeCPUForBenchmarking()
{ … }
bool DeleteSystemFile(const char *path)
{ … }
Process *LaunchProcess(const std::vector<const char *> &args, ProcessOutputCapture captureOutput)
{ … }
int NumberOfProcessors()
{ … }
const char *GetNativeEGLLibraryNameWithExtension()
{ … }
#if defined(ANGLE_PLATFORM_MACOS)
void InitMetalFileAPIHooking(int argc, char **argv)
{
if (argc < 1)
{
return;
}
for (int i = 0; i < argc; ++i)
{
if (strncmp(argv[i], kSkipFileHookingArg, strlen(kSkipFileHookingArg)) == 0)
{
return;
}
}
constexpr char kInjectLibVarName[] = "DYLD_INSERT_LIBRARIES";
constexpr size_t kInjectLibVarNameLen = sizeof(kInjectLibVarName) - 1;
std::string exeDir = GetExecutableDirectory();
if (!exeDir.empty() && exeDir.back() != '/')
{
exeDir += "/";
}
std::string injectLibsVar =
std::string(kInjectLibVarName) + "=" + exeDir + "libmetal_shader_cache_file_hooking.dylib";
char skipHookOption[sizeof(kSkipFileHookingArg)];
memcpy(skipHookOption, kSkipFileHookingArg, sizeof(kSkipFileHookingArg));
std::vector<char *> newEnv;
char **environ = *_NSGetEnviron();
for (int i = 0; environ[i]; ++i)
{
if (strncmp(environ[i], kInjectLibVarName, kInjectLibVarNameLen) == 0)
{
injectLibsVar += ':';
injectLibsVar += environ[i] + kInjectLibVarNameLen + 1;
}
else
{
newEnv.push_back(environ[i]);
}
}
newEnv.push_back(strdup(injectLibsVar.data()));
newEnv.push_back(nullptr);
std::vector<char *> newArgs;
newArgs.push_back(argv[0]);
newArgs.push_back(skipHookOption);
for (int i = 1; i < argc; ++i)
{
newArgs.push_back(argv[i]);
}
newArgs.push_back(nullptr);
ASSERT(-1 != execve(argv[0], newArgs.data(), newEnv.data()));
}
#endif
}