#887 *crtend.o(.ctors) not load on linux cross gcc (__cxa_throw)

closed-fixed
Danny Smith
binutils (105)
2006-01-31
2005-12-31
Henry N.
No

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

Discussion

1 2 > >> (Page 1 of 2)
  • Henry N.
    Henry N.
    2005-12-31

    patch binutils-2.15.91-20040904-1 to load ctors from crtend.o

     
  • Henry N.
    Henry N.
    2006-01-12

    • summary: *crtend.o(.dtors) not load on linux cross gcc (cxa_throw) --> *crtend.o(.ctors) not load on linux cross gcc (cxa_throw)
     
  • Henry N.
    Henry N.
    2006-01-12

    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

     
  • Henry N.
    Henry N.
    2006-01-12

    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

     
  • Danny Smith
    Danny Smith
    2006-01-13

    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

     
  • Henry N.
    Henry N.
    2006-01-13

    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

     
  • Henry N.
    Henry N.
    2006-01-16

    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

     
  • Henry N.
    Henry N.
    2006-01-16

    test for fnmatch, simulate link parms

     
    Attachments
  • Henry N.
    Henry N.
    2006-01-30

    • status: open --> closed
     
1 2 > >> (Page 1 of 2)