Cross compile from linux for mingw32 don't init the
ctors from crtend.o!
Every 'throw' in a program crashes with a "NULL-
Pointer read" in function __cxa_throw.
>>> Source line: gcc-3.3.1-20030804-1/libstdc++-
v3/libsupc++/eh_throw.cc:64 >>>
header->unexpectedHandler = __unexpected_handler;
<<< snip <<<
"__unexpected_handler" is a macro to
variable "__w32_sharedptr_unexpected", and there was
not init. Internal
function "_w32_sharedptr_initialize" was not called
before main starts.
This is the standard function tree, started from a
section .ctors in crtend.o:
__reg_frame_ctor
__do_frame_init
__w32_sharedptr_initialize
__register_frame_info
Problem is, that "*crtend.o (.ctors)" in linker script
does not include the function pointer
to "__reg_frame_ctor". With other words: The default
linker script from mingw32 not loads contructors from
crtend.o.
>>> cat sample.cc >>>
int main(void)
{
try {
throw "End!";
} catch (...) {
return 1;
}
return 0;
}
<<< end cat <<<
Build it with linker map
i686-pc-mingw32-g++ -Wl,-M -Wl,--verbose -o
sample.exe sample.cc
See the emtpy section .ctors for crtend.o:
>>> old bad map file >>>
0x00406c80
__CTOR_LIST__ = .
0x00406c80 0x4 LONG 0xffffffff
*(EXCLUDE_FILE(*crtend.o) .ctors)
*(.ctor)
*(SORT(.ctors.*))
*crtend.o(.ctors)
0x00406c84 0x4 LONG 0x0
0x00406c88
___DTOR_LIST__ = .
<<< snip map <<<
With my patch shows good, for sample:
>>> new good map file >>>
0x00406c80
__CTOR_LIST__ = .
0x00406c80 0x4 LONG 0xffffffff
*(EXCLUDE_FILE(*crtend.o) .ctors)
*(.ctor)
*(SORT(.ctors.*))
*(.ctors)
.ctors 0x00406c84
0x4 /home/hn/CoLinux/mingw32/lib/gcc-lib/i686-pc-
mingw32/3.3.1/crtend.o
0x00406c88 0x4 LONG 0x0
0x00406c8c
___DTOR_LIST__ = .
<<< snip map <<<
Versions:
Build system: i686-pc-linux
Build cross tool chain with:
gcc-Version 3.3.1 (SuSE Linux)
GNU ld version 2.14.90.0.5 20030722 (SuSE Linux)
Used parameters for build Binutils:
./configure --prefix=/home/user/mingw32 --
target=i686-pc-mingw32
make
make install
Used parameters for build Compiler:
./configure -v --prefix=/home/user/mingw32 \
--target=i686-pc-mingw32 \
--with-headers=/home/user/mingw32/i686-pc-
mingw32/include \
--with-gnu-as \
--with-gnu-ld \
--without-newlib \
--disable-multilib
make LANGUAGES="c c++"
make LANGUAGES="c c++" install
Target system: i686-pc-mingw32
# i686-pc-mingw32-gcc -v
Reading specs from ./../lib/gcc-lib/i686-pc-
mingw32/3.3.1/specs
Configured with: /home/hn/CoLinux/build/co-devel-
tmp/gcc-3.3.1-20030804-1/configure -v --
prefix=/home/hn/CoLinux/mingw32 --target=i686-pc-
mingw32 --with-headers=/home/hn/CoLinux/mingw32/i686-
pc-mingw32/include --with-gnu-as --with-gnu-ld --
without-newlib --disable-multilib
Thread model: single
gcc version 3.3.1 (mingw special 20030804-1)
# i686-pc-mingw32-ld -v
GNU ld version 2.15.91 20040904
# Mingw from source
binutils-2.15.91-20040904-1-src.tar.gz
Same problem if using this versions:
binutils-2.16.91-20050827-1-src.tar.gz (is the last,
I think)
gcc-g++-3.4.4-20050522-1-src.tar.gz
Henry
patch binutils-2.15.91-20040904-1 to load ctors from crtend.o
patch for binutils-2.16.91
Logged In: YES
user_id=579204
Added patch for binutils-2.16.91-20050827-1, and I mailed
to binutils@sourceware.org (perhaps wrong channel here?)
Henry
Logged In: YES
user_id=579204
Misterous. In current source of binutils the linker script
was unchanged for "ctors from crtend.o":
http://sourceware.org/cgi-
bin/cvsweb.cgi/src/ld/scripttempl/pe.sc?rev=1.15&content-
type=text/x-cvsweb-markup&cvsroot=src
I'm not shure, who changed the linkerscript
ld/scripttempl/pe.sc with the not working line
*crtend.o (.ctors);
-^^^^^^^^----------
Why was changed in mingw32 source?
And who would change it back?
Henry
Logged In: YES
user_id=11494
I don't understand why *crtend.o(.ctors) syntax doesn't
work on cross-build, but it does on native builds. I'll
change it to *(.ctors) for next mingw release after a bit
more testing.
BTW the reason for all the crtend.o business is to make
absolutely sure that the crtend.o ctor is run first,
even if user has set priority of other ctors using
init_priority attribute or asm. This is not necessary for
stock FSF gcc, because the crtend/crtbegin objects are not
specified in mingw32.h target file of stock sources
Danny
Logged In: YES
user_id=579204
Thanks, for replay.
I'm also very confused, because have tested it in many
build systems with and without filename matching, and also
with native build.
Yes, only the cross build is the problem.
The "EXCLUDE_FILE" works and the include dosn't?
I will try to debuging the filename parsing next times.
First, it was hard enough to find the problem. Normal, I
trust the build system and search only in my sources. ;)
Many thanks for your mingw32 project!
Henry
Logged In: YES
user_id=579204
binutils-2.16.91-20050827-1/ld/ldlang.c(671):
if (fnmatch (file_spec, f->filename, FNM_FILE_NAME) == 0)
The function walk_wild() use fnmatch() with FNM_FILE_NAME,
and in this case the '*' in names don't match '/'.
See also info ld, section 'Input Section Wildcard Patterns':
http://sources.redhat.com/binutils/docs-2.12/ld.info/Input-
Section-Wildcards.html
---
binutils-2.16.91-20050827-1/ld/ldlang.c(184):
skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
The EXCLUDE_FILE in linker script use fnmatch with
option '0'. That's why exclude works and include not.
---
And why native builds wors?
Is function fnmatch perhaps emulated? And perhaps is
FNM_FILE_NAME not supported?
If I build from linux for win32, I use fnmatch from glibc.
Henry
test for fnmatch, simulate link parms
Logged In: YES
user_id=579204
This error was fixed in binutils 2.16.91-20060119-1
Thanks,
Henry