How should __attribute__((pcs("aapcs"))) be used in HardFP ABI programs? - android

I have a HardFP ABI (very) simple test program. It links with other HardFP binaries without any problems. Now I wanted to use a function from a Softfp ABI library in my code, so I changed the header file (.h) from this library to add the attibute: __ attribute__((pcs("aapcs"))) on every function which uses double args (like: void doSomething(double arg, double arg2)), so I'm telling the toolchain that this library uses softfp ABI. The problem is that the toolchain (arm-linux-androideabi-4.9) is yelling me that:
/media/data_disk/b2g/work/hardfp/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: /tmp/cc6SmP3D.o uses VFP register arguments, output does not
/media/data_disk/b2g/work/hardfp/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: /home/jgomez/b2g/build.flatfish.hardfp/out/target/product/flatfish/obj/lib/libc.so uses VFP register arguments, output does not
/media/data_disk/b2g/work/hardfp/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: /home/jgomez/b2g/build.flatfish.hardfp/out/target/product/flatfish/obj/lib/libstdc++.so uses VFP register arguments, output does not
/media/data_disk/b2g/work/hardfp/arm-linux-androideabi-4.9/bin/../lib/gcc/arm-linux-androideabi/4.9.x-google/../../../../arm-linux-androideabi/bin/ld: error: /home/jgomez/b2g/build.flatfish.hardfp/out/target/product/flatfish/obj/lib/libm.so uses VFP register arguments, output does not
(Of course, libc, libstdc++, and libm are hardfp too).
It doesn't compile.
So my question is,
How does __attribute__((pcs("aapcs"))) should be used to let HardFP ABI programs link with Softfp ABI binaries?
I thought that this was the purpose of such a flag. Am I wrong?
Thanks!!

Ok, I already figured out the problem.
As I thought, the attribute works as expected. The assembly code generated by the compiler (gcc) if I write the prefix: __attribute__((pcs("aapcs"))) in front of the function declaration, is using r registers to pass the argument values, so the callee, in Softfp mode, works perfect.
I just needed to add this flag to the compiler options:
--no-warn-mismatch

Related

Android NDK - deduced return types are a C++14 extension

I'm having an issue when compiling my project as an android library.
[jni/../../Src/Core\Util/Concurrent/WorkerThread.h:206:12] warning: 'decltype(auto)' type specifier is a C++14 extension [-Wc++14-extensions]
[jni/../../Src/Core\Util/Concurrent/WorkerThread.h:206:3] error: deduced return types are a C++14 extension
decltype(auto) wait() { return state->wait(); }
It seems related to the C++ version, but I'm not sure. I tried to; change the NDK version, change the C++ version, change the code itself.
I'm currently using Android NDK 23.1.7779620 & Clang 12 if not mistaken.
I'm not familiar with that so let me know if there is any information that I should add.

Tensorflow Quantized Graph for Android

I'm trying to load a quantized graph into an Android app.
My BUILD file contains
deps = ["//tensorflow/core:android_tensorflow_lib",
"//tensorflow/contrib/quantization:cc_array_ops",
"//tensorflow/contrib/quantization:cc_math_ops",
"//tensorflow/contrib/quantization:cc_nn_ops",
"//tensorflow/contrib/quantization/kernels:quantized_ops"]
The additional quantization deps work for standalone C++ builds.
I can't compile with Bazel, due to a large number of errors in GEMMLOWP. What's the proper way to include gemmlowp and the quantization ops in Android?
Here is an example error:
external/gemmlowp/eight_bit_int_gemm/eight_bit_int_gemm.cc:125:13: error: 'int32_t' is not a member of 'std'
MatrixMap<std::int32_t, ResultOrder> result(c, m, n, ldc);
This is on Ubuntu 16.04 with Bazel 0.3.0.
Here's a gist that has the output of two sequential attempts to build the package - it fails on highwayhash the first time and gemmlowp the second.
https://gist.github.com/ericdanz/81b799f2e0bbb3cc462aa3c90468c71b
Ultimately got it to compile and run with liberal addition of "-std=c++11" in BUILD files for gemmlowp and highwayhash, and substitution of the android framework for the framework dependencies in the quantized ops. It produces fairly different results though, and runs about 4x slower (26-3200ms vs 6-800 ms). I'll try to do a little deeper investigation.
Here's what worked for me - it is basically a combination of all the comments from Eric D above, but I wanted to put it all in one place for someone new who comes across this problem:
Add quantized_ops in deps to libtensorflow_demo.so in the BUILD file for the Android app:
deps = ["//tensorflow/core:android_tensorflow_lib",
"//tensorflow/contrib/quantization/kernels:quantized_ops",]
Modify the deps for quantized_ops in tensorflow/contrib/quantization/kernels/BUILD:
deps = [
"//tensorflow/contrib/quantization:cc_array_ops",
"//tensorflow/contrib/quantization:cc_math_ops",
"//tensorflow/contrib/quantization:cc_nn_ops",
"//tensorflow/core:android_tensorflow_lib",
#"//tensorflow/core",
#"//tensorflow/core:framework",
#"//tensorflow/core:lib",
#"//tensorflow/core/kernels:concat_lib_hdrs",
#"//tensorflow/core/kernels:conv_ops",
#"//tensorflow/core/kernels:ops_util_hdrs",
#"//tensorflow/core/kernels:pooling_ops_hdrs",
#"//tensorflow/core/kernels:eigen_helpers",
#"//tensorflow/core/kernels:ops_util",
#"//tensorflow/core/kernels:pooling_ops",
"//third_party/eigen3",
"#gemmlowp//:eight_bit_int_gemm",
],
Remove/comment out the .Doc() parts in tensorflow/contrib/quantization/ops/array_ops.cc, math_ops.cc and nn_ops.cc
Modify the deps for cc_array_ops, cc_math_ops and cc_nn_ops in tensorflow/contrib/quantization/BUILD:
deps = [
#"//tensorflow/core:framework",
"//tensorflow/core:android_tensorflow_lib",
],
Run bazel build command for Android app with --cxxopt="-std=c++11" flag.

