[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