Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling with arm-linux-androideabi-clang instead of just clang creates an executable that gives runtime error #7232

Closed
Grimler91 opened this issue Aug 1, 2021 · 8 comments · Fixed by #7856
Labels
arch-arm Issue reproducible on packages compiled for ARM bug report Something is not working properly

Comments

@Grimler91
Copy link
Member

Problem description

On arm (and i686?), compiling a program with the arm-linux-androideabi-clang symlink gives:

error: Android 5.0 and later only support position-independent executables

Compiling with just clang or clang-12 instead works fine. This is the same problem as described in 93fca0f, where I incorrectly thought it was a perl specific issue.

I think/am guessing that the issue started with llvm 12. Will test llvm 11 to see if that works tomorrow.

Steps to reproduce

Create a temporary directory and a small test program:

mkdir -p $TMPDIR/test
cd $TMPDIR/test
cat <<- EOF > conftest.c
#include <stdio.h>
int
main (void)
{
FILE *f = fopen ("conftest.out", "w");
  return ferror (f) || fclose (f) != 0;
  return 0;
}
EOF

and then compile and run it:

arm-linux-androideabi-clang -o conftest conftest.c
./conftest
echo $?

With arm-linux-androideabi-clang we get exit status 1 and the PIE error when running the program.
This small example is what autoconf uses to determine if the build is a cross compilation ([1], [2]), which is where I noticed the problem today.

Expected behavior

Program should compile and run without errors.

Additional information

Application version:
0.117
Packages CPU architecture:
arm
Subscribed repositories:
# sources.list
deb https://grimler.se/termux-packages-24 stable main
# game-repo (sources.list.d/game.list)
deb https://grimler.se/game-packages-24 games stable
# science-repo (sources.list.d/science.list)
deb https://grimler.se/science-packages-24 science stable
# unstable-repo (sources.list.d/unstable.list)
deb https://grimler.se/unstable-packages unstable main
Updatable packages:
All packages up to date
Android version:
11
Kernel build information:
Linux localhost 3.4.113-gf598eadb8e3 #1 SMP PREEMPT Sun Aug 1 18:01:37 CEST 2021 armv7l Android
Device manufacturer:
samsung
Device model:
SM-T800

@buttaface do you have an idea off the top of your head where/why the problem occurs?

@Grimler91 Grimler91 added arch-arm Issue reproducible on packages compiled for ARM bug report Something is not working properly labels Aug 1, 2021
@finagolfin
Copy link
Member

I have seen these LLVM compilers run in different modes depending on which symlink they're called with- you can see an example of this with the Swift package and it's various executable symlinks- so that would be my guess.

It may be easy to diagnose: add the -v flag to each of those two invocations and compare the list of internal compiler and linker flags each produces.

@Grimler91
Copy link
Member Author

You are right, with arm-linux-androideabi-clang it uses the triple armv4t-unknown-linux-android instead of armv7-unknown-linux-android24, full diff from {arm-linux-androideabi-,}clang -v outputs look something like:

--- clang.txt	2021-08-01 22:25:33.151881616 +0200
+++ arm-clang.txt	2021-08-01 22:26:23.399881641 +0200
@@ -1,10 +1,10 @@
 clang version 12.0.0
-Target: armv7a-unknown-linux-android24
+Target: arm-unknown-linux-android
 Thread model: posix
 InstalledDir: /data/data/com.termux/files/usr/bin
  "/data/data/com.termux/files/usr/bin/clang-12"
  -cc1
- -triple armv7-unknown-linux-android24
+ -triple armv4t-unknown-linux-android
  -emit-obj
  -mrelax-all
  --mrelax-relocations
@@ -14,19 +14,26 @@
  -discard-value-names
  -main-file-name conftest.c
  -mrelocation-model pic
- -pic-level 2
- -pic-is-pie
+ -pic-level 1
+ -fhalf-no-semantic-interposition
  -mframe-pointer=all
  -fno-rounding-math
  -mconstructor-aliases
- -target-cpu generic
+ -target-cpu arm7tdmi
+ -target-feature +soft-float
  -target-feature +soft-float-abi
- -target-feature +vfp2
- -target-feature +vfp2sp
- -target-feature +vfp3
- -target-feature +vfp3d16
- -target-feature +vfp3d16sp
- -target-feature +vfp3sp
+ -target-feature
+ -vfp2
+ -target-feature
+ -vfp2sp
+ -target-feature
+ -vfp3
+ -target-feature
+ -vfp3d16
+ -target-feature
+ -vfp3d16sp
+ -target-feature
+ -vfp3sp
  -target-feature
  -fp16
  -target-feature
@@ -47,14 +54,29 @@
  -fp-armv8sp
  -target-feature
  -fullfp16
- -target-feature +fp64
- -target-feature +d32
- -target-feature +neon
+ -target-feature
+ -fp64
+ -target-feature
+ -d32
+ -target-feature
+ -neon
  -target-feature
  -crypto
  -target-feature
+ -dotprod
+ -target-feature
  -fp16fml
