summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backtrace.c44
-rw-r--r--dlmopen.c15
-rw-r--r--gnulib.c8
-rw-r--r--pthread.c31
-rw-r--r--setjmp.c7
5 files changed, 105 insertions, 0 deletions
diff --git a/backtrace.c b/backtrace.c
new file mode 100644
index 0000000..2ceb334
--- /dev/null
+++ b/backtrace.c
@@ -0,0 +1,44 @@
+#include <dlfcn.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#define _frame_level(addr_buf, curr, frame, size) \
+ if(__builtin_frame_address(frame) != NULL && (curr = __builtin_return_address(frame)) > 0x1000 && frame <= size) addr_buf[frame] = curr; \
+ else return size;
+
+int backtrace(void **addr_buf, int size)
+{
+ void *curr;
+ _frame_level(addr_buf, curr, 0, size)
+ _frame_level(addr_buf, curr, 1, size)
+ _frame_level(addr_buf, curr, 2, size)
+ _frame_level(addr_buf, curr, 3, size)
+ _frame_level(addr_buf, curr, 4, size)
+ _frame_level(addr_buf, curr, 5, size)
+ _frame_level(addr_buf, curr, 6, size)
+ _frame_level(addr_buf, curr, 7, size)
+ _frame_level(addr_buf, curr, 8, size)
+ _frame_level(addr_buf, curr, 9, size)
+ return 9;
+}
+
+char **backtrace_symbols(void * const *addr_buf, int size)
+{
+ char **result = calloc(sizeof(char *), size);
+ if(result == NULL) return result;
+
+ for(int next = 0; next < size; next++)
+ {
+ Dl_info info;
+ int err = dladdr(addr_buf[next], &info);
+
+ if(err != 0)
+ {
+ result[next] = "??:0";
+ } else {
+ result[next] = info.dli_sname;
+ }
+ }
+
+ return result;
+}
diff --git a/dlmopen.c b/dlmopen.c
new file mode 100644
index 0000000..fecb29c
--- /dev/null
+++ b/dlmopen.c
@@ -0,0 +1,15 @@
+#include <dlfcn.h> // dlopen
+#include <stdio.h> // fprintf
+#include <stdlib.h> // getenv
+
+void *dlmopen(long lmid, const char *pathname, int mode)
+{
+ if(getenv("GLIBC_FAKE_DEBUG"))
+ {
+ fprintf(stderr, "library %s was requested to load in %ld namespace",
+ pathname, lmid);
+ }
+
+ return dlopen(pathname, mode);
+}
+
diff --git a/gnulib.c b/gnulib.c
new file mode 100644
index 0000000..08544fc
--- /dev/null
+++ b/gnulib.c
@@ -0,0 +1,8 @@
+#include <assert.h>
+#include <sys/select.h>
+
+unsigned long __fdelt_chk(unsigned long size)
+{
+ assert(size < FD_SETSIZE);
+ return size / (sizeof(unsigned long)<<3);
+}
diff --git a/pthread.c b/pthread.c
new file mode 100644
index 0000000..b4ea054
--- /dev/null
+++ b/pthread.c
@@ -0,0 +1,31 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* "Now we are all sons of bitches." */
+int pthread_setname_np(pthread_t thread, const char *name)
+{
+ char path[PATH_MAX];
+ int fd;
+ /* Cthulhu have mercy */
+ pid_t *my_pid = (pid_t *)((void *)thread + (sizeof(uintptr_t) * 7));
+ size_t len = strlen(name);
+
+ if(len > 15)
+ {
+ return -ERANGE;
+ }
+
+ snprintf(path, PATH_MAX, "/proc/self/tid/%u/name", *my_pid);
+ fd = open(path, O_RDWR);
+ write(fd, name, len + 1);
+ close(fd);
+
+ return 0;
+}
diff --git a/setjmp.c b/setjmp.c
new file mode 100644
index 0000000..306868f
--- /dev/null
+++ b/setjmp.c
@@ -0,0 +1,7 @@
+#include <assert.h>
+#include <setjmp.h>
+
+void __longjmp_chk(jmp_buf env, int val)
+{
+ longjmp(env, val);
+}