summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Pitcock <nenolod@dereferenced.org>2017-06-14 13:27:48 -0500
committerWilliam Pitcock <nenolod@dereferenced.org>2017-06-14 13:27:48 -0500
commit0b17ab1b84e43d1349334d34f6587539e2b10981 (patch)
tree077e4cddad01ffa03240096ac3abb8203a8fe58b
parentf67416822a54109bd9cfa0fd210d7d8f53412ced (diff)
downloadgcompat-0b17ab1b84e43d1349334d34f6587539e2b10981.tar.gz
gcompat-0b17ab1b84e43d1349334d34f6587539e2b10981.tar.bz2
gcompat-0b17ab1b84e43d1349334d34f6587539e2b10981.tar.xz
gcompat-0b17ab1b84e43d1349334d34f6587539e2b10981.zip
implement program loader
-rw-r--r--loader/loader.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/loader/loader.c b/loader/loader.c
new file mode 100644
index 0000000..f2942a4
--- /dev/null
+++ b/loader/loader.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 William Pitcock <nenolod@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 16384
+#endif
+
+#ifndef LINKER
+#error LINKER must be defined
+#endif
+
+#ifndef LIBGCOMPAT
+#error LIBGCOMPAT must be defined
+#endif
+
+int main(int argc, char *argv[], char *envp[]) {
+ size_t i = 0;
+ char target[PATH_MAX];
+ char **new_argv = calloc(sizeof(char *), argc + 5);
+
+ memset(target, 0, sizeof(target));
+ if (readlink("/proc/self/exe", target, sizeof(target)) < 0) {
+ perror("readlink");
+ return EXIT_FAILURE;
+ }
+
+ new_argv[0] = argv[0];
+ new_argv[1] = "--preload";
+ new_argv[2] = LIBGCOMPAT;
+ new_argv[3] = target;
+
+ for (i = 1; i < argc; i++) {
+ new_argv[3 + i] = argv[i];
+ }
+
+ execve(LINKER, new_argv, envp);
+
+ /* execve only returns if there is an error. */
+ perror("execve");
+ return EXIT_FAILURE;
+}