From 6a3c46ee385cbeef4a6df5933a9248d5bc51c51b Mon Sep 17 00:00:00 2001 From: Will Cohen Date: Sat, 25 Nov 2023 09:12:25 -0500 Subject: [PATCH 1/3] emscripten: add willcohen to maintainers --- pkgs/development/compilers/emscripten/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/compilers/emscripten/default.nix b/pkgs/development/compilers/emscripten/default.nix index 39c7d58aac850..01fa675205935 100644 --- a/pkgs/development/compilers/emscripten/default.nix +++ b/pkgs/development/compilers/emscripten/default.nix @@ -131,7 +131,7 @@ stdenv.mkDerivation rec { homepage = "https://github.com/emscripten-core/emscripten"; description = "An LLVM-to-JavaScript Compiler"; platforms = platforms.all; - maintainers = with maintainers; [ qknight matthewbauer raitobezarius ]; + maintainers = with maintainers; [ qknight matthewbauer raitobezarius willcohen ]; license = licenses.ncsa; }; } From a4daad0caa880988d181f9af214699fd4f2f3dad Mon Sep 17 00:00:00 2001 From: Will Cohen Date: Mon, 11 Dec 2023 11:10:22 -0500 Subject: [PATCH 2/3] llvmPackages_17.lld: backport table-base patch Starting with emscripten-3.1.46, this flag to LLVM is needed. This is a backport of https://github.com/llvm/llvm-project/commit/93adcb770b99351b18553089c164fe3ef2119699.patch, with additional review at https://reviews.llvm.org/D158892 and emscripten-core/emscripten#20097. --- .../llvm/17/lld/add-table-base.patch | 190 ++++++++++++++++++ .../compilers/llvm/17/lld/default.nix | 1 + 2 files changed, 191 insertions(+) create mode 100644 pkgs/development/compilers/llvm/17/lld/add-table-base.patch diff --git a/pkgs/development/compilers/llvm/17/lld/add-table-base.patch b/pkgs/development/compilers/llvm/17/lld/add-table-base.patch new file mode 100644 index 0000000000000..15fc903a5e3f3 --- /dev/null +++ b/pkgs/development/compilers/llvm/17/lld/add-table-base.patch @@ -0,0 +1,190 @@ +From 93adcb770b99351b18553089c164fe3ef2119699 Mon Sep 17 00:00:00 2001 +From: Sam Clegg +Date: Fri, 25 Aug 2023 13:56:16 -0700 +Subject: [PATCH] [lld][WebAssembly] Add `--table-base` setting + +This is similar to `--global-base` but determines where to place the +table segments rather than that data segments. + +See https://github.com/emscripten-core/emscripten/issues/20097 + +Differential Revision: https://reviews.llvm.org/D158892 +--- + test/wasm/table-base.s | 72 ++++++++++++++++++++++++++++++++++++++ + wasm/Driver.cpp | 19 ++++++++-- + wasm/Options.td | 5 ++- + wasm/Writer.cpp | 8 ----- + 4 files changed, 93 insertions(+), 11 deletions(-) + create mode 100644 test/wasm/table-base.s + +diff --git a/test/wasm/table-base.s b/test/wasm/table-base.s +new file mode 100644 +index 000000000000000..56fff414fd31d96 +--- /dev/null ++++ b/test/wasm/table-base.s +@@ -0,0 +1,72 @@ ++# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o ++ ++# RUN: wasm-ld --export=__table_base -o %t.wasm %t.o ++# RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-DEFAULT ++ ++# RUN: wasm-ld --table-base=100 --export=__table_base -o %t.wasm %t.o ++# RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-100 ++ ++.globl _start ++_start: ++ .functype _start () -> () ++ i32.const _start ++ drop ++ end_function ++ ++# CHECK-DEFAULT: - Type: TABLE ++# CHECK-DEFAULT-NEXT: Tables: ++# CHECK-DEFAULT-NEXT: - Index: 0 ++# CHECK-DEFAULT-NEXT: ElemType: FUNCREF ++# CHECK-DEFAULT-NEXT: Limits: ++# CHECK-DEFAULT-NEXT: Flags: [ HAS_MAX ] ++# CHECK-DEFAULT-NEXT: Minimum: 0x2 ++# CHECK-DEFAULT-NEXT: Maximum: 0x2 ++ ++# CHECK-DEFAULT: - Type: GLOBAL ++# CHECK-DEFAULT-NEXT: Globals: ++# CHECK-DEFAULT-NEXT: - Index: 0 ++# CHECK-DEFAULT-NEXT: Type: I32 ++# CHECK-DEFAULT-NEXT: Mutable: true ++# CHECK-DEFAULT-NEXT: InitExpr: ++# CHECK-DEFAULT-NEXT: Opcode: I32_CONST ++# CHECK-DEFAULT-NEXT: Value: 66560 ++# CHECK-DEFAULT-NEXT: - Index: 1 ++# CHECK-DEFAULT-NEXT: Type: I32 ++# CHECK-DEFAULT-NEXT: Mutable: false ++# CHECK-DEFAULT-NEXT: InitExpr: ++# CHECK-DEFAULT-NEXT: Opcode: I32_CONST ++# CHECK-DEFAULT-NEXT: Value: 1 ++ ++# CHECK-DEFAULT: - Type: EXPORT ++# CHECK-DEFAULT: - Name: __table_base ++# CHECK-DEFAULT-NEXT: Kind: GLOBAL ++# CHECK-DEFAULT-NEXT: Index: 1 ++ ++# CHECK-100: - Type: TABLE ++# CHECK-100-NEXT: Tables: ++# CHECK-100-NEXT: - Index: 0 ++# CHECK-100-NEXT: ElemType: FUNCREF ++# CHECK-100-NEXT: Limits: ++# CHECK-100-NEXT: Flags: [ HAS_MAX ] ++# CHECK-100-NEXT: Minimum: 0x65 ++# CHECK-100-NEXT: Maximum: 0x65 ++ ++# CHECK-100: - Type: GLOBAL ++# CHECK-100-NEXT: Globals: ++# CHECK-100-NEXT: - Index: 0 ++# CHECK-100-NEXT: Type: I32 ++# CHECK-100-NEXT: Mutable: true ++# CHECK-100-NEXT: InitExpr: ++# CHECK-100-NEXT: Opcode: I32_CONST ++# CHECK-100-NEXT: Value: 66560 ++# CHECK-100-NEXT: - Index: 1 ++# CHECK-100-NEXT: Type: I32 ++# CHECK-100-NEXT: Mutable: false ++# CHECK-100-NEXT: InitExpr: ++# CHECK-100-NEXT: Opcode: I32_CONST ++# CHECK-100-NEXT: Value: 100 ++ ++# CHECK-100: - Type: EXPORT ++# CHECK-100: - Name: __table_base ++# CHECK-100-NEXT: Kind: GLOBAL ++# CHECK-100-NEXT: Index: 1 +diff --git a/wasm/Driver.cpp b/wasm/Driver.cpp +index 84304881f5ca34e..c2f5f0185781f36 100644 +--- a/wasm/Driver.cpp ++++ b/wasm/Driver.cpp +@@ -502,6 +502,7 @@ static void readConfigs(opt::InputArgList &args) { + + config->initialMemory = args::getInteger(args, OPT_initial_memory, 0); + config->globalBase = args::getInteger(args, OPT_global_base, 0); ++ config->tableBase = args::getInteger(args, OPT_table_base, 0); + config->maxMemory = args::getInteger(args, OPT_max_memory, 0); + config->zStackSize = + args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize); +@@ -573,6 +574,17 @@ static void setConfigs() { + if (config->exportTable) + error("-shared/-pie is incompatible with --export-table"); + config->importTable = true; ++ } else { ++ // Default table base. Defaults to 1, reserving 0 for the NULL function ++ // pointer. ++ if (!config->tableBase) ++ config->tableBase = 1; ++ // The default offset for static/global data, for when --global-base is ++ // not specified on the command line. The precise value of 1024 is ++ // somewhat arbitrary, and pre-dates wasm-ld (Its the value that ++ // emscripten used prior to wasm-ld). ++ if (!config->globalBase && !config->relocatable && !config->stackFirst) ++ config->globalBase = 1024; + } + + if (config->relocatable) { +@@ -666,8 +678,11 @@ static void checkOptions(opt::InputArgList &args) { + warn("-Bsymbolic is only meaningful when combined with -shared"); + } + +- if (config->globalBase && config->isPic) { +- error("--global-base may not be used with -shared/-pie"); ++ if (config->isPic) { ++ if (config->globalBase) ++ error("--global-base may not be used with -shared/-pie"); ++ if (config->tableBase) ++ error("--table-base may not be used with -shared/-pie"); + } + } + +diff --git a/wasm/Options.td b/wasm/Options.td +index 50417d2928e0a34..bb764396bf4df14 100644 +--- a/wasm/Options.td ++++ b/wasm/Options.td +@@ -191,7 +191,7 @@ def growable_table: FF<"growable-table">, + HelpText<"Remove maximum size from function table, allowing table to grow">; + + def global_base: JJ<"global-base=">, +- HelpText<"Where to start to place global data">; ++ HelpText<"Memory offset at which to place global data (Defaults to 1024)">; + + def import_memory: FF<"import-memory">, + HelpText<"Import the module's memory from the default module of \"env\" with the name \"memory\".">; +@@ -224,6 +224,9 @@ def no_entry: FF<"no-entry">, + def stack_first: FF<"stack-first">, + HelpText<"Place stack at start of linear memory rather than after data">; + ++def table_base: JJ<"table-base=">, ++ HelpText<"Table offset at which to place address taken functions (Defaults to 1)">; ++ + defm whole_archive: B<"whole-archive", + "Force load of all members in a static library", + "Do not force load of all members in a static library (default)">; +diff --git a/wasm/Writer.cpp b/wasm/Writer.cpp +index f25d358dc5bae6f..0576bf2907e49c4 100644 +--- a/wasm/Writer.cpp ++++ b/wasm/Writer.cpp +@@ -358,13 +358,6 @@ void Writer::layoutMemory() { + memoryPtr = config->globalBase; + } + } else { +- if (!config->globalBase && !config->relocatable && !config->isPic) { +- // The default offset for static/global data, for when --global-base is +- // not specified on the command line. The precise value of 1024 is +- // somewhat arbitrary, and pre-dates wasm-ld (Its the value that +- // emscripten used prior to wasm-ld). +- config->globalBase = 1024; +- } + memoryPtr = config->globalBase; + } + +@@ -1685,7 +1678,6 @@ void Writer::run() { + // For PIC code the table base is assigned dynamically by the loader. + // For non-PIC, we start at 1 so that accessing table index 0 always traps. + if (!config->isPic) { +- config->tableBase = 1; + if (WasmSym::definedTableBase) + WasmSym::definedTableBase->setVA(config->tableBase); + if (WasmSym::definedTableBase32) diff --git a/pkgs/development/compilers/llvm/17/lld/default.nix b/pkgs/development/compilers/llvm/17/lld/default.nix index cc18aee76a448..84943e8effce1 100644 --- a/pkgs/development/compilers/llvm/17/lld/default.nix +++ b/pkgs/development/compilers/llvm/17/lld/default.nix @@ -26,6 +26,7 @@ stdenv.mkDerivation rec { patches = [ ./gnu-install-dirs.patch + ./add-table-base.patch ]; nativeBuildInputs = [ cmake ninja ]; From c4a686bcb7952c76e1c0b7d0e4f5317b7db2814d Mon Sep 17 00:00:00 2001 From: Will Cohen Date: Sat, 25 Nov 2023 09:11:57 -0500 Subject: [PATCH 3/3] emscripten: 3.1.47 -> 3.1.50 --- ...-emulate-clang-sysroot-include-logic.patch | 32 ++++++++----------- .../compilers/emscripten/default.nix | 15 ++++++--- pkgs/top-level/all-packages.nix | 2 +- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/pkgs/development/compilers/emscripten/0001-emulate-clang-sysroot-include-logic.patch b/pkgs/development/compilers/emscripten/0001-emulate-clang-sysroot-include-logic.patch index 6a57e423bd72b..4171906d5e368 100644 --- a/pkgs/development/compilers/emscripten/0001-emulate-clang-sysroot-include-logic.patch +++ b/pkgs/development/compilers/emscripten/0001-emulate-clang-sysroot-include-logic.patch @@ -1,4 +1,4 @@ -From 4bbbb640934aa653bcfec0335798b77a8935b815 Mon Sep 17 00:00:00 2001 +From 86fc9ce2b381748813b372f7e86909be6f955cbd Mon Sep 17 00:00:00 2001 From: Yureka Date: Sat, 7 Aug 2021 09:16:46 +0200 Subject: [PATCH] emulate clang 'sysroot + /include' logic @@ -16,27 +16,23 @@ in the include search order, right after the resource root. Hence usage of -idirafter. Clang also documents an -isystem-after flag but it doesn't appear to work --- - emcc.py | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) + emcc.py | 3 +++ + 1 file changed, 3 insertions(+) diff --git a/emcc.py b/emcc.py -index ba8d1b556..7d89644c5 100755 +index 279f6d4d9..26e20e2cc 100644 --- a/emcc.py +++ b/emcc.py -@@ -883,7 +883,12 @@ def parse_s_args(args): +@@ -400,6 +400,9 @@ def get_cflags(user_args, is_cxx): + # We add these to the user's flags (newargs), but not when building .s or .S assembly files + cflags = get_clang_flags(user_args) + cflags.append('--sysroot=' + cache.get_sysroot(absolute=True)) ++ cflags.append('-resource-dir=@resourceDir@') ++ cflags.append('-idirafter' + cache.get_sysroot(absolute=True) + os.path.join('/include')) ++ cflags.append('-iwithsysroot' + os.path.join('/include','c++','v1')) - - def emsdk_cflags(user_args): -- cflags = ['--sysroot=' + cache.get_sysroot(absolute=True)] -+ cflags = [ -+ '--sysroot=' + cache.get_sysroot(absolute=True), -+ '-resource-dir=@resourceDir@', -+ '-idirafter' + cache.get_sysroot(absolute=True) + os.path.join('/include'), -+ '-iwithsysroot' + os.path.join('/include','c++','v1') -+ ] - - def array_contains_any_of(hay, needles): - for n in needles: + if settings.EMSCRIPTEN_TRACING: + cflags.append('-D__EMSCRIPTEN_TRACING__=1') -- -2.40.0 +2.42.0 diff --git a/pkgs/development/compilers/emscripten/default.nix b/pkgs/development/compilers/emscripten/default.nix index 01fa675205935..1f8d2f55da347 100644 --- a/pkgs/development/compilers/emscripten/default.nix +++ b/pkgs/development/compilers/emscripten/default.nix @@ -8,7 +8,7 @@ stdenv.mkDerivation rec { pname = "emscripten"; - version = "3.1.47"; + version = "3.1.50"; llvmEnv = symlinkJoin { name = "emscripten-llvm-${version}"; @@ -32,7 +32,7 @@ stdenv.mkDerivation rec { src = fetchFromGitHub { owner = "emscripten-core"; repo = "emscripten"; - hash = "sha256-cRNkQ+7vUqJLNlf5dieeDcyT1jlBUeVxO8avoUvOPHI="; + hash = "sha256-iFZF+DxGaq279QPPugoLhYmoXmyLPkmn1x4rBCkdW+I="; rev = version; }; @@ -42,7 +42,7 @@ stdenv.mkDerivation rec { patches = [ (substituteAll { src = ./0001-emulate-clang-sysroot-include-logic.patch; - resourceDir = "${llvmEnv}/lib/clang/16/"; + resourceDir = "${llvmEnv}/lib/clang/17/"; }) ]; @@ -51,6 +51,9 @@ stdenv.mkDerivation rec { patchShebangs . + # emscripten 3.1.50 requires LLVM tip-of-tree instead of LLVM 17 + sed -i -e "s/EXPECTED_LLVM_VERSION = 18/EXPECTED_LLVM_VERSION = 17.0/g" tools/shared.py + # fixes cmake support sed -i -e "s/print \('emcc (Emscript.*\)/sys.stderr.write(\1); sys.stderr.flush()/g" emcc.py @@ -106,7 +109,11 @@ stdenv.mkDerivation rec { # TODO: get library cache to build with both enabled and function exported $out/bin/emcc $LTO $BIND test.c $out/bin/emcc $LTO $BIND -s RELOCATABLE test.c - $out/bin/emcc $LTO $BIND -s USE_PTHREADS test.c + # starting with emscripten 3.1.48+, + # to use pthreads, _emscripten_check_mailbox must be exported + # (see https://github.com/emscripten-core/emscripten/pull/20604) + # TODO: get library cache to build with pthreads at all + # $out/bin/emcc $LTO $BIND -s USE_PTHREADS test.c done done popd diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 2363df0fd2f04..b0c0ded400c99 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -7943,7 +7943,7 @@ with pkgs; easeprobe = callPackage ../tools/misc/easeprobe { }; emscripten = callPackage ../development/compilers/emscripten { - llvmPackages = llvmPackages_16; + llvmPackages = llvmPackages_17; }; emscriptenPackages = recurseIntoAttrs (callPackage ./emscripten-packages.nix { });