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

Shi, Steven via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 18 00:53:49 PST 2019


Hi Martin,
Thank you for the hint.

> 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.)
Yes, my assembly files do use prefix macro (ASM_PFX) for wrapping the underscore. We use the __USER_LABEL_PREFIX__ to control the  prefix macro expand to be "_" as below. I find the __USER_LABEL_PREFIX__ has been predefined by clang-cl, but it is defined as nothing. That is why my prefix macro expands to be nothing. Do you know why the clang-cl predefines the __USER_LABEL_PREFIX__ as nothing?

#ifndef __USER_LABEL_PREFIX__
#define __USER_LABEL_PREFIX__ _
#endif

#define _CONCATENATE(a, b)  __CONCATENATE(a, b)
#define __CONCATENATE(a, b) a ## b
#define ASM_PFX(name) _CONCATENATE (__USER_LABEL_PREFIX__, name)

Thanks
Steven

> -----Original Message-----
> From: Martin Storsjö [mailto:martin at martin.st]
> Sent: Monday, February 18, 2019 3:29 PM
> To: Shi, Steven <steven.shi at intel.com>
> Cc: Rui Ueyama <ruiu at google.com>; 'Peter Smith'
> <peter.smith at linaro.org>; 'llvm-dev at lists.llvm.org' <llvm-dev at lists.llvm.org>
> Subject: Re: [llvm-dev] lld-link fails to link 32bits assembly functions but
> 64bits pass
> 
> 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