How to use memset_s in Android NDK?

android.ndk {
moduleName = "hello-jni"
stl = "stlport_static"
CFlags.add("-std=iso9899:2011") // I have also used "-std=c11"
ldLibs.addAll(["android", "log"])
}
I still cannot see memset_s in jni C code. It says undefined reference.
In my c code i have also included string.h, stdlib.h, and stdio.h and also
#define STDC_WANT_LIB_EXT1 1
Still cannot get rid of the error undefined reference error.
If i add the flag Allow_Undefined_symbols it compiles but when ever i call the function memset_s it crashes.
The questions i would like to ask are as follows :
1) In which of the Android NDK tool chains can we get the C11 memset_s api?
2) The other question i have is how can we change the default tool chain for android in the latest android studio with experimental gradle alpha5?
This functionally of "Annex K" in the C11 standard is optional. It is not implemented in many C libraries.
You can test for conformance to Annex K by means of the macro __STDC_LIB_EXT1__.
I was not able to find any tool chain that supports C11 for NDK. So i have used a compliant solution for c99 from the following link:
https://www.securecoding.cert.org/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations
Which you can customize for your own purpose. I am adding this solution for any one in need.

Using -std=c++11 on VS2015

I have created a shared object for Android in Visual Studio 2015.
It works fine so far, but pop_back() for a wstring does not work:
wstring element = "JustATest!";
if (element.back() == L'!')
{
element.pop_back();
}
VS2015 tells me:
"no member named 'pop_back' in 'std::basic_string<wchar_t>'".
Can anybody tell me how to get rid of this error?
I have no idea why this should not work.
Is that because for some reason VS2015 does not use C++11 here?
Thank you for the help!
Edit: Another error:
When I try to use _wtoi, VS tells me: "use of undeclared identifier '_wtoi'.
Very very strange.
You need to turn on STL support. Turn on STL with Configuration Properties -> General -> Use of STL. Good options are LLVM libc++ static library (fewer features, more compatible with CLANG) and GNU STL static library (more features, I had an issue that required me to turn the CLANG optimizer to -Oz to prevent a segfault).

NDK error: "can't resolve `.data.rel.ro.local'"

Android/NDK project, worked with NDK versions all the way up to r8c. Under 8d and 8e, I get a compilation error message on the armeabi-v7a build:
Compile++ thumb : myproject <= MyFile.cpp
C:\cygwin\tmp\ccFXOc2F.s: Assembler messages:
C:\cygwin\tmp\ccFXOc2F.s:1935: Error: can't resolve `.data.rel.ro.local' {.data.rel.ro.local section} - `.LPIC44' {*UND* section}
The armeabi, MIPS, and x86 builds for the same project are successful.
It's reliably popping up on the same file. The file is nothing special - vanilla C++, it compiles and works on numerous other platforms (iOS, Windows, NDK r8c to name some). No STL. It does define a healthy amount of string constants though (AKA initialized read/only data). What could be going on?
Already tried a full rebuild, even deleted the obj folder altogether.
The C++ flags are:
LOCAL_CPPFLAGS := -fshort-wchar -fsigned-char -Wno-psabi
I know NDK comes with several versions of GCC; might a toolchain change help? How exactly?
Surely looks like a compiler bug to me. It's related to indexed access to a large chunk of static const data. When I've slightly reformulated a perfectly innocent statement, the error message went away.
Used to be:
//In global scope
static const LPCWSTR Comments[] = {L"A lot of strings here", L"String 2", L"String 3" /* and many more */ }:
void SomeMethod()
{
DoSomething(Comments[i]); //That was the offending line - commenting it out would get rid the error
}
Replaced with:
void SomeMethod()
{
static LPCWSTR pComments = 0;
if(!pComments)
pComments = Comments;
DoSomething(pComments[i]); //Now it works.
}
Ooky, spooky stuff.

Categories

Resources