From 5805151cffccc087942b9dd8d7ac10ca5f4f80a8 Mon Sep 17 00:00:00 2001 From: lapla Date: Tue, 20 Jan 2026 18:47:13 +0900 Subject: [PATCH] fix: Resolve weak undefined symbols to zero in read-only sections (#1474) #1472 When a weak undefined symbol is referenced from a read-only section via an absolute relocation, the resolved value should be 0, not the PLT entry address. --- libwild/src/elf_writer.rs | 6 ++++++ wild/tests/integration_tests.rs | 3 ++- wild/tests/sources/undefined-weak-sym.c | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 wild/tests/sources/undefined-weak-sym.c diff --git a/libwild/src/elf_writer.rs b/libwild/src/elf_writer.rs index 2923bc9e9..026636f0d 100644 --- a/libwild/src/elf_writer.rs +++ b/libwild/src/elf_writer.rs @@ -2574,6 +2574,12 @@ fn write_absolute_relocation( &layout.merged_strings, &layout.merged_string_start_addresses, ) + } else if resolution.flags.is_dynamic() + && resolution.flags.is_absolute() + && !section_info.is_writable + { + // Weak undefined symbol referenced from a read-only section. Fill in as zero. + Ok(0) } else if resolution.flags.is_interposable() && section_info.is_writable { table_writer.write_dynamic_symbol_relocation::( place, diff --git a/wild/tests/integration_tests.rs b/wild/tests/integration_tests.rs index bc4730412..9dd611ba7 100644 --- a/wild/tests/integration_tests.rs +++ b/wild/tests/integration_tests.rs @@ -3320,7 +3320,8 @@ fn integration_test( "wrap-real-only.c", "ifunc-alias.c", "ifunc-address-equality.c", - "stack-size.c" + "stack-size.c", + "undefined-weak-sym.c" )] program_name: &'static str, #[allow(unused_variables)] setup_symlink: (), diff --git a/wild/tests/sources/undefined-weak-sym.c b/wild/tests/sources/undefined-weak-sym.c new file mode 100644 index 000000000..b029ca7e2 --- /dev/null +++ b/wild/tests/sources/undefined-weak-sym.c @@ -0,0 +1,25 @@ +// A test for #1472. + +//#Object:runtime.c +//#CompArgs:-fno-PIC +//#Mode:dynamic +//#Shared:force-dynamic-linking.c +//#DiffIgnore:section.got +//#DiffIgnore:.dynamic.DT_NEEDED +//#DiffIgnore:.dynamic.DT_RELA +//#DiffIgnore:.dynamic.DT_RELAENT +//#DiffIgnore:rel.undefined-weak.dynamic.R_X86_64_GLOB_DAT + +#include "runtime.h" + +#define WEAK __attribute__((weak)) + +int WEAK foo(void); + +void _start(void) { + runtime_init(); + if (foo) { + exit_syscall(foo()); + } + exit_syscall(42); +}