Android NDKとNexus9を使って64bit ARMのバイナリを試してみた

Android NDKとNexus9を使って64bit ARMのバイナリを試してみた。

ちなみに去年(2014年)、iOSで64bit ARMのバイナリをコンパイルして動かすのを試している。
iOSのJailbreak環境で64bit ARM(AARCH64)のバイナリを試してみた
iOSのJailbreak環境で64bit ARM(AARCH64)のインラインアセンブラを試す
今回は、Android NDKで64bit ARMのバイナリをコンパイルするのを試してみる。

まず、Android NDKをインストールする。
Windows7(64bit版)のPCを使って、c:\android-ndk-r10dというフォルダーに入れた。

適当な作業フォルダー(例えば、c:\workなど)を作って、ソースコードを書く。
c:\workの下にjniというフォルダを作成し、そこにソースコードのファイルのhello.cを置く。
hello.c (c:\work\jni\hello.c) の内容は、以下の通り。

#include <stdio.h>

int main(int argc, char **argv, char **evnp)
{
#ifdef __LP64__
  printf("64bit\n");
#else
  printf("32bit\n");
#endif
  printf("Hello world.\n");
  return 0;
}

そして、Android.mkというビルド用の設定を記述したファイル作る。
Android.mk (c:\work\jni\Android.mk) の内容は、以下の通り。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_EXECUTABLE)

ビルド用のバッチファイルbuild.batというファイルも作成した。
build.bat (c:\work\build.bat) の内容は以下の通り。

rem =========== environment setting ==========
set PATH=%PATH%;c:\android-ndk-r10d\
set ANDROID_NDK_ROOT=c:\android-ndk-r10d\
set NDK_PROJECT_PATH=.

echo =========== 64bit build ============
call ndk-build -B V=1 APP_ABI=arm64-v8a

pause

このバッチファイルを実行すると、ソースコードhello.cがビルドされて、64bitのバイナリがc:\work\libsフォルダー以下に生成される。
hello (c:\work\libs\arm64-v8a\hello) が、64ビットのバイナリのファイルだ。

このファイルをNexus9の実機に転送して実行してみた。
Nexus9はroot化したものを使った。
Nexus9の/sdcardフォルダーの直下にtmpというフォルダを作ってそこに一旦helloを転送する。

adb push hello /sdcard/tmp/hello

そして、Nexus9側で、
/dataフォルダー直下にtmpというフォルダを作って、そちらにコピーする。
(フォルダーのパーミッション設定が必要だったかも)

cp /sdcard/tmp/* /data/tmp

そして、実行するためにchmodコマンドで実行属性を付ける。

chmod 744 /data/tmp/hello

そして実行する。
Rimg0001
64bit ARMのコードが実行されたのが確認できた。

次に64bit ARMのインラインアセンブラも試してみた。
同様の手順で、ソースコード(addvalue.c)は次のように書いた。
アセンブラで2つの数字を加算するというコードだ。

#include <stdio.h>

long int addvalues(long int val1,long int val2)
{
  long int result;
  __asm__ (
    "ADD %[Rd],%[Rs1],%[Rs2]"
    : [Rd] "=r" (result)
    : [Rs1] "r" (val1), [Rs2] "r" (val2)
  );
  return result;
}

int main(int argc, char **argv, char **envp)
{
  long int val=addvalues(1234567890123456789L,1L);
  printf("addvalues = %ld\n",val);
  return 0;
}

同様にビルドして実行すると、次のようになった。
Rimg0001
1234567890123456789と1が加算された結果の1234567890123456790が表示された。
無事、64bitのARMのインラインアセンブラも使うことができた。


追記
ビルド時のndk_buildでAPP_ABI=arm64-v8aを指定せずにビルドさせると、32bitのARMのバイナリが生成されるはずである。
しかし、そうして生成した32bitのバイナリはNexus9で実行しようとするとエラーになってしまった。
error: only position independent executables (PIE) are supported.というエラーだ。
なぜ??
[続き]


さらに追記
インラインアセンブラでなく、直接アセンブラで書いてみた。




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.

8 + 2 =