Skip to content

Commit

Permalink
wasi-libc: compile emmalloc.c without strict aliasing (#16157)
Browse files Browse the repository at this point in the history
emmalloc.c does a fair amount of type punning in order to access
the size of memory regions and traverse them.

Unfortunately, that can lead to unwanted optimizations.

This simple test case currently triggers a memory fault:

int main(void) {
    char * volatile p = malloc(1);
    p = realloc(p, 12);
    p = malloc(1);
    printf("%p\n", p);
}

Work around this by adding "-fno-strict-aliasing" when compiling
that file.
  • Loading branch information
jedisct1 authored Jun 25, 2023
1 parent b111702 commit e7f872c
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions src/wasi_libc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
switch (crt_file) {
.crt1_reactor_o => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, false);
try addCCArgs(comp, arena, &args, .{});
try addLibcBottomHalfIncludes(comp, arena, &args);
return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &.{
.{
Expand All @@ -85,7 +85,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
},
.crt1_command_o => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, false);
try addCCArgs(comp, arena, &args, .{});
try addLibcBottomHalfIncludes(comp, arena, &args);
return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &.{
.{
Expand All @@ -102,7 +102,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
{
// Compile emmalloc.
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true });
for (emmalloc_src_files) |file_path| {
try libc_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
Expand All @@ -116,7 +116,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
{
// Compile libc-bottom-half.
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcBottomHalfIncludes(comp, arena, &args);

for (libc_bottom_half_src_files) |file_path| {
Expand All @@ -132,7 +132,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
{
// Compile libc-top-half.
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcTopHalfIncludes(comp, arena, &args);

for (libc_top_half_src_files) |file_path| {
Expand All @@ -149,7 +149,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
},
.libwasi_emulated_process_clocks_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcBottomHalfIncludes(comp, arena, &args);

var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
Expand All @@ -165,7 +165,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
},
.libwasi_emulated_getpid_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcBottomHalfIncludes(comp, arena, &args);

var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
Expand All @@ -181,7 +181,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
},
.libwasi_emulated_mman_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcBottomHalfIncludes(comp, arena, &args);

var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
Expand All @@ -200,7 +200,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr

{
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });

for (emulated_signal_bottom_half_src_files) |file_path| {
try emu_signal_sources.append(.{
Expand All @@ -214,7 +214,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr

{
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
try addLibcTopHalfIncludes(comp, arena, &args);
try args.append("-D_WASI_EMULATED_SIGNAL");

Expand Down Expand Up @@ -249,17 +249,22 @@ fn sanitize(arena: Allocator, file_path: []const u8) ![]const u8 {
return out_path;
}

const CCOptions = struct {
want_O3: bool = false,
no_strict_aliasing: bool = false,
};

fn addCCArgs(
comp: *Compilation,
arena: Allocator,
args: *std.ArrayList([]const u8),
want_O3: bool,
options: CCOptions,
) error{OutOfMemory}!void {
const target = comp.getTarget();
const arch_name = musl.archNameHeaders(target.cpu.arch);
const os_name = @tagName(target.os.tag);
const triple = try std.fmt.allocPrint(arena, "{s}-{s}-musl", .{ arch_name, os_name });
const o_arg = if (want_O3) "-O3" else "-Os";
const o_arg = if (options.want_O3) "-O3" else "-Os";

try args.appendSlice(&[_][]const u8{
"-std=gnu17",
Expand All @@ -280,6 +285,10 @@ fn addCCArgs(

"-DBULK_MEMORY_THRESHOLD=32",
});

if (options.no_strict_aliasing) {
try args.appendSlice(&[_][]const u8{"-fno-strict-aliasing"});
}
}

fn addLibcBottomHalfIncludes(
Expand Down

0 comments on commit e7f872c

Please sign in to comment.