Recent

Author Topic: FPC 3.2.2 + NASM Windows 64-Bit Pro + how to: create DLL and EXE of .o files ?  (Read 2462 times)

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
now, no error pointed to multiple or undefined references by using ld.exe
But I get a very long list of:

ld: error: 0-bit reloc in dll
...

under the Windows Console.

I fpc compile with -fPIC
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
@munair
how do you doing NASM + LD ?
what is the command line ?
what do you link (.o and .a files) ?

I use it to compile the SharpBASIC runtime library and compiler, e.g. i386 code:

Code: FreeBasic  [Select][+][-]
  1. ' assemble
  2. print "assembling: " + afile.path
  3. buf = "nasm -f elf32 " + afile.path  ' + " -Ox" ' optimization
  4. print buf
  5. shell buf
  6.  
  7. ' link
  8. print "linking: " + afile.spec
  9. buf = "ld -m elf_i386 " + afile.spec + ".o " + "lib/sys.o " + "lib/io.o " + "-o " + afile.spec
  10. print buf
  11. shell buf
  12.  

There is plenty online documentation for nasm and ld. I suggest you look it up for your specific needs.
It's only logical.

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
thanks for the replies.
I get it working...

But an other Question about linking:

The CLI command option -B can be used, to force a compile run to compile all Pascal Files and Resource Files.
So, when I not use the -B Option explicit, the .s and .o bject Files will be not touched again in a new compile - only if they modified and/or the date is different from the source File (like Makefile's works) ?
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12270
  • FPC developer.
thanks for the replies.
I get it working...

But an other Question about linking:

The CLI command option -B can be used, to force a compile run to compile all Pascal Files and Resource Files.
So, when I not use the -B Option explicit, the .s and .o bject Files will be not touched again in a new compile - only if they modified and/or the date is different from the source File (like Makefile's works) ?

No. The recompilation is based on the ppu and sources I think, not the .o or .s

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
okay, indeed.
FPC seems to work with a checksum hash for each compiled unit (.ppu and .o).

But, when I compile with:
Code: Bash  [Select][+][-]
  1. fpc -dDLLEXPORT -dLANGDEU -n -B -O3 -Os -fPIC -CD RTLLib.pas
I get a working DLL

But, when I compile with:
Code: Bash  [Select][+][-]
  1. fpc -dDLLIMPORT -dLANGDEU -n -B -O3 -Os test.pas
I get a working EXE which can call the Functions out of the DLL above.

But. when I link with existing .o files:
Code: Bash  [Select][+][-]
  1. ld --disable-runtime-pseudo-reloc -nostdlib --allow-shlib-undefined ^
  2. -Map test.map --gc-sections -o test2.exe -T link.ld
I get only many error's in the style of:
Code: Bash  [Select][+][-]
  1. ld: error: 0-bit reloc in dll
  2. ld: error: 0-bit reloc in dll
  3. ld: error: 0-bit reloc in dll
  4. ...
by using this link.ld script:
Code: Bash  [Select][+][-]
  1. SEARCH_DIR(".")
  2. INPUT(
  3. RTLLib.o
  4. system.o
  5. xmm.o
  6. windows.o
  7. global.o
  8. RTLunit.o
  9. dialogs.o
  10. sysutils.o
  11. strutils.o
  12. exceptions.o
  13. locales.o
  14. sysinitpas.o
  15. )
  16. GROUP(
  17. libimpsystem.a
  18. libimpxmm.a
  19. libimpwindows.a
  20. libimpRTLunit.a
  21. libimpsysutils.a
  22. libimpexceptions.a
  23. )
  24. OUTPUT_FORMAT(pei-x86-64)
  25. ENTRY(PASCALMAIN)
  26. SECTIONS
  27. {
  28.   . = SIZEOF_HEADERS;
  29.   . = ALIGN(__section_alignment__);
  30.   .text  __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
  31.   {
  32.     __text_start__ = . ;
  33.     *(.init)
  34.     *(.text .stub .text.* .gnu.linkonce.t.*)
  35.     *(SORT(.text$*))
  36.     *(.glue_7t)
  37.     *(.glue_7)
  38.     . = ALIGN(8);
  39.      ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
  40.     LONG (-1);
  41.     LONG (-1);
  42.     *(.ctors); *(.ctor); *(SORT(.ctors.*));  LONG (0);
  43.     LONG (0);
  44.      ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
  45.     LONG (-1);
  46.     LONG (-1);
  47.     *(.dtors); *(.dtor); *(SORT(.dtors.*));  LONG (0);
  48.     LONG (0);
  49.      *(.fini)
  50.     PROVIDE (etext = .);
  51.     *(.gcc_except_table)
  52.   }
  53.   .data BLOCK(__section_alignment__) :
  54.   {
  55.     __data_start__ = . ;
  56.     *(.data .data.* .gnu.linkonce.d.* .fpc*)
  57.     *(.data2)
  58.     *(SORT(.data$*))
  59.     *(.jcr)
  60.     PROVIDE (_tls_index = .);
  61.     LONG (0);
  62.     __data_end__ = . ;
  63.     *(.data_cygwin_nocopy)
  64.   }
  65.   .rdata BLOCK(__section_alignment__) :
  66.   {
  67.     *(.rdata)
  68.     *(.rdata.*)
  69.     *(.rodata .rodata.* .gnu.linkonce.r.*)
  70.     *(SORT(.rdata$*))
  71.     *(.eh_frame)
  72.     ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
  73.     __RUNTIME_PSEUDO_RELOC_LIST__ = .;
  74.     *(.rdata_runtime_pseudo_reloc)
  75.     ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  76.     __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
  77.   }
  78.   .pdata BLOCK(__section_alignment__) : { *(.pdata) }
  79.   .bss BLOCK(__section_alignment__) :
  80.   {
  81.     __bss_start__ = . ;
  82.     *(.bss .bss.* .gnu.linkonce.b.*)
  83.     *(SORT(.bss$*))
  84.     *(COMMON)
  85.     __bss_end__ = . ;
  86.   }
  87.   .edata BLOCK(__section_alignment__) : { *(.edata) }
  88.   .idata BLOCK(__section_alignment__) :
  89.   {
  90.     SORT(*)(.idata$2)
  91.     SORT(*)(.idata$3)
  92.     /* These zeroes mark the end of the import list.  */
  93.     LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
  94.     SORT(*)(.idata$4)
  95.     SORT(*)(.idata$5)
  96.     SORT(*)(.idata$6)
  97.     SORT(*)(.idata$7)
  98.   }
  99.   .CRT BLOCK(__section_alignment__) :
  100.   {
  101.     ___crt_xc_start__ = . ;
  102.     *(SORT(.CRT$XC*))  /* C initialization */
  103.     ___crt_xc_end__ = . ;
  104.     ___crt_xi_start__ = . ;
  105.     *(SORT(.CRT$XI*))  /* C++ initialization */
  106.     ___crt_xi_end__ = . ;
  107.     ___crt_xl_start__ = . ;
  108.     *(SORT(.CRT$XL*))  /* TLS callbacks */
  109.     /* ___crt_xl_end__ is defined in the TLS Directory support code */
  110.     PROVIDE (___crt_xl_end__ = .);
  111.     ___crt_xp_start__ = . ;
  112.     *(SORT(.CRT$XP*))  /* Pre-termination */
  113.     ___crt_xp_end__ = . ;
  114.     ___crt_xt_start__ = . ;
  115.     *(SORT(.CRT$XT*))  /* Termination */
  116.     ___crt_xt_end__ = . ;
  117.   }
  118.   .tls BLOCK(__section_alignment__) :
  119.   {
  120.     ___tls_start__ = . ;
  121.     *(.tls .tls.*)
  122.     *(.tls$)
  123.     *(SORT(.tls$*))
  124.     ___tls_end__ = . ;
  125.   }
  126.   .rsrc BLOCK(__section_alignment__) :
  127.   {
  128.     *(.rsrc)
  129.     *(SORT(.rsrc$*))
  130.   }
  131.   .reloc BLOCK(__section_alignment__) : { *(.reloc) }
  132.   .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) }
  133.   .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) }
  134. }
  135.  
No DLL or EXE with the last LD step isn't produced.
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12270
  • FPC developer.
The Windows version of LD has a lot of limitations, and in general it is NOT used.  We stuck with the last versions before the msys introduction, which means that is probably a 2005(!) version. The increased use of the internal linker since 2007-2008 and finally the deprecation of the final usage, the textmode IDE with mingw GDB integrated in 2020.

In short, the disassociation of FPC windows targets from mingw/msys is nearly complete, and by sticking with it, you are entering unknown territory.

You could try newer LD's, but YMMV. The last linker I tested must have been somewhere in 2009 when I changed from cygwin to mingw and created the helper tools page


« Last Edit: May 14, 2025, 07:42:03 pm by marcov »

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
for versioning is proberly not the Problem:

as --version
GNU assembler (GNU Binutils) 2.42
Copyright (C) 2024 Free Software Foundation, Inc.

ld --version
GNU ld (GNU Binutils) 2.42
Copyright (C) 2024 Free Software Foundation, Inc.

gcc --version
gcc.exe (Rev3, Built by MSYS2 project) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
The ld man page (e.g., on man7.org or manpages.ubuntu.com) offers a concise reference for command-line options and basic usage. The OSDev Wiki provides insights into linker scripts for operating system development, particularly relevant for custom binary layouts. Blogs like "The most thoroughly commented linker script" by Thea Flowers offer practical, annotated examples of linker scripts for embedded systems. The LLVM project's lld documentation compares ld with alternatives, providing context on its features. https://lld.llvm.org/

