You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When linking a shared library that contains object files with COMMON symbols (e.g. .gomp_critical_user_.var emitted by Clang for #pragma omp critical), wild leaves them as undefined (U) in the output instead of allocating them into BSS (B). Both lld and GNU ld correctly handle this case.
Also verified the bug is present on current main (62a18be).
Reproduction
// test.c#include<omp.h>#include<stdio.h>voiddo_work(int*data, intn) {
interror_count=0;
#pragma omp parallel for reduction(+:error_count)
for (inti=0; i<n; i++) {
if (data[i] <0) {
#pragma omp critical
{
fprintf(stderr, "Error at %d\n", i);
error_count++;
}
}
}
}
# Compile the object file
clang -c -fopenmp=libomp test.c -o test.o
# Confirm the COMMON symbols exist in the object file
$ nm test.o | grep gomp
0000000000000020 C .gomp_critical_user_.reduction.var
0000000000000020 C .gomp_critical_user_.var
# Link with lld — COMMON symbols correctly become BSS
$ clang -shared -fopenmp=libomp test.o -o test_lld.so -fuse-ld=lld
$ nm -D test_lld.so | grep gomp
0000000000003fb8 B .gomp_critical_user_.reduction.var
0000000000003f98 B .gomp_critical_user_.var
# Link with wild — COMMON symbols left undefined
$ clang -shared -fopenmp=libomp test.o -o test_wild.so -fuse-ld=wild
$ nm -D test_wild.so | grep gomp
U .gomp_critical_user_.reduction.var
U .gomp_critical_user_.var
Expected behavior
COMMON symbols (C) in input object files should be allocated into BSS and appear as defined (B) in the output shared library, matching lld and GNU ld behavior.
Actual behavior
COMMON symbols remain undefined (U) in the output shared library, causing dlopen to fail at runtime:
undefined symbol: .gomp_critical_user_.var
Impact
Any shared library built with wild that contains OpenMP #pragma omp critical or #pragma omp ... reduction(...) (compiled with Clang) will fail to load at runtime.
Analysis
I traced this to SymbolCopyInfo::new() in libwild/src/layout.rs (around line 4384):
if sym.as_common().is_some() && !symbol_state.has_resolution(){returnNone;}
This skips COMMON symbols from the symtab when they don't have a resolution flag set. The load_symbol path in RegularLayoutState correctly calls common.allocate() for COMMON symbols, and load_non_hidden_symbols sets EXPORT_DYNAMIC. However, it appears the COMMON symbol either doesn't get its resolution flags set properly by the time allocate_symtab_space runs, or SymbolCopyInfo::new() is too aggressive in filtering them out.
Notes
GNU ld has a -d/-dc/-dp flag to "force common symbols to be defined", but lld doesn't need it (it always defines them). wild doesn't support this flag either.
A related fix for TLS COMMON symbols was made in commit 4f0688e (fix: put common TLS symbols into correct section #1310), but that addressed TLS symbols being placed in the wrong section, not the general case of non-TLS COMMON symbols being dropped from shared library output.
Summary
When linking a shared library that contains object files with COMMON symbols (e.g.
.gomp_critical_user_.varemitted by Clang for#pragma omp critical), wild leaves them as undefined (U) in the output instead of allocating them into BSS (B). Bothlldand GNUldcorrectly handle this case.Version
wild 0.8.0 (
d789d5d6716de3f665ff3da0c53d02dc65e49e3b)Also verified the bug is present on current
main(62a18be).Reproduction
Expected behavior
COMMON symbols (
C) in input object files should be allocated into BSS and appear as defined (B) in the output shared library, matchinglldand GNUldbehavior.Actual behavior
COMMON symbols remain undefined (
U) in the output shared library, causingdlopento fail at runtime:Impact
Any shared library built with wild that contains OpenMP
#pragma omp criticalor#pragma omp ... reduction(...)(compiled with Clang) will fail to load at runtime.Analysis
I traced this to
SymbolCopyInfo::new()inlibwild/src/layout.rs(around line 4384):This skips COMMON symbols from the symtab when they don't have a resolution flag set. The
load_symbolpath inRegularLayoutStatecorrectly callscommon.allocate()for COMMON symbols, andload_non_hidden_symbolssetsEXPORT_DYNAMIC. However, it appears the COMMON symbol either doesn't get its resolution flags set properly by the timeallocate_symtab_spaceruns, orSymbolCopyInfo::new()is too aggressive in filtering them out.Notes
ldhas a-d/-dc/-dpflag to "force common symbols to be defined", butllddoesn't need it (it always defines them). wild doesn't support this flag either.4f0688e(fix: put common TLS symbols into correct section #1310), but that addressed TLS symbols being placed in the wrong section, not the general case of non-TLS COMMON symbols being dropped from shared library output.