Missing functions with CGO & ARMv5

So this is no doubt a cursed question, but I need to cross compile a binary for Linux/ARMv5 while linking to libpcap for gopacket/pcap.

LDFLAGS='-l/usr/arm-linux-none-eabi/lib/libpcap.a' \
    GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc-10 \
    PKG_CONFIG_PATH=/usr/arm-linux-none-eabi/lib/pkgconfig \
    go build -ldflags '-X "main.Version=0.0.8" -X "main.Delta=81" -X "main.Buildinfos=2022-01-07T04:36:09+0000" -X "main.Tag=v0.0.8" -X "main.CommitID=25242e0d2bfa9697c5c346f73178e4aaa0ba034a" -s -w -linkmode external -extldflags -static' -o  cmd/*.go
# command-line-arguments
cmd/main.go:78:3: undefined: listInterfaces
cmd/main.go:126:3: undefined: initializeInterface

The undefined functions are defined in my main package and I can get this to code to compile on a variety of other platforms, including ARMv6/v7/64. I suspect this has to do with libpcap since these two functions either directly or indirectly make calls to gopacket/pcap / libpcap.

I’m compiling libpcap via:

CC=/build/bin/gcc BUILD_CC=gcc AR=/build/bin/ar  RANLIB=/build/bin/ranlib \
        ./configure --build i686-pc-linux-gnu --host arm-linux-none-eabi --prefix=/usr/arm-linux-none-eabi && make install

FWIW, I did try linking against the same libpcap static library I successfully use for ARMv6/v7/64, but that did not work:

CC=/build/bin/gcc BUILD_CC=gcc AR=/build/bin/ar  RANLIB=/build/bin/ranlib \
        ./configure --build i686-pc-linux-gnu --host arm-linux-gnueabi --prefix=/usr/arm-linux-gnueabi && make install

in both cases, extracting the objectfiles from the libpcap.a and inspecting them returns:

pcap-linux.o: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), with debug_info, not stripped

compiling done via Ubuntu 20.04.

so added the -x flag to go build and it’s failing at:

cd /build/udp-proxy-2020
/usr/lib/go-1.16/pkg/tool/linux_amd64/compile -o $WORK/b001/_pkg_.a -trimpath "$WORK/b001=>" -p main -lang=go1.16 -complete -buildid bhPWJnAyoBzK6Jt4_UTT/bhPWJnAyoBzK6Jt4_UTT -goversion go1.16.2 -D _/build/udp-proxy-2020/cmd -importcfg $WORK/b001/importcfg -pack -c=4 ./cmd/listen.go ./cmd/main.go ./cmd/send.go ./cmd/utils.go $WORK/b001/_gomod_.go
# command-line-arguments
cmd/main.go:78:3: undefined: listInterfaces
cmd/main.go:126:3: undefined: initializeInterface

What is super interesting is that those two functions are defined in cmd/interfaces.go but the go source file is not being included?? No idea why it is being removed by go build… there aren’t any errors I can see in the output or any references to cmd/interfaces.go in the output at all.

source code here: https://github.com/synfinatic/udp-proxy-2020/blob/main/cmd/interfaces.go

Well, kept banging my head on this and found out that this was the magical incantation:

# setup gcc
mkdir -p /build/bin && cd /build/bin && \
    ln -s /usr/bin/arm-linux-gnueabi-gccgo-10 gccgo && \
    ln -s /usr/bin/arm-linux-gnueabi-gcc-ar-10 ar && \
    ln -s /usr/bin/arm-linux-gnueabi-gcc-ranlib-10 ranlib && \
    ln -s /usr/bin/arm-linux-gnueabi-gcc-10 gcc

# build libpcap
CC=/build/bin/gcc BUILD_CC=gcc AR=/build/bin/ar  RANLIB=/build/bin/ranlib \
    ./configure --build i686-pc-linux-gnu \
    --host arm-linux-gnueabi --prefix=/usr/arm-linux-gnueabi && \
    make install

# build the binary
LDFLAGS='-l/usr/arm-linux-gnueabi/lib/libpcap.a' \
     GOOS=linux GOARCH=arm GOARM=5 CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc-10 \
     PKG_CONFIG_PATH=/usr/arm-linux-gnueabi/lib/pkgconfig \
     go build -ldflags '$(LDFLAGS) -linkmode external -extldflags -static' \
         -o ./dist/udp-proxy-2020-0.0.8-linux-armv5 cmd/*.go

And then using arm-linux-gnuabihf for ARMv6/v7.