Run ld --help or man ld on a system with Binutils installed for quick reference.

Use ld --verbose to display the default linker script for your system, which is useful for understanding platform-specific behavior.
https://mcyoung.xyz/2021/06/01/linker-script/

The GNU linker (ld) is primarily designed for Unix-like systems but can be used on Windows with some considerations. Its suitability depends on your use case, as it has both strengths and limitations in a Windows environment:

+ Cross-Platform Availability:
ld is included in toolchains like MinGW (Minimalist GNU for Windows) and MSYS2, which provide GNU Binutils for Windows. These environments allow ld to link object files into executables or libraries compatible with Windows. For example, MinGW uses ld to produce PE/COFF binaries, the native Windows executable format.

+ Cross-Compilation:
ld is widely used for cross-compiling Windows binaries from Linux or other platforms. For instance, you can configure ld with a Windows target (e.g., i686-w64-mingw32-ld) to generate Windows executables. This is common in embedded development or open-source projects.

+ Support for Windows-Specific Formats:
ld supports the PE/COFF format (used for Windows .exe and .dll files) through the BFD (Binary File Descriptor) libraries. It can handle Windows-specific features like DLL imports/exports and debug information, though with some quirks.

+ Linker Scripts for Customization:
ld's linker script language allows fine-grained control over binary layout, which is useful for specialized Windows applications (e.g., embedded systems or custom loaders).

+ Integration with GCC:
When used with gcc on Windows (via MinGW or MSYS2), ld is invoked indirectly through the compiler driver, simplifying the linking process for C/C++ programs.

- Native Windows Toolchain Preference:
Windows typically uses Microsoft’s linker (link.exe), part of the Visual Studio toolchain, which is optimized for the Windows ecosystem. ld is less common in native Windows development and may not integrate as seamlessly with Windows-specific tools like MSVC.

- PE/COFF Support Quirks:
While ld supports PE/COFF, its implementation is not as robust as Microsoft’s linker for certain Windows-specific features. For example:
DLL Handling: ld can struggle with complex DLL scenarios, such as auto-importing data symbols, leading to errors like "variable '<var>' can't be auto-imported." The --enable-auto-import option helps but may not resolve all issues.

Debug Information: ld supports Windows debug info (PDB) but may produce non-standard output when using long section names for Dwarf-2 debug info, which can confuse non-GNU tools.

Performance: For large Windows projects, ld may be slower than Microsoft’s linker or LLVM’s lld, which is optimized for PE/COFF.

- Environment Setup:
Using ld on Windows requires setting up a Unix-like environment (e.g., MSYS2, Cygwin, or WSL), which adds complexity compared to native Windows tools. Cygwin, for instance, introduces a dependency on its runtime (cygwin1.dll), which may not be desirable for standalone Windows applications.

