<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Thanks for hint. I have created ticket:</p>
<p><a class="moz-txt-link-freetext" href="https://gitlab.com/freepascal.org/fpc/source/-/work_items/41826">https://gitlab.com/freepascal.org/fpc/source/-/work_items/41826</a></p>
<div class="moz-cite-prefix">W dniu 22.07.2026 o 20:02, n7800 pisze:<br>
</div>
<blockquote type="cite"
cite="mid:1784743354.941298159@f328.i.mail.ru">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div class="cl-0u1zw232om">
<div>
<div>Perhaps it would be better to post this on the <a
href="https://gitlab.com/freepascal.org/fpc/source/-/work_items"
moz-do-not-send="true">FPC bug tracker</a>?</div>
<div> </div>
<div>Or on the "fpc-devel" mailing list.</div>
</div>
<br>
<div class="mail-quote-collapse">
<blockquote
style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px">
<div>
<div id="">
<div class="cl-gwbfz3ahak">
<div
class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr">
<div id="style_17847294010710600985_mr_css_attr">
<div
id="style_17847294010710600985_BODY_mr_css_attr">
<p>Hi,</p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">I suspect
that my first message was blocked
because I attached ODT document. Please
ignore duplicate if it show up.</span></span></span></p>
<p>I mentioned about this issue some time ago in
the topic about PasFLTK bindings which I made.
I decided to make dedicated thread because it
seems to be interesting.</p>
<p>So. I'm developing PasFLTK bindings for CFLTK
which is flatten C binding for major FLTK UI
framework written in C++. PasFLTK has two
modes, shared library which work perfectly
fine and experimental static linking.</p>
<p>Static linking has issues which I'm <span
lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">consistently</span></span></span> fixing.
Major problem is that C++ classes are not
initialized in proper way. Problem is not a
matter of "Static Initialization Order Fiasco"
because CFLTK/FLTK is designed to be static
linking for default (and that is how other
language bindings are using it). Problem is
how FPC LD linker prepare "startup" routines.
For example:</p>
<p>Class Fl_File_Chooser2.cxx has this public
variable:</p>
<p>const char
*Fl_File_Chooser::filesystems_label =
Fl::system_driver()->filesystems_label();</p>
<p>System_driver is not initialized yet so
filesystems_label become null which result
with access violations. Since I'm linux user I
started from this platform, working on this
with Claude AI (which amazed me how deeply he
can analyze binaries on low level). On linux,
fix was small and easy (for Claude, not for me
of course). LD linker prepare wrong init
structure and doesn't call the
__init_array_start in linux ELF standard. So
patch looks like that:<br>
</p>
<p>type<br>
TCtorProc = procedure(); cdecl;<br>
PCtorProc = ^TCtorProc;<br>
<br>
var<br>
__init_array_start: Byte; external name
'__init_array_start';<br>
__init_array_end: Byte; external name
'__init_array_end';<br>
<br>
procedure RunCppGlobalConstructorsLinux;<br>
var<br>
p, pend: PCtorProc;<br>
begin<br>
p := PCtorProc(@__init_array_start);<br>
pend := PCtorProc(@__init_array_end);<br>
while p < pend do<br>
begin<br>
if Assigned(p^) then<br>
p^();<br>
Inc(p);<br>
end;<br>
end; <br>
<br>
That small piece of code fixed everything and
static linking work like a charm on linux. I
have project (which I publish soon) totally
written as static linking and didn't notice
any new issues so far.</p>
<p>Now windows version. Here complication start.
First, build-in FPC linker is useless and
throw error:</p>
<p>Error: Failed reading coff file, invalid
section index while reading
C:\Users\vboxuser\Documents\CFLTKlibs\libcfltk.a(cfl_window.cpp.obj)<br>
<br>
I had to use -Xe flag which switch to external
ld.exe linker. But then I had DWARF errors
because LD support only up to 4 version and my
MinGW toolchain (MSYS2 on windows) is using
ver. 5. I had to call `strip --strip-debug` on
all *.a files (including some MinGW - e.g
libstd++.a).</p>
<p>Now, when binding are compiling fine, I fall
to the same problem with initialization as on
linux. I spent few evenings with Claude on
this. We compared objdump -h and extracted
objects on exactly the same demos written line
by line one using C (CFLTK) and second Free
Pascal. Since linux use ELF we get
__init_array_start, on windows PE - it looks
harder. LD.exe <span lang="en"
class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">delivered
with FPC is quite old and doesn't use
modern standard. Demo written in C and
linked by LD from toolchain has correct
.ctors and __CTOR_LIST__ which FPC
ld.exe is missing (in fact, filling it
incorrectly). Tried using
-FD"C:\msys64\mingw64\bin" which load
ld.exe from MinGW toolchain but this
result with dozens errors:</span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">C:\msys64\mingw64\bin\ld.exe:
C:\programowanie\lazarus\fpc\3.2.2\units\x86_64-win64\rtl\sysutils.o:
illegal relocation type 0 at address 0<br>
C:\msys64\mingw64\bin\ld.exe:
C:\programowanie\lazarus\fpc\3.2.2\units\x86_64-win64\rtl\math.o:
illegal relocation type 0 at address 0</span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">Claude also
compared rust bindings for CFLTK because
it also use static linking. They had
also problems and are stick to the
specific toolchain. But there problem
was easier to fix because Rust linker
correctly linking crt2.o and has own
guardians rsbegin.o and rsend.o (</span></span></span><span
lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">equivalent
of </span></span></span>crtbegin.o
and crtend.o) which are missing in FPC ld
linker.</p>
<p>Finally I get it working with Claude but this
require reorganize *.a and C++ objects with
--globalize-symbol and this solution is not
acceptable for me because it require <span
lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">engagement
everytime when something changed in
CFLT/FLTK source or even in MinGW.</span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">I'll be not
writting anymore and just attach summary
of our work which I asked Claude to
write in short. It has more technical
details. To sum up. Is there any plans
to upgrade LD linker or exists any alpha
/ beta of upcoming release? </span></span></span><span
lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">The
difference between FPC ld and GCC ld is
almost 10 years. </span></span></span><span
lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">I read
somewhere that FPC is not designed to
link C++ (only C) but as we can see, it
could be just small step to make it
possible and that open huge door. </span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">Below is
Claude's summary.</span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">Regards,
Dibo.</span></span></span></p>
<p><span lang="en" class="HwtZe_mr_css_attr"><span
class="jCAhz_mr_css_attr ChMk0b_mr_css_attr"><span
class="ryNqvb_mr_css_attr">Environment:<br>
<br>
Free Pascal Compiler 3.2.2, Windows
target x86_64-win64<br>
<br>
Bundled linker:
C:\programowanie\lazarus\fpc\3.2.2\bin\x86_64-win64\ld.exe
— GNU ld (GNU Binutils) 2.28<br>
<br>
Comparison linker: ld.exe from MSYS2
mingw-w64-x86_64-binutils package,
located at C:\msys64\mingw64\bin\ld.exe
— GNU ld (GNU Binutils) 2.46.1<br>
<br>
GCC/G++ used to build FLTK, CFLTK,
and the comparison C++ demo: 16.1.0
(MSYS2 mingw-w64-x86_64-gcc, reported as
"GCC 16.1.0"<br>
<br>
FLTK version: 1.4.5, CFLTK version:
1.5.23<br>
<br>
Root cause identified: FPC 3.2.2's
bundled ld.exe fails to correctly merge
.ctors input sections (containing C++
global constructor pointers) from object
files compiled by a modern GCC (16.1.0,
MinGW-w64/MSYS2) into the final
__CTOR_LIST__ array — even though the
linker script (identical KEEP(*(.ctors))
rule, confirmed via ld.exe --verbose on
both linkers) is present in both the old
bundled ld.exe and a current MSYS2
ld.exe.<br>
<br>
Evidence:<br>
<br>
A raw hex dump of __CTOR_LIST__ in
an FPC-linked executable (with 10 real
global constructors from a
statically-linked FLTK/CFLTK library
present and confirmed via nm) shows:
sentinel (-1) immediately followed by
terminator (0) — zero constructor
pointers, despite the constructor
functions (_GLOBAL__sub_I_*) physically
existing in the binary.<br>
<br>
The same source compiled and linked
natively with g++.exe/current MSYS2
ld.exe produces a fully populated
__CTOR_LIST__ with all 10 pointers
correctly resolved to the matching
_GLOBAL__sub_I_* addresses.<br>
<br>
Attempting to relink the FPC-built
binary with the current MSYS2 ld.exe
(via -FD<path>) fails with illegal
relocation type 0 / invalid section
index errors on FPC's own RTL object
files (sysutils.o, math.o) — indicating
FPC's internal object emitter and modern
binutils have diverged in mutually
incompatible ways. rtl\sysutils.o:
illegal relocation type 0 at address 0
etc<br>
<br>
The input .o files from the affected
FLTK library use COMDAT sections
(LINK_ONCE_DISCARD) extensively
(confirmed via objdump -h), which may be
related to how the old ld.exe mishandles
their .ctors content during merging —
this is hypothesis<br>
<br>
Consequently, statically linking
modern C++ libraries (FLTK/CFLTK, built
with current MinGW-w64/GCC) into an
FPC/Lazarus Windows executable silently
drops all global C++ constructors,
causing use of uninitialized static
objects downstream (observed as
intermittent access violations depending
on which code paths touch affected
statics).<br>
<br>
Workaround currently used: manually
enumerating _GLOBAL__sub_I_* symbols via
nm on the linked (even if crashing)
executable, globalizing their linkage
scope via objcopy --globalize-symbol
(they are emitted as local/t symbols),
and generating a small Pascal unit that
calls them all explicitly at program
startup. This resolves some but not all
downstream issues, suggesting missing
constructor invocation is necessary but
possibly not sufficient — full
mainCRTStartup context
(TLS/locale/guard-variable state) may
also matter for some lazily-initialized
C++ singletons. - this is last
hypothesis<br>
<br>
Question for the list: Is there a
newer/beta ld.exe (or plan to update the
bundled binutils) for the Windows FPC
toolchain that correctly handles
.ctors/COMDAT sections as emitted by
current GCC, without breaking
compatibility with FPC's own object file
emitter?</span></span></span></p>
<p> </p>
</div>
<div>_______________________________________________<br>
fpc-pascal maillist - <a
href="mailto:fpc-pascal@lists.freepascal.org"
moz-do-not-send="true"
class="moz-txt-link-freetext">fpc-pascal@lists.freepascal.org</a><br>
<a
href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal"
moz-do-not-send="true"
class="moz-txt-link-freetext">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal</a></div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</body>
</html>