Skip to content

Commit b40703e

Browse files
aykevldeadprogram
authored andcommitted
wasm: override dlmalloc heap implementation from wasi-libc
These two heaps conflict with each other, so that if any function uses the dlmalloc heap implementation it will eventually result in memory corruption. This commit fixes this by implementing all heap-related functions. This overrides the functions that are implemented in wasi-libc. That's why all of them are implemented (even if they just panic): to make sure no program accidentally uses the wrong one.
1 parent 00ea0b1 commit b40703e

File tree

2 files changed

+62
-15
lines changed

2 files changed

+62
-15
lines changed

main_test.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func TestCompiler(t *testing.T) {
125125
// Test with few optimizations enabled (no inlining, etc).
126126
t.Run("opt=1", func(t *testing.T) {
127127
t.Parallel()
128-
runTestWithConfig("stdlib.go", "", t, &compileopts.Options{
128+
runTestWithConfig("stdlib.go", "", t, compileopts.Options{
129129
Opt: "1",
130130
}, nil, nil)
131131
})
@@ -134,15 +134,14 @@ func TestCompiler(t *testing.T) {
134134
// TODO: fix this for stdlib.go, which currently fails.
135135
t.Run("opt=0", func(t *testing.T) {
136136
t.Parallel()
137-
runTestWithConfig("print.go", "", t, &compileopts.Options{
137+
runTestWithConfig("print.go", "", t, compileopts.Options{
138138
Opt: "0",
139139
}, nil, nil)
140140
})
141141

142142
t.Run("ldflags", func(t *testing.T) {
143143
t.Parallel()
144-
runTestWithConfig("ldflags.go", "", t, &compileopts.Options{
145-
Opt: "z",
144+
runTestWithConfig("ldflags.go", "", t, compileopts.Options{
146145
GlobalValues: map[string]map[string]string{
147146
"main": {
148147
"someGlobal": "foobar",
@@ -188,20 +187,20 @@ func runBuild(src, out string, opts *compileopts.Options) error {
188187
}
189188

190189
func runTest(name, target string, t *testing.T, cmdArgs, environmentVars []string) {
191-
options := &compileopts.Options{
192-
Target: target,
193-
Opt: "z",
194-
PrintIR: false,
195-
DumpSSA: false,
196-
VerifyIR: true,
197-
Debug: true,
198-
PrintSizes: "",
199-
WasmAbi: "",
190+
options := compileopts.Options{
191+
Target: target,
200192
}
201193
runTestWithConfig(name, target, t, options, cmdArgs, environmentVars)
202194
}
203195

204-
func runTestWithConfig(name, target string, t *testing.T, options *compileopts.Options, cmdArgs, environmentVars []string) {
196+
func runTestWithConfig(name, target string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
197+
// Set default config.
198+
options.Debug = true
199+
options.VerifyIR = true
200+
if options.Opt == "" {
201+
options.Opt = "z"
202+
}
203+
205204
// Get the expected output for this test.
206205
// Note: not using filepath.Join as it strips the path separator at the end
207206
// of the path.
@@ -230,7 +229,7 @@ func runTestWithConfig(name, target string, t *testing.T, options *compileopts.O
230229

231230
// Build the test binary.
232231
binary := filepath.Join(tmpdir, "test")
233-
err = runBuild("./"+path, binary, options)
232+
err = runBuild("./"+path, binary, &options)
234233
if err != nil {
235234
printCompilerError(t.Log, err)
236235
t.Fail()

src/runtime/arch_tinygowasm.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,51 @@ func growHeap() bool {
5555
// Heap has grown successfully.
5656
return true
5757
}
58+
59+
// The below functions override the default allocator of wasi-libc.
60+
// Most functions are defined but unimplemented to make sure that if there is
61+
// any code using them, they will get an error instead of (incorrectly) using
62+
// the wasi-libc dlmalloc heap implementation instead. If they are needed by any
63+
// program, they can certainly be implemented.
64+
65+
//export malloc
66+
func libc_malloc(size uintptr) unsafe.Pointer {
67+
return alloc(size)
68+
}
69+
70+
//export free
71+
func libc_free(ptr unsafe.Pointer) {
72+
free(ptr)
73+
}
74+
75+
//export calloc
76+
func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
77+
// Note: we could be even more correct here and check that nmemb * size
78+
// doesn't overflow. However the current implementation should normally work
79+
// fine.
80+
return alloc(nmemb * size)
81+
}
82+
83+
//export realloc
84+
func libc_realloc(ptr unsafe.Pointer, size uintptr) unsafe.Pointer {
85+
runtimePanic("unimplemented: realloc")
86+
return nil
87+
}
88+
89+
//export posix_memalign
90+
func libc_posix_memalign(memptr *unsafe.Pointer, alignment, size uintptr) int {
91+
runtimePanic("unimplemented: posix_memalign")
92+
return 0
93+
}
94+
95+
//export aligned_alloc
96+
func libc_aligned_alloc(alignment, bytes uintptr) unsafe.Pointer {
97+
runtimePanic("unimplemented: aligned_alloc")
98+
return nil
99+
}
100+
101+
//export malloc_usable_size
102+
func libc_malloc_usable_size(ptr unsafe.Pointer) uintptr {
103+
runtimePanic("unimplemented: malloc_usable_size")
104+
return 0
105+
}

0 commit comments

Comments
 (0)