Git Product home page Git Product logo

Comments (10)

dimitry- avatar dimitry- commented on August 22, 2024

R_ARM_COPY implies text-relocations in the executable and it is indeed not supported for apps targeting sdk version M and later.

I am a little bit fuzzy on how object relocations turn into R_ARM_COPY, if I had to guess I would say this is because D generated a file that lead to this relocation in final elf-file.

Does your code have inline assembly? If so that might be the source of the problem and this link could help with it: https://wiki.gentoo.org/wiki/Hardened/Textrels_Guide

If not - I would try (1) checking if ld.gold does the same thing and (2) asking D compiler team about it.

from ndk.

joakim-noah avatar joakim-noah commented on August 22, 2024

Here's the thing, the exact same object files produce an executable without that relocation when I use older or newer versions of ld.bfd. That says to me that it is a bug in the linker, nothing to do with D. As for ld.gold, I noted that it doesn't have the issue, but that I need ld.bfd because it has linker scripts that keep ELF section ordering, whereas gold just reorders them any way it likes.

from ndk.

dimitry- avatar dimitry- commented on August 22, 2024

This definitely sounds like a bfd bug.

from ndk.

joakim-noah avatar joakim-noah commented on August 22, 2024

I've packaged up some test objects to try out, along with the resulting executables produced by the older ld.bfd from NDK r10e and the newer one from r11. Here are the commands used to produce test.break and test.work from the given test.o and libdruntime-ldc.a:

/opt/ndk-r11/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -Wl,-z,nocopyreloc --sysroot=/opt/ndk-r11/platforms/android-9/arch-arm -lgcc -gcc-toolchain /opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 -target armv7-none-linux-androideabi -no-canonical-prefixes -fuse-ld=bfd -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -mthumb -lc -lm test.o lib/libdruntime-ldc.a -o test.break
/opt/android-ndk-r10e/toolchains/llvm-3.6/prebuilt/linux-x86_64/bin/clang -Wl,-z,nocopyreloc --sysroot=/opt/ndk-r11/platforms/android-9/arch-arm -lgcc -gcc-toolchain /opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 -target armv7-none-linux-androideabi -no-canonical-prefixes -fuse-ld=bfd -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -mthumb -lc -lm test.o lib/libdruntime-ldc.a -o test.work

test.o is compiled from this small D file that simply calls putc on stdout:

import core.stdc.stdio;
void main() { putc('a', stdout);}

libdruntime-ldc.a is the D runtime library, which contains core.stdc.stdio that references __sF.

ld-reloc.zip

from ndk.

DanAlbert avatar DanAlbert commented on August 22, 2024

FYI, I've asked our binutils guy to take a look at this. Sounds like he has an idea of the patches that need to be cherry-picked, so should be doable for r12.

from ndk.

joakim-noah avatar joakim-noah commented on August 22, 2024

Thanks, looking forward to that, I'll just use the older bfd linker in r10e for now.

from ndk.

shenhanc78 avatar shenhanc78 commented on August 22, 2024

Hi, joakim-noah and Dan,

First of all, for the 2 command lines you aforementioned (thanks for providing reproducible commands), actually, they are using exactly the same binutinls binary - "/opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.bfd". Because of the fact both '-gcc-toolchain' point to the same location.
So it's not a regression in binutils.

Secondly, the reason for "regression" is in clang. The earlier (ndk-r10) clang, while calling ld.bfd, passes a '-pie', while the newer one 'ndk-r11' clang not. You can observe this by adding '-v' right after clang.

Thirdly, this change is quite dubious - whether or not to add '-pie' by default affects the final binary in multiple ways. @DanAlbert is this dropping '-pie' intentional?

I pasted the 2 commands below for reference
Command generates broken binary -

/opt/ndk-r11/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -Wl,-z,nocopyreloc \
    --sysroot=/opt/ndk-r11/platforms/android-9/arch-arm -lgcc \
    -gcc-toolchain /opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
    -target armv7-none-linux-androideabi -no-canonical-prefixes -fuse-ld=bfd \
    -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now \
    -Wl,--warn-shared-textrel -Wl,--fatal-warnings -mthumb -lc -lm test.o \
    lib/libdruntime-ldc.a -o test.break`

Command generates good binary -

/opt/android-ndk-r10e/toolchains/llvm-3.6/prebuilt/linux-x86_64/bin/clang \
    -Wl,-z,nocopyreloc --sysroot=/opt/ndk-r11/platforms/android-9/arch-arm -lgcc \
    -gcc-toolchain /opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 \
    -target armv7-none-linux-androideabi -no-canonical-prefixes -fuse-ld=bfd \
    -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now \
    -Wl,--warn-shared-textrel -Wl,--fatal-warnings -mthumb -lc -lm test.o \
    lib/libdruntime-ldc.a -o test.work

from ndk.

joakim-noah avatar joakim-noah commented on August 22, 2024

@shenhanc78, thanks for looking into this issue. You're right: that flag is the difference and the linker used is actually the same one from r11 with both command invocations. It appears Dan took out PIE by default from clang last year, and it was added to the makefiles instead.

I extracted the flags I was using from Android API 9, by running ndk-build V=1 on the since-removed test-libstdc++ NDK sample executable, because I wanted to have as broad Android support as possible. However, that's why I missed the -fPIE -pie flags that the NDK build scripts add for any executables compiled against Android API 16 or above, when PIE began being supported.

I will use those PIE flags instead, as the market share of Android API 15 and older is small.

from ndk.

DanAlbert avatar DanAlbert commented on August 22, 2024

First of all, for the 2 command lines you aforementioned (thanks for providing reproducible commands), actually, they are using exactly the same binutinls binary - "/opt/ndk-r11/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld.bfd". Because of the fact both '-gcc-toolchain' point to the same location.
So it's not a regression in binutils.

@joakim-noah: can you comment on that? Was that an error when copying the information into the bug, or is that right?

@shenhanc78: Dropping -pie by default was intentional; Android did not support PIE executables until android-16 (Jelly Bean). @joakim-noah: if you're building executables for pre-JB with -pie, they won't run.

from ndk.

joakim-noah avatar joakim-noah commented on August 22, 2024

@joakim-noah: can you comment on that? Was that an error when copying the information into the bug, or is that right?

I did comment on it above, "You're right: that flag is the difference and the linker used is actually the same one from r11 with both command invocations." I had tried to make the command-lines as identical as possible by using the same --sysroot and -gcc-toolchain from NDK 11, with only the compiler different.

I didn't know that meant they'd use the same linker too, I only checked after @shenhanc78 mentioned it and he's right. The only difference is what he said: the old clang 3.6 in NDK r10e was passing the -pie flag to the linker by default, whereas the new clang 3.8 in NDK r11 isn't. I should have checked this myself before filing the issue.

@joakim-noah: if you're building executables for pre-JB with -pie, they won't run.

Yes, I know, that's fine with me. Apparently, they only ever ran for me on 4.1 and above because clang was passing -pie by default before.

I suppose this issue shows that some other flag will now have to be passed to the linker if you want to support Android APIs before 16, ie non-PIE? You could change the topic to that if you like.

from ndk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.