Discussion:
bootstrap-linux patches for cross compilation to arm
James Bond
2012-07-28 12:18:43 UTC
Permalink
Hi,

This is the patch to make bootstrap linux to cross compile successfully to
arm target.
This patch is based on pikhq's commit a0a06ab5329cbcfbb088fbe490c4363043a1216a
(the latest as of today).

I've successfully created a working rootfs and native toolchain from x86-64
host with this. My host gcc is 4.6.2 if it matters.
The changes are minimal and intended only to get the cross working, I
didn't try to optimise anything.

What was fixed:
- change linux-musl to linux-musleabi for arm target
- add host_configargs="LIBS=-lc" and --with-stage1-libs=-lc for native
gcc/binutils compile so that they don't pull in *printf from libiberty
(which segfaults).
- add linux-arm.config

Some known issues:
a) musl version as configured is at 0.9.2 but with arm it won't boot with
0.9.2 (busybox segfaults), you need to get the latest git master, make a
tarball out of it and rename it to musl-0.9.2.tar.gz in the "src"
directory.
b) kernel compile is commented out - it doesn't work out of the box. It
kind of works but stops near then end with missing symbols. If one then
re-do the process (issue another make in the kernel directory) it then
continues to completion. The produced kernel/modules works fine.
c) the kernel config for arm is configured based on versatible emulation
(because that's what I use for qemu at the moment).

Got a lot of help from John and Isaac to get this going, so thanks to both
of you.

This is my first post to the mailing list, so you feel this kind of stuff
is out of topic, my apology and lesson learnt.

cheers!
Rich Felker
2012-07-28 12:54:21 UTC
Permalink
Post by James Bond
- add host_configargs="LIBS=-lc" and --with-stage1-libs=-lc for native
gcc/binutils compile so that they don't pull in *printf from libiberty
(which segfaults).
Do you have any idea why this is needed? Are they always pulled in
(and just don't segfault on other archs), or is pulling them in
arm-specific?
Post by James Bond
- add linux-arm.config
a) musl version as configured is at 0.9.2 but with arm it won't boot with
0.9.2 (busybox segfaults), you need to get the latest git master, make a
tarball out of it and rename it to musl-0.9.2.tar.gz in the "src"
directory.
Do you know which bugfix solved this? It would be nice to mention in
the 0.9.3 release notes/announcement (hopefully in the next few days).
Post by James Bond
This is my first post to the mailing list, so you feel this kind of stuff
is out of topic, my apology and lesson learnt.
Welcome to the list. This type of contribution to the list is
perfectly acceptable.

Rich
John Spencer
2012-07-28 13:54:58 UTC
Permalink
Post by Rich Felker
Post by James Bond
- add host_configargs="LIBS=-lc" and --with-stage1-libs=-lc for native
gcc/binutils compile so that they don't pull in *printf from libiberty
(which segfaults).
Do you have any idea why this is needed? Are they always pulled in
(and just don't segfault on other archs), or is pulling them in
arm-specific?
i experienced similar things on sabotage. ARM is for some reason pulling
in more of libiberty as other archs.
some of them have conflicting prototypes with libc.

https://github.com/rofl0r/sabotage/blob/master/pkg/stage0_gcc4 :

for i in strsignal putenv random setenv strstr strtod strtol strtoul; do
culprit=libiberty/$i.c
rm $culprit
touch $culprit
done
Post by Rich Felker
Post by James Bond
- add linux-arm.config
a) musl version as configured is at 0.9.2 but with arm it won't boot with
0.9.2 (busybox segfaults), you need to get the latest git master, make a
tarball out of it and rename it to musl-0.9.2.tar.gz in the "src"
directory.
Do you know which bugfix solved this? It would be nice to mention in
the 0.9.3 release notes/announcement (hopefully in the next few days).
https://github.com/rofl0r/sabotage/blob/master/pkg/musl

patch -p1 < "$K/musl-0.9.2-arm_init.patch" || exit 1
patch -p1 < "$K/musl-0.9.2-arm_sigsetjmp.patch" || exit 1
patch -p1 < "$K/musl-0.9.2-longjmp.patch" || exit 1
patch -p1 < "$K/musl-0.9.2-rtld.patch" || exit 1
patch -p1 < "$K/musl-0.9.2-sendmsg.patch" || exit 1
patch -p1 < "$K/musl-0.9.2-getservbyname.patch" || exit 1


busybox needs another fix, as described also on the musl wiki FAQ
https://github.com/rofl0r/sabotage/blob/master/pkg/busybox

# --sort-section renders busybox unusable on ARM:
http://sourceware.org/bugzilla/show_bug.cgi?id=14156
sed -i 's,SORT_SECTION=,SORT_SECTION= #,' scripts/trylink
James Bond
2012-07-28 14:42:21 UTC
Permalink
This post might be inappropriate. Click to display it.
Rich Felker
2012-07-28 20:37:03 UTC
Permalink
Post by James Bond
Post by Rich Felker
Post by James Bond
- add host_configargs="LIBS=-lc" and --with-stage1-libs=-lc for native
gcc/binutils compile so that they don't pull in *printf from libiberty
(which segfaults).
Do you have any idea why this is needed? Are they always pulled in
(and just don't segfault on other archs), or is pulling them in
arm-specific?
This seems to be a problem in arm only. Unpatched bootstrap will build
cross x86-64 --> x86 rootfs and native toolchain fine, no problem.
The problem so far looks like this: some of the helper functions in libgcc
raises exceptions; and the code for these exceptions in libc (also musl).
But when using static libc, libc is linked in first before libgcc, thus
libgcc's dependencies on libc can't be resolved unless we add "-lc" at the
end.
Are you sure this is how the workaround is working? Adding -lc is most
likely to take place at the beginning, not the end. Default libs
provided by the compiler come last.
Post by James Bond
One can easily exhibit the same problem using musl-cross too - just make
sure that musl-cross build a toolchain with static musl libc (instead of
the default dynamic libc). Then compile "#include <stdio.h> void main() {
printf("hello %d\n"); }" with "arm-linux-musleabi -o hello hello.c" --- you
will get a host of unsatisfied dependency errors for raise, abort, etc
basically the stack unwinding stuff. The problem is down the chain printf
uses division, and division is done in libgcc and can raise exception, thus
the need for the stack unwinding code. To get it to compile, I found that I
need to do "arm-linux-musleabi -o hello hello.c -lc" instead.
This is stupid; there's no reason for the division to raise signals or
generate exceptions. Integer division by zero results in undefined
behavior, so libgcc can just do nothing special when it happens. Or it
could just execute an instruction that will raise a synchronous signal
(like an illegal opcode) rather than making library calls.

Floating point division by zero has well-defined results and raises a
floating point exception on implementations that support floating
point exceptions, but ARM EABI does not support them, and therefore
there's nothing special to be done (and even if there were, it would
not involve signals or C++ exceptions, just raising flags).

