Closed bacam closed 8 years ago
That's problematic. I don't think there is a "nice" way to solve this within opam-android; what you can do is to pass -fPIE
to ocamlopt manually. This will require some custom ocamlbuild rules...
you could perhaps pass this in with the CAMLPARAM env var that appends compiler flags.
On 27 Sep 2015, at 12:14, whitequark notifications@github.com wrote:
That's problematic. I don't think there is a "nice" way to solve this within opam-android; what you can do is to pass -fPIE to ocamlopt manually. This will require some custom ocamlbuild rules...
— Reply to this email directly or view it on GitHub https://github.com/whitequark/opam-android/issues/7#issuecomment-143543748.
@avsm, that would conflict with ocamlbuild's caching. The build product would be different but ocamlbuild does not know that as it does not observe the value of CAMLPARAM. (Maybe it should.)
I filed a bug: http://caml.inria.fr/mantis/view.php?id=6999
@bacam Does the newer toolchain default to passing -fPIE
itself, or do you have to do it manually even with r11c, level 24, etc?
I just gave it a fresh try and still generates non-PIE executables. I don't know a lot about the NDK, but from what I've seen I think it adds the options in their build setup rather than the actual tools. I suspect that the same tools also support pre-PIE Android. I forgot to mention this before, but I did manage to get it working before by adding -fPIE -pie
to BYTECC
in config/Makefile
and managed to build unison. Both bytecode and native run, although native produces the warning
WARNING: linker: ./unison has text relocations. This is wasting memory and prevents security hardening. Please fix.
and I'm not sure if ocamlopt's code generator is actually sufficiently position independent (I recall seeing some PIE patches for iOS) so I've been using the bytecode version.
@bacam Yeah, that's what I eventually found out as well. What I suggest doing is building your executable using OCAMLPARAM=cclib=-fPIE,-pie, which requires no changes to ocaml-cross-android and allows to reuse the same toolchain for different Android versions.
Re: ocamlopt's code generator. It is not. But I don't think that using bytecode is a correct response to this; if your executable is in OCaml then memory safety bugs aren't nearly as pressing...
Closing with the recommendation to use export OCAMLPARAM=cclib=-fPIE,-pie
rather than changing the embedded build flags. Please reopen if you think this is wrong.
For the record, you can also add -ccopt -fPIE -ccopt -pie
to your ocamlopt
arguments, and it will generate the PIE executable, such that it will run on armv7 android. However, it still prints the error xyz has text relocations
, and if you try to run the binary on an arm64 device, it refuses to run, with the error:
CANNOT LINK EXECUTABLE "/data/local/tmp/helloworld.native": /data/local/tmp/helloworld.native: has text relocations
I believe this is something that can only be fixed upstream.
Try compile every single object files with -fpic, including ocaml objects when you build ocaml. This make sure no text allocation is needed at runtime.
@whiteshark, why do you say that? Is it because we have some hand written asm in ocaml?(GC for example)
Try compile every single object files with -fpic, including ocaml objects when you build ocaml.
This is already done as per https://github.com/ocaml-cross/opam-cross-android/issues/7#issuecomment-212638955. However, the code that ocamlopt generates itself still has text relocations.
Turns out you can sidestep the problem by either
In Android 5.0 Google removed linker support for non-PIE (position independent executables) binaries. This causes both bytecode and native ocaml programs to fail:
That was generated on a standard Google 5.0.1 image for armeabi-v7a, but the same thing happens on a Nexus 5.
A little searching around suggests that it can be tricky to support both recent and older versions of Android simultaneously because older versions don't directly support PIE, but recent versions require it. Apparently Chromium has a wrapper executable to work around this, while other people generate different executables for different versions of Android.