Pelles C forum
C language => Beginner questions => Topic started by: roger@languageone.com.au on December 05, 2018, 06:21:53 AM
-
All my code is assembled using NASM
I have created a library using POLIB
How do I link this library with my main module ?
-
Assemble using the Win32/Win64 output format in nasm, then use polink to link library and nasm object files.
-
I can do that happily, but was looking to build a library to link to.
After creating the library any attempt to link to it results in "unresolved external reference".
I thought perhaps I was doing something wrong.
-
Are those symbols from your library ?
Same calling convention ?
-
Yes and Yes
-
In my test for x86 nasm needs commandline option --gprefix _
extern int foo1();
extern int foo2();
int printf(const char * restrict format, ...);
int __cdecl main(void)
{
printf("foo1: %d\n", foo1());
printf("foo2: %d\n", foo2());
return 0;
}
; nasm.exe -fwin32 --gprefix _ -o test_nasm_1.obj test_nasm_1.asm
; nasm.exe -fwin64 -o test_nasm_1.obj test_nasm_1.asm
global foo1
section .text ; instructions, code segment
foo1:
mov eax, 1
ret
; nasm.exe -fwin32 --gprefix _ -o test_nasm_2.obj test_nasm_2.asm
; nasm.exe -fwin64 -o test_nasm_2.obj test_nasm_2.asm
global foo2
section .text ; instructions, code segment
foo2:
mov eax, 2
ret
PS: PEView (http://wjradburn.com/software/) or TLPEView (https://forum.pellesc.de/index.php?topic=7172.msg27200#msg27200) show library or object-file symbols.
-
I get the following error when using -gprefix
nasm: fatal: unrecognized debug format `prefix' for output format `win64'
I get the following information from nasm regarding debug formats for win64
nasm -f win64 -y
valid debug formats for 'win64' output format are ('*' denotes default):
cv8 Codeview 8
-
In test was --gprefix _ for underscore for x86 __cdecl
nasm.exe -fwin32 --gprefix _ -o test_nasm_1.obj test_nasm_1.asm
Also polink v9.0 don't support CV8 / CodeView debug format.
-
Your example uses win32
My code is 64bit (win64)
-
First of all Timo is talking of "--gprefix _" (double dash --) not "-gprefix" (single dash) that is the switch that defines debug information.
In 64bits code there is no decoration at all of symbols, so you shouldn't have any problem linking the modules.
I suggest to use the utility podump to have a look of symbols created in the modules.
If still in trouble post a small sample containing library and assembler modules and a cmd file with the comand you use to link it reproducing the problem, so we can check it.
-
I have cut down the the command responses but hopefully you can follow what I have done.
It show a dump of one of the obj files (w_WWW.obj)
A list of the library to show that w_WWW.obj exists in the library
and a dump of the library to show that _WWW is there
I guess I am just using polink incorrectly or that there may be some requirement for a .def or .lib file ????
Dump of lib\w_WWW.obj
File type: OBJ
SYMBOL TABLE
0000 00000000 DEBUG notype filename | .file
w_WWW.LIB
0002 00000000 SECT1 notype static | .debug$S
length of section 1700, #relocations B8, #linenumbers 0
0004 00000000 SECT2 notype static | .debug$T
length of section 1E, #relocations 0, #linenumbers 0
0006 00000000 SECT3 notype static | .data
length of section 10080, #relocations 5, #linenumbers 0
0008 00000000 SECT4 notype static | .bss
length of section A66, #relocations 0, #linenumbers 0
000A 00000000 SECT5 notype static | .text
length of section 88B, #relocations 6D, #linenumbers 0
000C 00000000 ABS notype static | .absolut
000D 00000000 UNDEF notype external | CreateFileA
000E 00000000 UNDEF notype external | ReadFile
.
.
0045 00000000 SECT5 notype external | _WWW
C:\Users\roger\_dev1\source\languageONE>_PELLESC\Bin\polib /LIST lib\languageONE.w
SUMMARY
A66 .bss
10080 .data
1700 .debug$S
1E .debug$T
88B .text
lib\DECISIONS.obj
lib\NUMBERS.obj
lib\TABLES.obj
lib\WORDS.obj
lib\w_COMMON.obj
lib\w_FILES.obj
lib\w_STDIO.obj
lib\w_WWW.obj
lib\w_XTABLES.obj
Dump of lib\languageONE.w
File type: LIB
SYMBOL TABLE
0000 00000000 DEBUG notype filename | .file
w_WWW.LIB
0002 00000000 SECT1 notype static | .debug$S
length of section 16C0, #relocations B4, #linenumbers 0
0004 00000000 SECT2 notype static | .debug$T
length of section 1E, #relocations 0, #linenumbers 0
0006 00000000 SECT3 notype static | .data
length of section 10071, #relocations 5, #linenumbers 0
0008 00000000 SECT4 notype static | .bss
length of section A66, #relocations 0, #linenumbers 0
000A 00000000 SECT5 notype static | .text
length of section 87F, #relocations 6D, #linenumbers 0
000C 00000000 ABS notype static | .absolut
000D 00000000 UNDEF notype external | CreateFileA
000E 00000000 UNDEF notype external | ReadFile
.
.
0044 00000000 SECT5 notype external | _WWW
-
This works for me using PellesC 9:
nasm -fwin64 w_WWW.asm
polib -out:w_WWW.lib w_WWW.obj
pocc w_test.c
polink w_test.obj w_WWW.lib -map
;w_WWW.asm
global _WWW
section .text
_WWW:
mov eax, 1
ret
//w_test.c
extern _WWW;
int main(void)
{
return _WWW;
}
-
I don't find any problem linking between modules compiled with nasm and PellesC, in object module or library.
The attached sample uses 3 modules, one of which in assembler and in C.
The main executable call the function foo, write in assembler and compiled with nasm. This function use a symbol defined in the main.c module, and call the function bar in library foobar.lib.
The library is build in assembler, using nasm, and in C.
The command file make.cmd compiles the 2 versions and run them.
-
The difference here is that ALL my code is assembler.
I assemble modules thus:-
nasm -f win64 -O0 -w-macro-params %prog%.ASM
linking a main module to library modules (*.obj) is succesfully achieved thus:-
polink /subsystem:console /entry:_start /largeaddressaware:no /export:_start %1.obj @w.pellesC.libraries
with @pellesC.libraries defined as thus:-
lib\DECISIONS.obj
lib\NUMBERS.obj
lib\TABLES.obj
lib\WORDS.obj
lib\w_COMMON.obj
lib\w_STDIO.obj
lib\w_FILES.obj
lib\w_XTABLES.obj
lib\w_WWW.obj
_PELLESC\Lib\Win64\kernel32.lib
_PELLESC\Lib\Win64\ws2_32.lib
_PELLESC\Lib\Win64\lz32.lib
HOWEVER trying to create a library thus:-
polib /machine:x64 /out:lib\languageONE.w lib\*.obj
and then linking thus:-
polink /subsystem:console /entry:_start /largeaddressaware:no /export:_start %1.obj @w.pellesC.libraries
with @pellesC.libraries defined as thus:-
lib\languageONE.w
_PELLESC\Lib\Win64\kernel32.lib
_PELLESC\Lib\Win64\ws2_32.lib
_PELLESC\Lib\Win64\lz32.lib
fails with:-
POLINK: fatal error: Invalid machine type in object 'lib\languageONE.w
-
Rename lib\languageONE.w to lib\languageONE.lib, otherwise it is handled as a object-file.
POLINK has the following general syntax:
POLINK [ { filespec | @response-file | option } ... ]
The filespec argument specifies the name of a library (.lib or .a), a module-definition file (.def), a binary resource file (.res), or an object file (.obj or .o). Wildcards are allowed for all types except a module-definition file.
-
Try with:
polink -machine:x64 /subsystem:console /entry:_start /largeaddressaware:no /export:_start %1.obj @w.pellesC.libraries
Adding the machine type.
As specified by Timo the problem is the library file extension '.w' which is not standard.
polink uses the file extension to define the file-type, the extension '.w' is interpreted as an object file, so when the linker try to access the supposed object file format looking for PE header find wrong machine type (and of course a lot of other wrong data :( )
-
Thanks guys. That did the trick.
Oddly, I had tried this once but must of had an error somewhere else that masked this.
Thanks again :)