summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mk/__jkmalloc.d1
-rw-r--r--mk/__segv.d11
-rw-r--r--mk/all.mk1
-rw-r--r--mk/deps.mk4
-rw-r--r--src/__main.c3
-rw-r--r--src/signal/__segv.c147
-rw-r--r--src/signal/_signal.h1
-rw-r--r--src/stdlib/__jkmalloc.c131
-rw-r--r--src/stdlib/_jkmalloc.h37
9 files changed, 207 insertions, 129 deletions
diff --git a/mk/__jkmalloc.d b/mk/__jkmalloc.d
index 6436cbcf..5d4a1e77 100644
--- a/mk/__jkmalloc.d
+++ b/mk/__jkmalloc.d
@@ -4,7 +4,6 @@ libc.a(__jkmalloc.o): $(OBJDIR)/__jkmalloc.o
$(OBJDIR)/__jkmalloc.o: src/stdlib/__jkmalloc.c
$(OBJDIR)/__jkmalloc.o: src/_safety.h
-$(OBJDIR)/__jkmalloc.o: src/_forced/sigaction.h
$(OBJDIR)/__jkmalloc.o: src/_forced/mmap.h
$(OBJDIR)/__jkmalloc.o: src/_forced/munmap.h
$(OBJDIR)/__jkmalloc.o: src/_forced/mprotect.h
diff --git a/mk/__segv.d b/mk/__segv.d
new file mode 100644
index 00000000..ac2464a9
--- /dev/null
+++ b/mk/__segv.d
@@ -0,0 +1,11 @@
+libc_C.0: libc.a(__segv.o)
+libc.a(__segv.o): $(OBJDIR)/__segv.o
+ @$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
+
+$(OBJDIR)/__segv.o: src/signal/__segv.c
+$(OBJDIR)/__segv.o: src/_safety.h
+$(OBJDIR)/__segv.o: src/_forced/sigaction.h
+$(OBJDIR)/__segv.o: src/stdlib/_jkmalloc.h
+$(OBJDIR)/__segv.o:
+ @mkdir -p $(@D)
+ $(CC) -c -o $@ $(CFLAGS) src/signal/__segv.c
diff --git a/mk/all.mk b/mk/all.mk
index 66e9e1e0..dcca93a1 100644
--- a/mk/all.mk
+++ b/mk/all.mk
@@ -372,6 +372,7 @@ include mk/raise.d
include mk/__signal_handler.d
include mk/__sigsegv.d
include mk/__signal_h.d
+include mk/__segv.d
include mk/frexp.d
include mk/erfc.d
include mk/rint.d
diff --git a/mk/deps.mk b/mk/deps.mk
index b32ecabd..a3963021 100644
--- a/mk/deps.mk
+++ b/mk/deps.mk
@@ -1498,6 +1498,10 @@ all: mk/__signal_h.d
mk/__signal_h.d: src/signal/__signal_h.c
sh mk/deps.sh src/signal/__signal_h.c
+all: mk/__segv.d
+mk/__segv.d: src/signal/__segv.c
+ sh mk/deps.sh src/signal/__segv.c
+
all: mk/frexp.d
mk/frexp.d: src/math/frexp.c
sh mk/deps.sh src/math/frexp.c
diff --git a/src/__main.c b/src/__main.c
index a24c24ef..510def1e 100644
--- a/src/__main.c
+++ b/src/__main.c
@@ -3,6 +3,7 @@
#include <locale.h>
#include "stdio/_stdio.h"
#include "stdlib/_stdlib.h"
+#include "signal/_signal.h"
#undef stdin
#undef stdout
@@ -39,6 +40,8 @@ void __init_libc(void)
extern char **environ;
__stdlib_h.environ = environ;
#endif
+
+ __segv();
}
void __main(int (*main)(int, char*[]), int argc, char **argv)
diff --git a/src/signal/__segv.c b/src/signal/__segv.c
new file mode 100644
index 00000000..7a4a2656
--- /dev/null
+++ b/src/signal/__segv.c
@@ -0,0 +1,147 @@
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "_safety.h"
+
+#ifdef _XOPEN_SOURCE
+#else
+#include "_forced/sigaction.h"
+#include "_forced/mprotect.h"
+
+#define sysconf(__n) 4096
+#define psiginfo(x, y) fprintf(stderr, "%s (%p)\n", (char*)(y), (void*)(x))
+#define sigemptyset(x) memset(x, 0, sizeof(*x))
+#endif
+
+#include "stdlib/_jkmalloc.h"
+
+static void __jk_undef(void)
+{
+ static int printed = 0;
+ if (printed == 0) {
+ printed = 1;
+ fprintf(stderr, "Undefined Behavior: ");
+ }
+}
+
+static void __jk_error(const char *s, void *addr, struct jk_source *src)
+{
+ __jk_undef();
+
+ if (s && *s) {
+ fputs(s, stderr);
+ if (addr != NULL) {
+ fprintf(stderr, " %p", addr);
+ }
+ fputs("\n", stderr);
+ }
+
+ if (src && src->bucket && src->bucket->trace[0] != '\0') {
+ fwrite(src->bucket->trace, src->bucket->tlen, 1, stderr);
+ fputs("\n", stderr);
+ }
+
+ if (src && src->file) {
+ fprintf(stderr, "!!! %s() (%s:%ju)\n", src->func, src->file, src->line);
+ }
+
+ _Exit(JKMALLOC_EXIT_VALUE);
+}
+
+static void __jk_sigaction(int sig, siginfo_t *si, void *addr)
+{
+ __signal_h.current = 0;
+
+ (void)sig; (void)addr;
+
+ __jk_undef();
+
+ if (__dangerous[0].func) {
+ fprintf(stderr, "In call to %s, attempting to read parameter %s (%p)\n", __dangerous[0].func, __dangerous[0].param, __dangerous[0].addr);
+ }
+
+ if (__dangerous[1].func) {
+ fprintf(stderr, "In call to %s, attempting to write parameter %s (%p)\n", __dangerous[1].func, __dangerous[1].param, __dangerous[1].addr);
+ }
+
+ if (!si) {
+ __jk_error("No signal information provided", NULL, NULL);
+ }
+
+ if (si->si_addr == NULL) {
+ psiginfo(si, "NULL pointer dereference");
+ __jk_error(NULL, NULL, NULL);
+ }
+
+ struct jk_bucket *bucket = jk_pageof(si->si_addr);
+ if (mprotect(bucket, __jk_pagesize, PROT_READ) != 0) {
+ psiginfo(si, NULL);
+ __jk_error(NULL, NULL, NULL);
+ }
+
+ MAGIC_CHECK:
+ switch (bucket->magic) {
+ case JK_UNDER_MAGIC:
+ if (bucket->size == 0) {
+ psiginfo(si, "Attempt to use 0-byte allocation");
+ } else {
+ psiginfo(si, "Heap underflow detected");
+ }
+ break;
+
+ case JK_OVER_MAGIC:
+ if (bucket->size == 0) {
+ psiginfo(si, "Attempt to use 0-byte allocation");
+ } else {
+ psiginfo(si, "Heap overflow detected");
+ fprintf(stderr, "Allocation of size %zu at %p, overflow at %p (offset %zu)\n", bucket->size, (void*)bucket->start, si->si_addr, (size_t)((char*)si->si_addr - (char*)bucket->start));
+ fprintf(stderr, "Buffer begins with %4s\n", (char*)bucket->start);
+ }
+ break;
+
+ case JK_FREE_MAGIC:
+ psiginfo(si, "Use after free() detected");
+ break;
+
+ case JK_RONLY_MAGIC:
+ psiginfo(si, "Attempt to modify read-only memory detected");
+ break;
+
+ default:
+ /* try to find the actual error */
+ bucket = (void*)((char*)bucket - __jk_pagesize);
+ if (mprotect(bucket, __jk_pagesize, PROT_READ) != 0) {
+ psiginfo(si, NULL);
+ __jk_error(NULL, NULL, NULL);
+ }
+ goto MAGIC_CHECK;
+ }
+
+ struct jk_source src = { .bucket = bucket };
+ __jk_error(NULL, NULL, &src);
+}
+
+GCC_SSE_HACK
+void __segv(void)
+{
+ static int sa_set = 0;
+ if (!sa_set) {
+ struct sigaction sa = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = __jk_sigaction,
+ };
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
+ sa_set = 1;
+ }
+}
+
+/*
+SIGNAL_SAFE(0)
+STDC(0)
+*/
diff --git a/src/signal/_signal.h b/src/signal/_signal.h
index 1e484f83..f0d038f5 100644
--- a/src/signal/_signal.h
+++ b/src/signal/_signal.h
@@ -13,6 +13,7 @@ extern struct __signal_h {
} __signal_h;
void __signal_handler(int);
+void __segv(void);
/*
STDC(-1)
diff --git a/src/stdlib/__jkmalloc.c b/src/stdlib/__jkmalloc.c
index 34b34fbc..2f9bc3a3 100644
--- a/src/stdlib/__jkmalloc.c
+++ b/src/stdlib/__jkmalloc.c
@@ -1,7 +1,6 @@
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
-#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -13,66 +12,22 @@
#include <sys/mman.h>
#include <unistd.h>
#else
-#include "_forced/sigaction.h"
#include "_forced/mmap.h"
#include "_forced/munmap.h"
#include "_forced/mprotect.h"
#define sysconf(__n) 4096
-#define psiginfo(x, y) fprintf(stderr, "%s (%p)\n", (char*)(y), (void*)(x))
-#define sigemptyset(x) memset(x, 0, sizeof(*x))
#endif
#include "_jkmalloc.h"
-#define PTR_BITS (CHAR_BIT * sizeof(uintptr_t))
-
-#define JKMALLOC_EXIT_VALUE (127 + SIGSEGV)
-#define JK_FREE_LIST_SIZE (8)
-
-/* magic numbers derived from CRC-32 of jk_foo_block */
-#define JK_FREE_MAGIC (0x551a51dc)
-#define JK_UNDER_MAGIC (0xcb2873ac)
-#define JK_OVER_MAGIC (0x18a12c17)
-#define JK_RONLY_MAGIC (0x902faf31)
-
-#define jk_pages(bytes) (((bytes + __jk_pagesize - 1) / __jk_pagesize) + 2)
-#define jk_pageof(addr) ((void*)((uintptr_t)addr - ((uintptr_t)addr % __jk_pagesize)))
-#define jk_bucketof(addr) ((void*)((uintptr_t)jk_pageof(addr) - __jk_pagesize))
-
-struct jk_bucket {
- uint32_t magic;
- uintptr_t start;
- size_t size;
- size_t align;
- size_t pages;
- size_t tlen;
- char trace[];
-};
-
-struct jk_source {
- const char *file;
- const char *func;
- uintmax_t line;
- struct jk_bucket *bucket;
-};
-
static struct jk_bucket *__jk_free_list[JK_FREE_LIST_SIZE];
static size_t __jk_free_buckets = 0;
-static size_t __jk_pagesize = 0;
-
-static void __jk_undef(void)
-{
- static int printed = 0;
- if (printed == 0) {
- printed = 1;
- fprintf(stderr, "Undefined Behavior: ");
- }
-}
+//static size_t __jk_pagesize = 0;
static void __jk_error(const char *s, void *addr, struct jk_source *src)
{
- __jk_undef();
+ fprintf(stderr, "Undefined Behavior: ");
if (s && *s) {
fputs(s, stderr);
@@ -117,91 +72,11 @@ static void *__jk_page_alloc(size_t npages)
return pages;
}
-static void __jk_sigaction(int sig, siginfo_t *si, void *addr)
-{
- __signal_h.current = 0;
-
- (void)sig; (void)addr;
-
- __jk_undef();
-
- if (__dangerous.func) {
- fprintf(stderr, "In call to %s, accessing parameter %s (%p)\n", __dangerous.func, __dangerous.param, __dangerous.addr);
- }
-
- if (!si) {
- __jk_error("No signal information provided", NULL, NULL);
- }
-
- if (si->si_addr == NULL) {
- psiginfo(si, "NULL pointer dereference");
- __jk_error(NULL, NULL, NULL);
- }
-
- struct jk_bucket *bucket = jk_pageof(si->si_addr);
- if (mprotect(bucket, __jk_pagesize, PROT_READ) != 0) {
- psiginfo(si, NULL);
- __jk_error(NULL, NULL, NULL);
- }
-
- MAGIC_CHECK:
- switch (bucket->magic) {
- case JK_UNDER_MAGIC:
- if (bucket->size == 0) {
- psiginfo(si, "Attempt to use 0-byte allocation");
- } else {
- psiginfo(si, "Heap underflow detected");
- }
- break;
-
- case JK_OVER_MAGIC:
- if (bucket->size == 0) {
- psiginfo(si, "Attempt to use 0-byte allocation");
- } else {
- psiginfo(si, "Heap overflow detected");
- fprintf(stderr, "Allocation of size %zu at %p, overflow at %p (offset %zu)\n", bucket->size, (void*)bucket->start, si->si_addr, (size_t)((char*)si->si_addr - (char*)bucket->start));
- fprintf(stderr, "Buffer begins with %4s\n", (char*)bucket->start);
- }
- break;
-
- case JK_FREE_MAGIC:
- psiginfo(si, "Use after free() detected");
- break;
-
- case JK_RONLY_MAGIC:
- psiginfo(si, "Attempt to modify read-only memory detected");
- break;
-
- default:
- /* try to find the actual error */
- bucket = (void*)((char*)bucket - __jk_pagesize);
- if (mprotect(bucket, __jk_pagesize, PROT_READ) != 0) {
- psiginfo(si, NULL);
- __jk_error(NULL, NULL, NULL);
- }
- goto MAGIC_CHECK;
- }
-
- struct jk_source src = { .bucket = bucket };
- __jk_error(NULL, NULL, &src);
-}
-
GCC_SSE_HACK
void* __jkmalloc(void *ptr, size_t alignment, size_t size1, size_t size2, const char *user)
{
- static int sa_set = 0;
- if (!sa_set) {
- struct sigaction sa = {
- .sa_flags = SA_SIGINFO,
- .sa_sigaction = __jk_sigaction,
- };
- sigemptyset(&sa.sa_mask);
- sigaction(SIGSEGV, &sa, NULL);
- sa_set = 1;
- }
-
if (__jk_pagesize == 0) {
- __jk_pagesize = sysconf(_SC_PAGESIZE);
+ //__jk_pagesize = sysconf(_SC_PAGESIZE);
}
struct jk_source src = {
diff --git a/src/stdlib/_jkmalloc.h b/src/stdlib/_jkmalloc.h
index cab5cfcb..107bf904 100644
--- a/src/stdlib/_jkmalloc.h
+++ b/src/stdlib/_jkmalloc.h
@@ -3,6 +3,43 @@
#include <inttypes.h>
+#define PTR_BITS (CHAR_BIT * sizeof(uintptr_t))
+
+#define JKMALLOC_EXIT_VALUE (127 + SIGSEGV)
+#define JK_FREE_LIST_SIZE (8)
+
+#define __jk_pagesize (4096)
+
+/* magic numbers derived from CRC-32 of jk_foo_block */
+#define JK_FREE_MAGIC (0x551a51dc)
+#define JK_UNDER_MAGIC (0xcb2873ac)
+#define JK_OVER_MAGIC (0x18a12c17)
+#define JK_RONLY_MAGIC (0x902faf31)
+
+#define jk_pages(bytes) (((bytes + __jk_pagesize - 1) / __jk_pagesize) + 2)
+#define jk_pageof(addr) ((void*)((uintptr_t)addr - ((uintptr_t)addr % __jk_pagesize)))
+#define jk_bucketof(addr) ((void*)((uintptr_t)jk_pageof(addr) - __jk_pagesize))
+
+
+struct jk_bucket {
+ uint32_t magic;
+ uintptr_t start;
+ size_t size;
+ size_t align;
+ size_t pages;
+ size_t tlen;
+ char trace[];
+};
+
+
+struct jk_source {
+ const char *file;
+ const char *func;
+ uintmax_t line;
+ struct jk_bucket *bucket;
+};
+
+
void* __jkmalloc(void *ptr, size_t alignment, size_t size1 , size_t size2, const char *user);
#endif