-> Alternative Linkers:
LLVM’s lld is a drop-in replacement for ld and offers better performance and native PE/COFF support on Windows. It’s often recommended over ld for Windows development due to its speed (more than twice as fast as GNU gold in some cases) and compatibility with Windows debug info.

Microsoft’s link.exe is the standard for Windows-native development, especially for projects using MSVC or Windows SDKs.

- Dynamic Linking Challenges:
Windows’ dynamic linking model (DLLs) differs from Unix’s shared libraries (.so). ld handles DLLs but may require additional configuration (e.g., --dll-search-prefix or --enable-stdcall-fixup) to resolve symbol mismatches or calling convention issues.


For most Windows projects, consider alternatives like LLVM’s lld or Microsoft’s link.exe unless ld’s specific features (e.g., linker scripts) are required.

I hope this helps.
It's only logical.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12270
  • FPC developer.
munair: sounds like a low grade AI summary.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
munair: sounds like a low grade AI summary.
These are basic considerations when choosing LD on Windows.
It's only logical.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12270
  • FPC developer.
munair: sounds like a low grade AI summary.
These are basic considerations when choosing LD on Windows.

I can't imagine recommending LLD over LD.  LLD basically has no error handling, and simply silently generates defunct binaries.

And since this is the FPC channel, it must work with FPC generated object files (which are generated by FPC directly), and a dll generated by the internal linker.  The FPC internal parts replaced an AS/AR/LD combo, so the formats and style it generates are close to it (like COFF, and not OMF). I don't know the commercial linkers that well, but that might be a problem.  .

As for Paule32: you might want try to use a development version of FPC and see if that contains fixes to the object writer/internal linker.

munair

  • Hero Member
  • *****
  • Posts: 884
  • compiler developer @SharpBASIC
    • SharpBASIC
I can't imagine recommending LLD over LD.  LLD basically has no error handling, and simply silently generates defunct binaries.
LLD has matured over the years and according to development status is used to link production builds such as Chromium and Firefox.
https://lld.llvm.org/windows_support.html

It might be a better choice than LD. However, it remains tricky what the OP tries to do and I agree with PascalDragon.
It's only logical.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12270
  • FPC developer.
I can't imagine recommending LLD over LD.  LLD basically has no error handling, and simply silently generates defunct binaries.
LLD has matured over the years and according to development status is used to link production builds such as Chromium and Firefox.

That is the problem. LLD is only verified as far as clang uses it. We are talking here about blending object files from various sources. That is not the same kind of usage, and errorhandling for unsupported features are important.

My experiences were afaik with LLVM 14 on FreeBSD 14. 

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
now, I get 7 reloc errors.
A step wider because before the count was over 20 reloc error's.

Code: Bash  [Select][+][-]
  1. ld --shared --disable-runtime-pseudo-reloc -nostdlib --allow-shlib-undefined -Map test.map --image-base=0x409000 -o test2.dll -T link.ld
  2. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  3. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  4. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  5. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  6. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  7. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
  8. T:\msys64\mingw64\bin\ld.exe: error: 0-bit reloc in dll
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

paule32

  • Hero Member
  • *****
  • Posts: 516
  • One in all. But, not all in one.
okay... I am nearly the Goal...

with:
Code: Bash  [Select][+][-]
  1. fpc -dDLLEXPORT -dLANGDEU -n -B -O3 -Os -CD RTLLib.pas
  2. dlltool --input-def rtllib_dll.def --dllname rtllib.dll --output-lib librtllib_dll.a
  3. fpc -dDLLIMPORT -dLANGDEU -n -B -O3 -Os test.pas
  4. strip test.exe
  5. strip rtllib.dll
  6.  
  7. fpc -dDLLEXPORT -dLANGDEU -dCPU64 -n -B -O3 -Xe -Os -Cg -a -al -Anasmwin64 test.pas
  8. nasm.exe -f win64 -o test.o -w-orphan-labels test.s
  9.  
  10. ld -nostdlib -Map test.map -o test2.exe -T link.ld
I get a working executable.
MS-IIS - Internet Information Server, Apache, PHP/HTML/CSS, MinGW-32/64 MSys2 GNU C/C++ 13 (-stdc++20), FPC 3.2.2
A Friend in need, is a Friend indeed.

 

TinyPortal © 2005-2018