[lld] [wasm-ld] Avoid a signed overflow on large sections (PR #178287)
Fatih BAKIR via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 27 12:07:59 PST 2026
https://github.com/FatihBAKIR created https://github.com/llvm/llvm-project/pull/178287
wasm sections sizes are specified as u32s, and thus can be as large as 4GB. wasm-ld currently stores the offset into a section as an int32_t which overflows on large sections and results in a crash. This change makes it a uint32_t to accommodate any valid wasm section.
This PR fixes the issue by storing the offset as a uint32_t, and also adds a lit test to make sure it works. I confirmed the test fails on `main` but passes with this fix.
Fixes https://github.com/llvm/llvm-project/issues/178286
>From 0a97d96deb316a5537036d5cf5da10ec5ff16adf Mon Sep 17 00:00:00 2001
From: fatih <mfatihbakir at gmail.com>
Date: Tue, 27 Jan 2026 11:12:39 -0800
Subject: [PATCH] [wasm-ld] Avoid a signed overflow on large sections
wasm sections sizes are specified as u32s, and thus can be as large as
4GB. wasm-ld currently stores the offset into a section as an int32_t
which overflows on large sections and results in a crash. This change
makes it a uint32_t to accommodate any valid wasm section.
---
lld/test/wasm/large-section.test | 34 ++++++++++++++++++++++++++++++++
lld/wasm/InputChunks.h | 2 +-
2 files changed, 35 insertions(+), 1 deletion(-)
create mode 100644 lld/test/wasm/large-section.test
diff --git a/lld/test/wasm/large-section.test b/lld/test/wasm/large-section.test
new file mode 100644
index 0000000000000..6f399000d9c89
--- /dev/null
+++ b/lld/test/wasm/large-section.test
@@ -0,0 +1,34 @@
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %t/chunk1.s -o %t/chunk1.o
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %t/chunk2.s -o %t/chunk2.o
+# --no-gc-sections to prevent the linker from optimizing the chunk away, otherwise it produces a tiny output
+# RUN: wasm-ld --no-entry --no-gc-sections %t/chunk1.o %t/chunk2.o -o %t/combined.wasm
+# RUN: llvm-readobj --sections %t/combined.wasm | FileCheck %s
+
+# Just making sure the linker doesn't crash for now and it has the combined, gigantic section, may need a better check
+# CHECK: Size: 2348810260
+
+# A 2GB + some extra bytes of data to make sure we go over 2G
+#--- chunk1.s
+.section .data.chunk1,"",@
+.globl chunk1_start
+.type chunk1_start, at object
+chunk1_start:
+ .int32 0xAAAAAAAA
+ .int32 0xBBBBBBBB
+ .zero 2214592504
+ .int32 0xCCCCCCCC
+ .int32 0xDDDDDDDD
+.size chunk1_start, 2214592512
+
+#--- chunk2.s
+.section .data.chunk2,"",@
+.globl chunk2_start
+.type chunk2_start, at object
+chunk2_start:
+ .int32 0x11111111
+ .int32 0x22222222
+ .zero 134217712
+ .int32 0x44444444
+ .int32 0x55555555
+.size chunk2_start, 134217728
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 1fe78d76631f1..462fa766081e6 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -97,7 +97,7 @@ class InputChunk {
// After assignAddresses is called, this represents the offset from
// the beginning of the output section this chunk was assigned to.
- int32_t outSecOff = 0;
+ uint32_t outSecOff = 0;
uint8_t sectionKind : 3;
More information about the llvm-commits
mailing list