diff options
-rw-r--r-- | backtrace.c | 44 | ||||
-rw-r--r-- | dlmopen.c | 15 | ||||
-rw-r--r-- | gnulib.c | 8 | ||||
-rw-r--r-- | pthread.c | 31 | ||||
-rw-r--r-- | setjmp.c | 7 |
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); +} |