Gomobile Android builds for x86

559 views
Skip to first unread message

timcoo...@gmail.com

unread,
May 13, 2015, 5:05:48 PM5/13/15
to golan...@googlegroups.com
Hi,

As you might have seen, I'm trying to include x86 in the gomobile cross-compiled JNI-based libraries for Android (and possibly other architectures in the future) . The goal is to support all architectures commonly used on Android devices. The android-15 version in the NDK currently used by gomobile supports arm, x86 and mips. The latest android-21 version in the NDK supports arm, arm64, mips, mips64, x86 and x86_64. As noted in the issue (https://github.com/golang/go/issues/10743) by Hyang-Ah Hana Kim creating x86 builds for Android requires more than only changes to the gomobile tool, so I'm trying to include those as well. 

Currently I almost got cross-compiling for x86 working. However I can't figure out how do solve the following problem: The linux/arm syscall assembly file (https://github.com/golang/go/blob/master/src/runtime/sys_linux_arm.s#L485) has definitions for runtime.access, runtime.connect and runtime.socket (https://github.com/golang/go/blob/master/src/runtime/sys_linux_arm.s#L485). These routines are only used by the android builds. However these definitions are missing in the linux/386 file (https://github.com/golang/go/blob/master/src/runtime/sys_linux_386.s) and I have no idea how to add them.

Does anybody have any pointers how to get these assembly routines for x86?

Best,
Tim

Ian Lance Taylor

unread,
May 13, 2015, 6:19:15 PM5/13/15
to timcoo...@gmail.com, golang-nuts
There are several examples in runtime/sys_linux_386.s of functions
that simply make a system call. Copy one of them.

Ian

timcoo...@gmail.com

unread,
May 16, 2015, 1:52:42 PM5/16/15
to golan...@googlegroups.com
Thanks! That was easier to sort out than I thought. Sadly another problem which I can't get my head around arises:
/Users/timcooijmans/Development/gomobile/pkg/gomobile/work-134315846/go/pkg/tool/darwin_amd64/8l: running /Users/timcooijmans/Development/gomobile/pkg/gomobile/android-ndk-r10d/386/bin/i686-linux-android-gcc failed: exit status 1
/Users/timcooijmans/Development/gomobile/pkg/gomobile/android-ndk-r10d/386/bin/../lib/gcc/i686-linux-android/4.8/../../../../i686-linux-android/bin/ld: internal error in relocate_tls, at /s/ndk-toolchain/src/build/../binutils/binutils-2.24/gold/i386.cc:3114
collect2
: error: ld returned 1 exit status

I'm not sure what causes this. This following code from bin-utils is associated with this error:

case elfcpp::R_386_TLS_LE:           // Local-exec
      // If we're creating a shared library, a dynamic relocation will
      // have been created for this location, so do not apply it now.
      if (!parameters->options().shared())
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return;
	    }
	  value -= tls_segment->memsz();
	  Relocate_functions<32, false>::rel32(view, value);
	}
      break;



But I'm not sure what causes it and how to resolve it. By the way I'm not the only one with this problem. See: https://peawee.net/posts/150/


Tim


Ian Lance Taylor

unread,
May 18, 2015, 3:10:48 PM5/18/15
to Tim Cooijmans, golang-nuts
On Sat, May 16, 2015 at 10:52 AM, <timcoo...@gmail.com> wrote:
>
> Thanks! That was easier to sort out than I thought. Sadly another problem
> which I can't get my head around arises:
> /Users/timcooijmans/Development/gomobile/pkg/gomobile/work-134315846/go/pkg/tool/darwin_amd64/8l:
> running
> /Users/timcooijmans/Development/gomobile/pkg/gomobile/android-ndk-r10d/386/bin/i686-linux-android-gcc
> failed: exit status 1
> /Users/timcooijmans/Development/gomobile/pkg/gomobile/android-ndk-r10d/386/bin/../lib/gcc/i686-linux-android/4.8/../../../../i686-linux-android/bin/ld:
> internal error in relocate_tls, at
> /s/ndk-toolchain/src/build/../binutils/binutils-2.24/gold/i386.cc:3114
> collect2: error: ld returned 1 exit status
>
> I'm not sure what causes this. This following code from bin-utils is
> associated with this error:
>
> case elfcpp::R_386_TLS_LE: // Local-exec

My understanding, which is likely incomplete, is that the Android
linker does not support TLS. It would seem to follow that it won't
work to generate TLS relocations on Android. I would think that this
code in cmd/internal/ld/data.go would prevent it:

// Android emulates runtime.tlsg as a regular variable.
if r.Type == obj.R_TLS && goos == "android" {
r.Type = obj.R_ADDR
}

Evidently not. Can you find out what is causing 8l to emit a
R_386_TLS_LE reloc?

Ian

Michael Hudson-Doyle

unread,
May 18, 2015, 5:32:51 PM5/18/15
to Ian Lance Taylor, Tim Cooijmans, golang-nuts
The handling of TLS on intel and ARM is very different, probably
partly because g is always stored in TLS on intel and also partly
because TLS works differently on ARM. In particular, R_TLS relocations
are never emitted on intel, and so the code Ian found will not fire.

As far as I can see the hack by which android/arm emulates TLS cannot
work when using the LE model (because in the LE model on intel the
offset is encoded in the instruction). If you mirror the work I did
for amd64 to support the IE model, I think it probably could.

Cheers,
mwh
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages