[llvm-dev] lld-link fails to link 32bits assembly functions but 64bits pass

Martin Storsjö via llvm-dev llvm-dev at lists.llvm.org
Sun Feb 17 23:28:30 PST 2019


On Mon, 18 Feb 2019, Shi, Steven via llvm-dev wrote:

> 
> Hi Rui, Peter,
> 
> You know I’m enabling the “clang-cl + lld-link” toolchain for Uefi firmware.
> I meet a problem that the lld-link fails to link 32bits assembly functions,
> but can link 64bits assembly functions successfully. I need your suggestion.
> 
> Below is an example to show my problem in linux. The example has two only
> source files: main.c and foo.nasm.
> 
>  
> 
> $ cat main.c
> 
> void Foo (void);
> 
> int main()
> 
> {
> 
>   Foo();
> 
>   return 0;
> 
> }
> 
>  
> 
> $ cat foo.nasm
> 
>     SECTION .text
> 
> global Foo
> 
> Foo:
> 
> Ret
> 
>  
> 
> 64bits compiling and linking is successful:
> 
> $ nasm foo.nasm -Ox -f win64 -g -o foo.obj
> 
> $ ~/llvm/releaseinstall/bin/clang-cl main.c /nologo /c /WX /GS- /W4 /Gs32768
> /D UNICODE /O1b2s /EHs-c- /GR- /GF /Gy /Zi /Gw -m64
> 
> $ ~/llvm/releaseinstall/bin/lld-link main.obj foo.obj /NOLOGO /NODEFAULTLIB
> /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /SECTION:.xdata,D
> /SECTION:.pdata,D /DLL /ENTRY:main /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER
> /SAFESEH:NO /BASE:0 /DRIVER: /DEBUG:GHASH /Machine:X64
> 
>  
> 
> But 32bits linking fails with error of Foo assembly function is a undefined
> symbol:
> 
> $ nasm foo.nasm -Ox -f win32 -g -o foo.obj
> 
> $ ~/llvm/releaseinstall/bin/clang-cl main.c /nologo /c /WX /GS- /W4 /Gs32768
> /D UNICODE /O1b2 /EHs-c- /GR- /GF /Gy /Zi /Gw -m32
> 
> $ ~/llvm/releaseinstall/bin/lld-link main.obj foo.obj /NOLOGO /NODEFAULTLIB
> /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /SECTION:.xdata,D
> /SECTION:.pdata,D /DLL /ENTRY:main /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER
> /SAFESEH:NO /BASE:0 /DRIVER: /DEBUG:GHASH /MACHINE:X86
> 
> lld-link: error: undefined symbol: _Foo
> 
> >>> referenced by /home/jshi19/llvm/wrongcode/lld-link/main.c:4
> 
> >>>               main.obj:(_main)

For 32 bit windows, functions with cdecl calling convention (the default 
in C) are decorated with an underscore prefix. So you'd need to update 
your nasm source file to define the symbol _Foo instead of Foo. (Most 
assembly files use some sort of macro for wrapping this detail.)


> BTW, I find the lld-link does not suppor the /MAP option to generate
> mapfile. If I hope to output the linking mapfile info, what option should I
> use?

lld-link has got a private option /lldmap:<filename> which does output 
some sort of filename. I'm not sure what the reasons are for providing it 
under a private name instead of supporting the link.exe option /map. Maybe 
the format of the generated mapfile differs so that it might not work for 
automatic tools that operate on the map file at least.

// Martin


More information about the llvm-dev mailing list