llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.99k stars 11.05k forks source link

The compiler generates mangled weak symbol in scope of `extern "C"` #95891

Open AllanZyne opened 4 weeks ago

AllanZyne commented 4 weeks ago

example:

// weak.cpp
extern "C" {
int __xxx(void) { return 0; }
#pragma weak xxx = __xxx
}

clang:

$ clang++ -shared weak.cpp -o libweak.so
$ nm -D libweak.so
                 w __cxa_finalize
                 w __gmon_start__
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000001100 T __xxx
0000000000001100 W _Z3xxxv

compare with gcc:

$ g++ -shared weak.cpp -o libweak_gcc.so
$ nm -D libweak_gcc.so
                 w __cxa_finalize                                                                                                                                                                                                                            
                 w __gmon_start__                                                                                                                                                                                                                            
                 w _ITM_deregisterTMCloneTable                                                                                                                                                                                                               
                 w _ITM_registerTMCloneTable                                                                                                                                                                                                                 
00000000000010f9 T __xxx                                                                                                                                                                                                                                     
00000000000010f9 W xxx
llvmbot commented 4 weeks ago

@llvm/issue-subscribers-clang-frontend

Author: Yang Zhao (AllanZyne)

example: ```c++ // weak.cpp extern "C" { int __xxx(void) { return 0; } #pragma weak xxx = __xxx } ``` clang: ```bash $ clang++ -shared weak.cpp -o libweak.so $ nm -D libweak.so w __cxa_finalize w __gmon_start__ w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 0000000000001100 T __xxx 0000000000001100 W _Z3xxxv ``` compare with gcc: ```bash $ g++ -shared weak.cpp -o libweak_gcc.so $ nm -D libweak_gcc.so w __cxa_finalize w __gmon_start__ w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 00000000000010f9 T __xxx 00000000000010f9 W xxx ```
shafik commented 3 weeks ago

CC @MaskRay

bd1976bris commented 2 weeks ago

GCC's docs state that #pragma weak takes a "symbol" name which I suspect means not the name in the source code but the potentially mangled symbol name after codegen. Given that I suspect that the bug is that Clang shouldn't be applying name mangling (or any other manipulation) to the arguments to #pragma weak.

A workaround is to combine an alias attribute with the other form of #pragma weak.

// weak.cpp
extern "C" {
int __xxx(void) { return 0; };
int xxx(void)  __attribute__((alias("__xxx")));
#pragma weak xxx
}