lld-link fails to link uefi binary because of undefined symbol _fltused

Hi Rui, Peter,

We meet a problem to use lld-link to generate uefi binary. It is related to the lld-link force to use float point lib symbol: _fltused. Uefi binary doesn’t use any external float point lib and we don’t know how to tell lld-link not to emit the float point lib symbol. Below is a simplified example to reproduce this issue. Please give me some advice. Thanks!

$ cat main.c

double v=0;

void mainfunction(){

v+=1;

}

$ ~/llvm-project/releaseinstall/bin/clang -c -Oz -flto -target x86_64-unknown-windows main.c -o main.ir

$ ~/llvm-project/releaseinstall/bin/lld-link /machine:X64 /DLL /ENTRY:mainfunction main.ir /OUT:main.dll

lld-link: error: undefined symbol: _fltused

referenced by lto.tmp

Thanks

Steven

This is expected behavior – if you use floating point operations in a source file, the _fltused symbol is mentioned in order to run the floating-point-environment initialization routine from the MS CRT.

If you want to make a standalone binary, not linking against the CRT, you can simply define “int _fltused = 0;” in some source file, within extern “C” {} if you’re in C++. (Note that the definition of the symbol doesn’t actually matter, since it’s normally only used as a trigger to pull in the initialization function.)

Hello Steven,

Apologies this is a little bit out of my area of expertise
(Windows/COFF). The reference to _fltused is coming from the compiler
and not the linker. You can see this by compiling your source file
without LTO and dumping the symbols. For example
bin/clang -c -Oz -target x86_64-unknown-windows main.c -o main.o
bin/llvm-readobj --symbols main.o
...
  Symbol {
    Name: _fltused
    Value: 0
    Section: IMAGE_SYM_UNDEFINED (0)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
...

In your case it will have come from the lld code generator.

A change to add this reference looks like
https://reviews.llvm.org/D56548 from various comments it seems like
this reference might be required by the Windows ABI in some cases. If
in your use case you don't need this then I suggest supplying a dummy
definition of the symbol in another object (making sure that LTO
doesn't remove it).

I think others on the list are more familiar with Windows.

Peter