+ -target-feature
+ -bf16
+ -target-feature
+ -mve
+ -target-feature
+ -mve.fp
+ -target-feature
+ -fpregs
+ -target-feature +strict-align
  -target-abi aapcs-linux
+ -msoft-float
  -mfloat-abi soft
  -fallow-half-arguments-and-returns
  -fno-split-dwarf-inlining
@@ -83,9 +105,8 @@
  /data/data/com.termux/files/usr/include/arm-linux-androideabi
  /data/data/com.termux/files/usr/include
 End of search list.
- "/data/data/com.termux/files/usr/bin/ld"
+ "/data/data/com.termux/files/usr/bin/arm-linux-androideabi-ld"
  --sysroot=/data/data/com.termux/files
- -pie
  -z noexecstack
  -EL
  --warn-shared-textrel
@@ -93,7 +114,7 @@
  -z relro
  -z max-page-size=4096
  -X
- --hash-style=gnu
+ --hash-style=both
  --enable-new-dtags
  -rpath=/data/data/com.termux/files/usr/lib
  --eh-frame-hdr

Then I know approximately what to look for in the llvm code at least

@finagolfin
Copy link
Member

It looks like that arm refers to the old Android armeabi arch that has since been deprecated. We shouldn't use that and only have one for the still supported armv7 arch, which the regular clang correctly defaults to.

@Grimler91
Copy link
Member Author

Changing the prefix of the clang programs from arm-linux-androideabi- to arm-linux-android24- makes it work. The 24 seems crucial, *androideabi24* and armv7a-*-android24* makes it work.

I have not been able to locate a place where it can be changed in the source code, yet

@enh-google
Copy link

It looks like that arm refers to the old Android armeabi arch that has since been deprecated. We shouldn't use that and only have one for the still supported armv7 arch, which the regular clang correctly defaults to.

yes, that's correct.

it shouldn't matter though. no-one needs armv4t in 2021 --- even the Cortex-M microcontrollers are better than that! :-)

@truboxl
Copy link
Contributor

truboxl commented Oct 25, 2021

Based on https://android.googlesource.com/platform/ndk/+/refs/heads/master/build/tools/make_standalone_toolchain.py#89

Specifically make_clang_target() and make_clang_scripts()

This seems like Google's doing rather than LLVM. Guess we have to specifically package it ourselves...

@enh-google
Copy link

Based on https://android.googlesource.com/platform/ndk/+/refs/heads/master/build/tools/make_standalone_toolchain.py#89

Specifically make_clang_target() and make_clang_scripts()

This seems like Google's doing rather than LLVM. Guess we have to specifically package it ourselves...

well, it depends what you're actually trying to do here. that line in our script is to avoid this problem --- we wanted to silently move anyone who had "arm-" in a build script over to "armv7-". our theory being that since it's unlikely that anyone's deliberately targeting armv4t we could save them the trouble of search-and-replace'ing arm- to armv7- without actually losing any compatibility in practice.

but if you actually build for armv4t, that implies that you're building for pre-jellybean, which means that you don't support PIC/PIE. so clang should default to no PIC/PIE in that case, which is what you were indeed seeing in the diff at the top of this bug:

- -pic-level 2
- -pic-is-pie
+ -pic-level 1

(where - is armv7 and + is arm.)

the problem with that is that Android had a hard switchover in lollipop ("Android 5.0") --- it can't run non-PIE executables (as it says in the error message at the top of this bug). so although "compile for armv4t because it's the lowest option" might sound more compatible, it's actually not compatible with any device that anyone's still using in 2021.

TL;DR: don't build with "arm-" prefixed toolchains in 2021 (unless you really are targeting only ancient devices, and are also building a newer binary for any >= lollipop devices), and always use "armv7-" prefixed toolchains.

@Grimler91 --- you can do the "android24" trick you mentioned above, but that's more restrictive than necessary --- you're basically saying "assume a crappy old CPU, but a modern OS". if you're going to assume API level 24, you should definitely take advantage of armv7, since the CDD required that all devices running that version of the OS had armv7 CPUs :-)

Grimler91 added a commit that referenced this issue Oct 26, 2021
This is the same wrapper as what the ndk uses for selecting api level.

This fixes #7232 and
#7839.
@Grimler91
Copy link
Member Author

@enh-google thanks, target armv7a-linux-androideabi24 should be the way to go then.

I kept the name arm-linux-androideabi-clang{,++} to not confuse packages that currently expect the compiler name to be exactly that, but replaced the symlink with the same type of wrapper script as the ndk uses: 04b73f5.

Grimler91 added a commit that referenced this issue Oct 26, 2021
This is the same wrapper as what the ndk uses for selecting api level.

This fixes #7232 and
#7839.
metayan pushed a commit to metayan/termux-packages that referenced this issue Nov 28, 2021
This is the same wrapper as what the ndk uses for selecting api level.

This fixes termux#7232 and
termux#7839.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-arm Issue reproducible on packages compiled for ARM bug report Something is not working properly
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants