-mmacosx-version-min=10.6 behavior with additional libgcc_s.1.dylib's

223 views
Skip to first unread message

Jack Howarth

unread,
Feb 4, 2011, 7:28:26 AM2/4/11
to xcode...@lists.apple.com, darwi...@lists.apple.com, kle...@apple.com, ia...@gcc.gnu.org, mike...@comcast.net
Nick,
Can you please confirm that the following analysis of the limitations
for handling additional physcial copies of libgcc_s.1.dylib by the linker
and dyld under -mmacosx-version-min=10.6 is correct? In FSF gcc 4.5, in
order to access all of the additional symbols added to the FSF libgcc_s.1.dylib
after the symbol set for libgcc_s.10.5.dylib was defined, versioned copies
of libgcc_ext.10.4.dylib and libgcc_ext.10.5.dylib were introduced. These were
stubs to the FSF libgcc_s.1.dylib which only exported those symbols not present
in the matching libgcc_s.10.4.dylib and libgcc_s.10.5.dylib. The linkage order
of -lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem was used for
both -mmacosx-version-min=10.5 and -mmacosx-version-min=10.6. This results in
a linkage order (as viewed by 'otool -L') of...

/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

In FSF gcc 4.6, in attempt to remove the /usr/lib/libgcc_s.1.dylib linkage for
-mmacosx-version-min=10.6, this linkage was changed to just..

-lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

so that 'otool -L' shows...

/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

However, while testing builds of xplor-nih (which contains shared libs built with -flat_namespace)
using FSF gcc 4.6, I discovered that the exception trackback could become broken and would crash
out in the FSF libgcc_s.1.dylib's unwinder.
Comparing how Apple gcc 4.2.1 and clang produced linkages under -mmacosx-version-min=10.6, I
noticed that both precedes -lgcc with -lSystem. However, for FSF gcc 4.6 under -mmacosx-version-min=10.6,
using just...

-lgcc_ext.10.5 -lSystem -lgcc -no_compact_unwind -lSystem

which retains the linkage order (as seen by 'otool -L') of...

/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

was insufficient to eliminate these exception traceback failures when using -flat_namespace.
Only the linkage...

-lSystem -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

which produces the linkage order (as seen by 'otool -L') of...

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.10)
/sw/lib/gcc4.6/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

eliminates the exception traceback failures with -flat_namespace.
It is my belief that it is an incorrect assumption that, under -mmacosx-version-min=10.6, the
stub mechanism alone will prevent the unexported symbols in the /sw/lib/gcc4.6/lib/libgcc_s.1.dylib
from being used by the darwin linker. In other words, for -mmacosx-version-min=10.6, any additional
copies of libgcc_s.1.dylib have to be treated the same as the -lgcc linkage and must be preceded by a
linkage on -lSystem to insure that its symbols are used. The fact that the /usr/lib/libgcc_s.*.dylib
files are all symlinks back to libSystem (which contains magic symbols for those in libgcc_s.10.4.dylib
and libgcc_s.10.5.dylib), makes me suspect that the stub mechanism of limiting the exported symbols
from additional physical copies of libgcc_s.1.dylib is insufficient alone to prevent the unexported
symbols in libgcc_ext.10.5.dylib from being used (hence the traceback into FSF gcc's libgcc_s.1.dylib's
unwinder) for -mmacosx-version-min=10.6.
Can you confirm that this analysis, that either the design of the linker and dylib for
-mmacosx-version-min=10.6 doesn't expect an additional physical linkage on another
libgcc_s.1.dylib before libSystem.dylib or that this is a bug in the handling of stubs in the
case -mmacosx-version-min=10.6, is correct? Thanks in advance for any advice.
Jack
ps I would also note that only the use of "-lSystem -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem"
causes the duplicate symbol for ___divdc3 is gotten from libSystem again and failures in the FSF gcc
gcc.dg/torture/builtin-math-7.c re-exposed (<rdar://problem/7457013> ___divdc3 slightly wrong).
Iain is resisting the proposed change to the linkage order for -mmacosx-version-min=10.6 because the
details of how the magic symbols in libgcc_s.*.dylib operate are undocumented. Any clarifications will
be greatly appreciated.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (Darwi...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/darwin-dev/darwin-dev-garchive-73044%40googlegroups.com

This email sent to darwin-dev-g...@googlegroups.com

Jack Howarth

unread,
Feb 4, 2011, 10:28:32 AM2/4/11
to xcode...@lists.apple.com, darwi...@lists.apple.com, kle...@apple.com, ia...@gcc.gnu.org, mike...@comcast.net
Nick,
Appended is a very simple test case that I found for PR47558 that demonstrates
the problem and the proposed fix.
Jack

The following works as a testcase for PR47558

test_main.c
--------------------------
void main (void)
{
extern int unwindcall(void);
int i;
i=unwindcall();
}
--------------------------

test_call.c
---------------------------
int unwindcall (void)
{
static __thread i;
i+i;
_Unwind_Resume ((void *)0);
return i;
}
----------------------------

./dist/bin/gcc -dynamiclib -o libtestcall.dylib -flat_namespace -undefined
suppress -single_module test_call.c
./dist/bin/gcc -o PR47558.exe test_main.c ./libtestcall.dylib

otool -L PR47558.exe
PR47558.exe:
libtestcall.dylib (compatibility version 0.0.0, current version 0.0.0)
/Users/howarth/dist/lib/libgcc_s.1.dylib (compatibility version 1.0.0,


current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
125.2.1)

./PR47558.exe
Abort

gdb ./PR47558.exe
GNU gdb 6.3.50-20050815 (Apple version gdb-1510) (Wed Sep 22 02:45:02 UTC 2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared
libraries .... done

(gdb) r
Starting program: /Users/howarth/PR47558.exe
Reading symbols for shared libraries +++. done

Program received signal SIGABRT, Aborted.
0x00007fff87c05616 in __kill ()
(gdb) bt
#0 0x00007fff87c05616 in __kill ()
#1 0x00007fff87ca5cca in abort ()
#2 0x00000001000147a6 in uw_init_context_1 (context=0x7fff5fbfe5d0,
outer_cfa=0x7fff5fbfe800, outer_ra=0x100003f75) at
../../../gcc/libgcc/../gcc/unwind-dw2.c:1265
(gdb)

For the testcase in Comment 56 using my proposed patch from Comment 45...

gcc-4 -dynamiclib -o libtestcall.dylib -flat_namespace -undefined suppress
-single_module test_call.c
gcc-4 -o PR47558.exe test_main.c ./libtestcall.dylib

otool -L ./PR47558.exe
./PR47558.exe:
libtestcall.dylib (compatibility version 0.0.0, current version 0.0.0)


/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
125.2.10)
/sw/lib/gcc4.6/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current
version 1.0.0)

gdb ./PR47558.exe
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000010
0x00007fff839d3c35 in _Unwind_Resume ()
(gdb) bt
#0 0x00007fff839d3c35 in _Unwind_Resume ()
#1 0x0000000100003f75 in unwindcall ()
#2 0x0000000100000f7b in main ()

Jack Howarth

