1
1
mirror of https://github.com/rui314/mold.git synced 2024-12-28 19:04:27 +03:00
mold/mold-wrapper.c

113 lines
2.6 KiB
C
Raw Normal View History

2021-03-25 10:03:23 +03:00
#define _GNU_SOURCE 1
#include <dlfcn.h>
2021-03-25 12:38:25 +03:00
#include <spawn.h>
#include <stdarg.h>
2021-03-25 10:03:23 +03:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2021-03-25 12:38:25 +03:00
#include <unistd.h>
2021-03-25 10:03:23 +03:00
extern char **environ;
static char *get_mold_path() {
2021-03-26 16:12:07 +03:00
char *path = getenv("MOLD_REAL_PATH");
2021-03-26 13:47:02 +03:00
if (path)
return path;
2021-03-26 16:12:07 +03:00
fprintf(stderr, "MOLD_REAL_PATH is not set\n");
2021-03-26 13:47:02 +03:00
exit(1);
}
static void debug_print(char *fmt, ...) {
if (!getenv("MOLD_WRAPPER_DEBUG"))
return;
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "mold-wrapper.so: ");
vfprintf(stderr, fmt, ap);
fflush(stderr);
va_end(ap);
2021-03-25 10:03:23 +03:00
}
2021-03-25 12:38:25 +03:00
static void get_args(va_list ap, int argc, char **argv) {
for (int i = 1; i < argc - 1; i++) {
char *arg = va_arg(ap, char *);
if (!arg)
break;
argv[i] = arg;
}
}
int execve(const char *path, char *const *argv, char *const *envp) {
2021-03-26 13:47:02 +03:00
debug_print("execve %s\n", path);
2021-03-25 10:03:23 +03:00
2021-03-25 12:38:25 +03:00
if (!strcmp(path, "/usr/bin/ld")) {
2021-03-25 10:03:23 +03:00
path = get_mold_path();
2021-03-25 12:38:25 +03:00
((const char **)argv)[0] = path;
}
2021-03-25 10:03:23 +03:00
2021-03-26 13:47:02 +03:00
typeof(execve) *real = dlsym(RTLD_NEXT, "execve");
2021-03-25 10:03:23 +03:00
return real(path, argv, envp);
}
2021-03-25 12:38:25 +03:00
int execl(const char *path, const char *arg0, ...) {
va_list ap;
va_start(ap, arg0);
char *argv[4096] = {(char *)arg0};
get_args(ap, 4096, argv);
return execve(path, argv, environ);
2021-03-25 10:03:23 +03:00
}
2021-03-25 12:38:25 +03:00
int execlp(const char *file, const char *arg0, ...) {
va_list ap;
va_start(ap, arg0);
char *argv[4096] = {(char *)arg0};
get_args(ap, 4096, argv);
return execvpe(file, argv, environ);
2021-03-25 10:03:23 +03:00
}
2021-03-25 12:38:25 +03:00
int execle(const char *path, const char *arg0, ...) {
va_list ap;
va_start(ap, arg0);
char *argv[4096] = {(char *)arg0};
get_args(ap, 4096, argv);
char **env = va_arg(ap, char **);
execve(path, argv, env);
2021-03-25 10:03:23 +03:00
}
int execv(const char *path, char *const *argv) {
return execve(path, argv, environ);
}
int execvp(const char *file, char *const *argv) {
2021-03-25 12:38:25 +03:00
return execvpe(file, argv, environ);
2021-03-25 10:03:23 +03:00
}
int execvpe(const char *file, char *const *argv, char *const *envp) {
2021-03-26 13:47:02 +03:00
debug_print("execvpe %s\n", file);
2021-03-25 10:03:23 +03:00
2021-03-25 12:38:25 +03:00
if (!strcmp(file, "ld") || !strcmp(file, "/usr/bin/ld")) {
2021-03-25 10:03:23 +03:00
file = get_mold_path();
2021-03-25 12:38:25 +03:00
((const char **)argv)[0] = file;
}
2021-03-25 10:03:23 +03:00
2021-03-26 13:47:02 +03:00
typeof(execvpe) *real = dlsym(RTLD_NEXT, "execvpe");
2021-03-25 10:03:23 +03:00
return real(file, argv, environ);
}
2021-03-25 12:38:25 +03:00
int posix_spawn(pid_t *pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const *argv, char *const *envp) {
2021-03-26 13:47:02 +03:00
debug_print("posix_spawn %s\n", path);
2021-03-25 12:38:25 +03:00
if (!strcmp(path, "/usr/bin/ld")) {
path = get_mold_path();
((const char **)argv)[0] = path;
}
2021-03-26 13:47:02 +03:00
typeof(posix_spawn) *real = dlsym(RTLD_NEXT, "posix_spawn");
2021-03-25 12:38:25 +03:00
return real(pid, path, file_actions, attrp, argv, envp);
}