[llvm-dev] (no subject)

Martin Storsjö via llvm-dev llvm-dev at lists.llvm.org
Thu Sep 24 00:49:03 PDT 2020


Hi,

On Wed, 23 Sep 2020, Eric Astor via llvm-dev wrote:

> While working on alias support for the LLVM-ML project, I ran into a feature
> implemented back in 2010: default-null weak externals in COFF, a GNU
> extension.
> https://reviews.llvm.org/rG17990d56907b
> I'd like to disable this feature when targeting MSVC compatibility. Does
> anyone have more context on this, and why it'd be a terrible idea?
> 
> For context: This seems to be designed to let LLVM implement a GNU extension
> in COFF libraries. However, it leads to very different behavior than we see
> for cl.exe (and ml.exe) on Windows; for already-defined aliasees, it injects
> an alternate placeholder ".weak.<alias>.default.<uniquifier>" symbol which
> resolves back to the current location. I admit, I'm not quite sure how this
> helps. If anyone can explain the purpose, I'd really appreciate it!

So, for the GNU extension, from the user point of view, there's two 
potential usecases.

A translation unit can reference a function declaration with 
__attribute__((weak)), with no implementation in the translation unit. 
This then then either evaluates to NULL or an actual implementation, if 
there existed another, non-weak definition in another object file at 
link time.

Secondly, multiple translation units may have function definitions that 
are marked with the weak attribute. You can have this in 0-N object files, 
and 0-1 object files containing a non-weak definition. If there's no 
non-weak definition, one of the weak definitions ends up picked, but if 
there is one, the non-weak one ends up used.

As all this is consumed via GNU style attributes (in MinGW environments), 
it shouldn't really matter in an MSVC context.

I recently worked on this to get the final details on this hooked up for 
COFF, so I'd be happy to have a look at any work touching this feature.

> In Windows PE/COFF files, aliases typically just resolve to their target
> symbol. For an example, see https://reviews.llvm.org/D87403#inline-811289.

For the cases where there already exists a symbol with a name that is 
unique in itself, just adding an alias directly to the target symbol 
sounds sensible in itself, but for cases when it isn't set up as an alias, 
but where the implementation itself is marked weak, the uniquifying symbol 
name is needed, to allow multiple objects to provide the same thing.

Consider these two examples in GAS assembly form:

         .globl uniquename
uniquename:
         ret

         .globl func
func:
         ret

         .weak aliasname
aliasname = func

This produces the following symbols, shown with llvm-objdump -t:

[ 6](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 uniquename
[ 7](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000001 func
[ 8](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 aliasname
AUX indx 10 srch 3        [pointing at .weak.aliasname.default.uniquename]
[10](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000001 .weak.aliasname.default.uniquename

So here .weak.aliasname.default.uniquename is identical to func, and as 
func itself is non-weak, aliasname could just as well have pointed 
directly at func instead.


But for this case, the extra dance is necessary:

         .globl uniquename
uniquename:
         ret

         .weak func
         .globl func
func:
         ret

Producing:
[ 6](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 uniquename
[ 7](sec  0)(fl 0x00)(ty   0)(scl  69) (nx 1) 0x00000000 func
AUX indx 9 srch 3
[ 9](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000001 .weak.func.default.uniquename



Initially, the non-weak symbols were just named ".weak.func.default", but 
this caused clashes if multiple object files defined the same one. I tried 
fixing this in https://reviews.llvm.org/D71711 by making the non-weak 
symbols that the weak ones point at static, but MSVC tools error out if 
you have a weak symbol pointing at a non-external symbol (as "weak" in 
COFF actually is "weak external"). Therefore I reverted that attempt and I 
later made https://reviews.llvm.org/D75989 that tries to make unique names 
for these symbols, to avoid clashes.

// Martin


More information about the llvm-dev mailing list