It would be really nice to fix this issue at the gcc level since it's
significantly bloating applications with code that do not, and should
not, need.
Post by James Bond
The end result is without adding those parameters, libiberty configure will
fail to detect that musl has *printf (because compilation fails), and thus
pulls in its own version (which crash but that's totally out of topic
here).
I see. That makes sense.

Rich
James Bond
2012-07-30 01:14:46 UTC
Permalink
Post by Rich Felker
Are you sure this is how the workaround is working? Adding -lc is most
likely to take place at the beginning, not the end. Default libs
provided by the compiler come last.
If I put that the beginning it won't work. I'm not sure how it works (the
previous explanation is just my guess - I should have said so earlier) but
it does solve problem - by doing this the compilation works and thus
libiberty configure detects *printf and uses musl's version correctly.
Post by Rich Felker
This is stupid; there's no reason for the division to raise signals or
generate exceptions. Integer division by zero results in undefined
behavior, so libgcc can just do nothing special when it happens. Or it
could just execute an instruction that will raise a synchronous signal
(like an illegal opcode) rather than making library calls.
Floating point division by zero has well-defined results and raises a
floating point exception on implementations that support floating
point exceptions, but ARM EABI does not support them, and therefore
there's nothing special to be done (and even if there were, it would
not involve signals or C++ exceptions, just raising flags).
It would be really nice to fix this issue at the gcc level since it's
significantly bloating applications with code that do not, and should
not, need.
Agreed.

A few people have been hit by this problem, I found at least two here:
- earlier problem (2009) with proposed hack
http://gcc.gnu.org/ml/gcc-help/2009-10/msg00332.html
- more recent problem (2012) with proposed patches
http://comments.gmane.org/gmane.comp.gcc.help/41025

The patch involves disabling exception in libgcc's libunwind. However I'm
not qualified to judge the correctness or suitability of these patches for
general purpose as they are targetting bare metal, while for our case we
are targetting musl.

BTW - Re-run bootstrap with the latest musl git master (as of yesterday)
and all seems to work fine.

cheers
James
Rich Felker
2012-07-30 04:21:17 UTC
Permalink
Post by James Bond
Post by Rich Felker
This is stupid; there's no reason for the division to raise signals or
generate exceptions. Integer division by zero results in undefined
[...]
Agreed.
- earlier problem (2009) with proposed hack
http://gcc.gnu.org/ml/gcc-help/2009-10/msg00332.html
- more recent problem (2012) with proposed patches
http://comments.gmane.org/gmane.comp.gcc.help/41025
The patch involves disabling exception in libgcc's libunwind. However I'm
not qualified to judge the correctness or suitability of these patches for
general purpose as they are targetting bare metal, while for our case we
are targetting musl.
The patch seems correct or at least suitable as a workaround. It looks
like this is a bug in gcc's code generation for arm; with exceptions
enabled, it seems to be generating code to throw an exception for
division by zero. There's no reason this should be done; integer
division by zero is UB not an exception you can catch and handle (even
in C++).

Rich

Continue reading on narkive:
Loading...