Shi, Steven via llvm-dev
2019-Feb-18 07:19 UTC
[llvm-dev] lld-link fails to link 32bits assembly functions but 64bits pass
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)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? Thanks Steven -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190218/a0503db7/attachment.html>
Martin Storsjö via llvm-dev
2019-Feb-18 07:28 UTC
[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
Shi, Steven via llvm-dev
2019-Feb-18 08:53 UTC
[llvm-dev] lld-link fails to link 32bits assembly functions but 64bits pass
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