Cross-translating on 64 bit host for ARM: recompile with -fPIC and -m32

Issue #2218 new
created an issue

When cross-translating pypy 4.0.1 for 32-bit ARM on a x86-64 bit host (Ubuntu 14.04), the translation task:

pypy <path to rpython>/rpython/bin/rpython -Ojit --platform=arm --gcrootfinder=shadowstack --jit-backend=arm

fails with:

[platform:Error] /usr/bin/ld: /tmp/usession-release-4.0.1-59/rpython/translator/c/src/signals.o: relocation R_X86_64_32 against `pypysig_counter' can not be used when making a shared object; recompile with -fPIC [platform:Error] /tmp/usession-release-4.0.1-59/rpython/translator/c/src/signals.o: error adding symbols: Bad value [platform:Error] collect2: error: ld returned 1 exit status

when I add the -fPIC, the error changes to:

translation:ERROR] OSError: Cannot load library /tmp/usession-release-4.0.1-60/shared_cache/ /tmp/usession-release-4.0.1-60/shared_cache/ wrong ELF class: ELFCLASS64

Finally, The attached patch adds -m32 to args_for_shared() and get_shared_only_compile_flags(), which which fixes the problem for me.

The patch is hackish - could someone please advise on what the correct solution would look like?

Comments (12)

  1. Armin Rigo

    This is not supported: the docs explicitly say that you need a 32-bit host to cross-compile to a 32-bit target. You might indeed work around it by adding "-m32" here and there, but it is untested. (Your patch appears to add "-m32" in other situations too; wouldn't that cause endless amounts of troubles?)

  2. mzakharo reporter

    I am not sure about endless amounts of troubles - I was able to successfully cross-translate and build all cffi modules on 64 bit host without any further troubles with the above patch.

    Hopefully this helps someone else who wishes to use 64 bit hosts for cross-translating!

  3. mzakharo reporter

    agreed - there must be a way to automatically detect cross-translation on 64-bit host and add -m32 dynamically. Any ideas on how this would look like?

  4. Armin Rigo

    I'll stand on my position that cross-compiling to a 32-bit target from a 64-bit host gives highly nonsensical code even if translation appears to work, which it should not. There are good reasons. I may be wrong, but I have a large amount of doubts. For example, what does "sys.maxint" say in the compiled pypy?

    EDIT: in that case you're supposed to run translation from a 32-bit Python calling a 32-bit gcc. Maybe a way to call the correct gcc is to set CFLAGS='-m32'. You still need a 32-bit Python. Cross-translation is basically not tested at all, and we run 32-bit Linux translations inside full 32-bit installations (with chroot), but I'm sure there should be a way like that.

  5. mzakharo reporter

    Compiled pypy returns 2147483647 for sys.maxint. How do I run it through the entire suite of tests to make sure it is Kosher?
    I cross-translated using 32-bit pypy.
    Someone had to set '-m32' when calling HOST's gcc only, since my arm-gcc does not understand this flag.

  6. squeaky

    My 3 cents. I do cross-translation on x86-64 to i686 regularly. I use 32 bit CPython and multilib GCC to run translation and just add -m32 to both CFLAGS, CPPFLAGS and LDFLAGS. I dont need any patches in my case and it just works.

  7. Armin Rigo

    I would create a script called "gcc" which invokes the original gcc with an extra arg, "-m32". Then I'd add this script in my path only when I'm about to use the 32-bit Python. This is similar to CFLAGS, but it will (probably) not be used inside the arm sandbox too; only outside.

  8. Log in to comment