Skip to content

Commit

Permalink
Replace GC implementation with bdwgc (envoyproxy#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
anuraaga authored Nov 9, 2022
1 parent bd06f5b commit 636eee4
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 563 deletions.
22 changes: 22 additions & 0 deletions buildtools/bdwgc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright The OWASP Coraza contributors
# SPDX-License-Identifier: Apache-2.0

FROM ghcr.io/corazawaf/coraza-proxy-wasm/buildtools-wasi-sdk:main

RUN apt-get install -y autogen autoconf automake libtool patch

RUN mkdir -p /bdwgc && curl -L https://github.com/ivmai/bdwgc/archive/refs/tags/v8.2.2.tar.gz | tar -xz --strip-components 1 -C /bdwgc
WORKDIR /bdwgc
ADD bdwgc.patch bdwgc.patch
RUN patch -p1 < bdwgc.patch
RUN ./autogen.sh

# -D_WASI_EMULATED_MMAN allows wasi-libc's mmap header files to be included. We do not actually use
# the library itself, instead reimplementing in mmap.go
ENV CFLAGS ${CFLAGS} -D_WASI_EMULATED_MMAN

# host is required by configure but not used so set it arbitrarily
RUN ./configure --disable-threads --enable-mmap --disable-shared --disable-gcj-support --disable-java-finalization --disable-atomic-uncollectible --host=i686-pc-linux-gnu
RUN make

CMD ["cp", "/bdwgc/.libs/libgc.a", "/out/"]
109 changes: 109 additions & 0 deletions buildtools/bdwgc/bdwgc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
diff --git a/alloc.c b/alloc.c
index a53e12c0..6e7be764 100644
--- a/alloc.c
+++ b/alloc.c
@@ -19,7 +19,7 @@
#include "private/gc_priv.h"

#include <stdio.h>
-#if !defined(MACOS) && !defined(MSWINCE)
+#if !defined(MACOS) && !defined(MSWINCE) && !defined(WASI)
# include <signal.h>
# if !defined(GC_NO_TYPES) && !defined(SN_TARGET_PSP2) \
&& !defined(__CC_ARM)
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 2ffd4dd0..28ed5100 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -838,7 +838,9 @@ EXTERN_C_END
# endif
#endif /* DARWIN */

-#include <setjmp.h>
+#if !defined(GC_NO_SIGSETJMP)
+# include <setjmp.h>
+#endif

#if __STDC_VERSION__ >= 201112L
# include <assert.h> /* for static_assert */
diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h
index 2de01afe..cf25e78c 100644
--- a/include/private/gcconfig.h
+++ b/include/private/gcconfig.h
@@ -703,6 +703,11 @@ EXTERN_C_BEGIN
# define I386
# define mach_type_known
# endif
+# if defined(__wasi__)
+# define WASI
+# define I386
+# define mach_type_known
+#endif

/* Feel free to add more clauses here */

@@ -1425,6 +1430,21 @@ EXTERN_C_BEGIN
# define USE_MMAP_ANON /* avoid /dev/zero, not supported */
# define STACK_GROWS_DOWN
# endif
+# ifdef WASI
+ extern unsigned char __global_base;
+ extern unsigned char __heap_base;
+# define OS_TYPE "WASI"
+# define DATASTART ((ptr_t)&__global_base)
+# define DATAEND ((ptr_t)&__heap_base)
+# define STACKBOTTOM ((ptr_t)&__global_base)
+# define GETPAGESIZE() 65536
+# define USE_MMAP_ANON /* avoid /dev/zero, not supported */
+# define GC_NO_SIGSETJMP 1
+# define NO_CLOCK 1
+# ifndef HBLKSIZE
+# define HBLKSIZE 4096
+# endif
+# endif
# if defined(__QNX__)
# define OS_TYPE "QNX"
# define SA_RESTART 0
diff --git a/misc.c b/misc.c
index 64eeb7e4..273a1fa7 100644
--- a/misc.c
+++ b/misc.c
@@ -20,7 +20,7 @@
#include <limits.h>
#include <stdarg.h>

-#ifndef MSWINCE
+#if !defined(MSWINCE) && !defined(WASI)
# include <signal.h>
#endif

diff --git a/os_dep.c b/os_dep.c
index e116ad02..4bd9031c 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -27,14 +27,14 @@
#endif

#include <stdio.h>
-#if defined(MSWINCE) || defined(SN_TARGET_PS3)
+#if defined(MSWINCE) || defined(SN_TARGET_PS3) || defined(WASI)
# define SIGSEGV 0 /* value is irrelevant */
#else
# include <signal.h>
#endif

#if defined(UNIX_LIKE) || defined(CYGWIN32) || defined(NACL) \
- || defined(SYMBIAN)
+ || defined(SYMBIAN) || defined(WASI)
# include <fcntl.h>
#endif

@@ -2668,7 +2668,7 @@ static void block_unmap_inner(ptr_t start_addr, size_t len)
if (madvise(start_addr, len, MADV_DONTNEED) == -1)
ABORT_ON_REMAP_FAIL("unmap: madvise", start_addr, len);
# endif
-# elif defined(EMSCRIPTEN)
+# elif defined(EMSCRIPTEN) || defined(WASI)
/* Nothing to do, mmap(PROT_NONE) is not supported and */
/* mprotect() is just a no-op. */
# else
1 change: 1 addition & 0 deletions buildtools/tinygo/wasi-libc.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ FROM ghcr.io/corazawaf/coraza-proxy-wasm/buildtools-wasi-sdk:main

RUN apt-get install -y git

# https://github.com/tinygo-org/tinygo/pull/3280
RUN git clone https://github.com/anuraaga/tinygo --branch wasm-stacks-nogc
WORKDIR /tinygo
RUN git fetch origin wasm-stacks-nogc && git reset --hard e2da8f6f0f5cf5a75a384bbddae80c1b8a84eca7
Expand Down
2 changes: 1 addition & 1 deletion init_tinygo.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ package main

import _ "github.com/corazawaf/coraza-proxy-wasm/internal/agc"

// #cgo LDFLAGS: lib/libinjection.a lib/libre2.a lib/libcre2.a lib/libc++.a lib/libc++abi.a lib/libclang_rt.builtins-wasm32.a lib/libaho_corasick.a lib/libmimalloc.a
// #cgo LDFLAGS: lib/libinjection.a lib/libre2.a lib/libcre2.a lib/libc++.a lib/libc++abi.a lib/libclang_rt.builtins-wasm32.a lib/libaho_corasick.a lib/libmimalloc.a lib/libgc.a
import "C"
7 changes: 2 additions & 5 deletions internal/agc/doc.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
// Copyright The OWASP Coraza contributors
// SPDX-License-Identifier: Apache-2.0

// Package agc is a custom gargabe gollector for TinyGo. The main difference is instead of taking
// ownership of the entire process heap, it uses malloc to allocate blocks for the GC to then
// assign to allocated objects.
// Package agc is a custom garbage collector for TinyGo. It delegates to bdwgc for actual
// allocation and collection.
//
// Unfortunately, we must rely on a package init() method for initializing the heap because we
// cannot override TinyGo's initHeap function that normally does it. This means initialization
// order matters, this package should be the first package to be initialized - any packages
// initialized before cannot allocate memory. For that reason, we have named this agc instead
// of gc.
//
// Currently, only one block can be allocated meaning this has a fixed-size heap.
package agc
Loading

0 comments on commit 636eee4

Please sign in to comment.