unread,
Feb 4, 2011, 5:13:11 PM2/4/11
to Nick Kledzik, ia...@gcc.gnu.org, darwi...@lists.apple.com, xcode...@lists.apple.com, mike...@comcast.net
On Fri, Feb 04, 2011 at 10:55:36AM -0800, Nick Kledzik wrote:
> Jack,
>
> Normally, when the linker produces a final linked image, it records which dylib each undefined symbol was found at build time. Then, at runtime, dyld only looks for those undefined symbols in the specific dylibs recorded. When a -flat_namespace is used, the linker records "flat lookup" for which dylib the undefinded was found in. At runtime, dyld will search each loaded image in load order looking for those undefined symbols when referenced from that -flat_namespace image.
>
> Given the above, there are two things that can go wrong:
> 1) There is one over all chronological load order that is used when dyld searches for a symbol with flat lookup. The order of dependent libraries only matters if none of the dependent libraries have been already loaded. That is, you could have flat_namespace dylib A and dylib B. A links with dylib X and Y in that order while B links with Y and X in that order. At runtime, X and Y will be loaded in some order and that order defines how both A and B's undefined symbols are found. You can use DYLD_PRINT_LIBRARIES to see the actual load order of dylibs. You can use DYLD_PRINT_BINDINGS to see how all references are bound.
>
> 2) Mixing flat and two-level namespace dylibs can give unexpected results. Only the flat namespace dylibs can get their undefined symbols bound differently at runtime. All the other two-level namespace dylibs will continue to use what they recorded at build time. In the case of unwinding, that means two different unwinders could be in play and since they have different context pointers you can easily hand off an unwind context from one unwinder to another and boom.

Nick,
What confused me is how the unwinder symbols for FSF libgcc are ever accessed with the following linkage...

-lgcc_ext.10.5 -lSystem -lgcc -no_compact_unwind -lSystem

Since libgcc_ext.10.5.dylib is created as a stub only exporting those symbols from FSF libgcc_s.1.dylib which don't exist
in libgcc_s.10.5.dylib, we believed that the unwinder symbols in FSF libgcc_s.1.dylib would be invisible to the linker
even when -flat_namespace is used. Or are you saying that the -flat_namespace option allows dyld to look past the stub
of libgcc_ext.10.5 directly at all symbols contained in the FSF libgcc_s.1.dylib? If so, what would be the best approach
for linking here? I have suggested we adopt...

-lSystem -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

which flips linkage from...

/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)


/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

to

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

This prevents the FSF libgcc unwinder being accidentally accessed under -flat_namespace. It also has the effect
of having any overlapping symbols in libgcc_ext.10.5.dylib and libSystem (like ___divdc3) resolve from libSystem
(hence the failures we then see in gcc.dg/torture/builtin-math-7.c's execution test due to


<rdar://problem/7457013> ___divdc3 slightly wrong).

>
> What are you trying to accomplish? Does the libgcc_ext just have extra math stuff? Or are you trying to force the use of the gcc unwinder as well? If so, is this because of new gcc unwinder functionality? or just because you want to test the gcc unwinder?

We are trying to make -flat_namespace more bullet-proof so that the FSF unwinder is never accessed
by accident. FYI, xplor-nih is a mix of c, c++ and fortran which upstream builds on darwin entirely from
the FSF gcc compilers. The xplor-nih program's code is stored in a series of shared libraries all built
with -flat_namespace because they are used both from a standalone driver program (not currently linked
with -flat_namespace) as well as from within python and tcl as bundles.
In FSF gcc 4.5, we linked as...

-lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

for both -macosx_version_min=10.5 and -macosx_version_min=10.6 so that even under -flat_namespace, the FSF libgcc
unwinder was never accidentally used. My concern is that FSF gcc 4.6 currently only links that way for
-macosx_version_min=10.5 and use...

-lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

instead for -macosx_version_min=10.6. This worries me on a couple of issues...

1) Since we are not linking -lSystem before -lgcc, don't we risk pulling in symbols like ___enable_execute_stack
from /sw/lib/gcc4.6/lib/gcc/x86_64-apple-darwin10.6.0/4.6.0/libgcc.a under the FSF gcc 4.6 compiler? I would think
that the absence of either the initial -lgcc_s.10.5 or -lSystem linkage would expose the symbols from the -lgcc
linkage?

2) Since -flat_namespace has been long recommended for porting unix software under Mac OS X, the fact that
the current linkage in FSF gcc 4.6 can accidentally invoke the FSF libgcc unwinder if both the shared libs
and executable aren't all compiled with -flat_namespace is a concern. My experience has been that -flat_namespace
(when used) has only been applied to the shared library builds and not the executables.

Jack

>
> -Nick

Reply all
Reply to author
Forward
0 new messages