Skip to content

cmd/link: Cross-compiled binaries using cgo selects incorrect ld-linux #12443

@17twenty

Description

@17twenty

I am trying to use a Yocto toolchain to build cross-platform binaries for a Gumstix targte using the cgo bindings with the following code:

package binding

// #include <stdlib.h>
// #include <stdio.h>
/*  void myprint(char* s) {
        printf("%s", s);
    }
*/
import "C"

func Random() int {
    return int(C.random())
}

func PrintHello() {
    C.myprint(C.CString("Hello\n"))
}

func Seed(i int) {
    C.srandom(C.uint(i))
}
...
package main
import (
    "./binding"
    "fmt"
)

func main() {
    binding.PrintHello()
    binding.Seed(1)
    fmt.Println(binding.Random())
    binding.Seed(2)
    fmt.Println(binding.Random())
    binding.Seed(3)
    fmt.Println(binding.Random())
}

I built it using the following:

nick@bignick:~/demo/cgodemo$ CC=arm-poky-linux-gnueabi-gcc CGO_CFLAGS="-march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=/opt/poky/1.7.1/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi" CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=5 go build -o Foo_ARM *.go

When trying to run the executable on target you groan and see:

root@target:~# ./Foo_ARM
-sh: ./Foo_ARM: No such file or directory

The issue seems to be that the runtime loader used is incorrect
If you run readelf you can see it's embedding ld-linux.so.3 as the linux loader but the toolchain is configured for ld-linux-armhf.so.3

nick@bignick:~/demo/cgodemo$ arm-poky-linux-gnueabi-readelf Foo_ARM -a | grep ld-
  [ 3] .note.gnu.build-i NOTE            00008188 000188 000024 00   A  0   0  4
      [Requesting program interpreter: /lib/ld-linux.so.3]

I'm not sure why this has happened as those CC and CFLAGS are exactly that used to produce other binaries which don't have this issue i.e.:

nick@bignick:~/demo/cgodemo$ arm-poky-linux-gnueabi-readelf  NormalCrossCompiledHelloWorld -a | grep ld-
  [ 3] .note.gnu.build-i NOTE            00008170 000170 000024 00   A  0   0  4
      [Requesting program interpreter: /lib/ld-linux-armhf.so.3]
   03     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .ARM.exidx .eh_frame 
   06     .note.ABI-tag .note.gnu.build-id 
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
  000000: Version: 1  File: ld-linux-armhf.so.3  Cnt: 1

After a bit of faffing and checking out the binaries a suggested workaround is simply to create a softlink between the two but this should ideally be fixed when building:

ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3
root@target:/lib# ~/Foo_ARM 
Hello
1804289383
1505335290
1205554746

Any suggestions?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions