8

I try to compile some C code for an embedded (custom) ARM-based Linux system. I set up an Ubuntu VM with a cross-compiler named arm-linux-gnueabi-gcc-4.4 because it looked like what I needed. Now when I compile my code with this gcc, it produces a binary like this:

$ file test1
test1: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.31,
BuildID[sha1]=0x51b8d560584735be87adbfb60008d33b11fe5f07, not stripped

When I try to run this binary on the embedded Linux, I get

$ ./test1
-sh: ./test1: not found

Permissions are sufficient. I can only imagine that something's wrong with the binary format, so I looked at some working binary as reference:

$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped

I see that there are some differences, but I do not have the knowledge to derive what exactly I need to fix and how I can fix that. Can someone explain which difference is critical?

Another thing I looked at are the dependencies:

$ ldd test1
    libc.so.6 => not found (0x00000000)
    /lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)

(Interestingly, this works on the target system although it cannot execute the binary.) The embedded system only has a libc.so.0 available. I guess I need to tell the compiler the libc version I want to link against, but as I understand it, gcc just links against the version it comes with, is this correct? What can I do about it?

Edit: Here's the Makefile I use:

CC=/usr/bin/arm-linux-gnueabi-gcc-4.4
STRIP=/usr/bin/arm-linux-gnueabi-strip          
CFLAGS=-I/usr/arm-linux-gnueabi/include             
LDFLAGS=-nostdlib
LDLIBS=../libc.so.0

SRCS=test1.c
OBJS=$(subst .c,.o,$(SRCS))

all: test1

test1: $(OBJS)
    $(CC) $(LDFLAGS) -o main $(OBJS) $(LDLIBS)
    $(STRIP) main

depend: .depend

.depend: $(SRCS)
    rm -f ./.depend
    $(CC) $(CFLAGS) -MM $^>>./.depend;

clean:
    rm -f $(OBJS)

include .depend
flyx
  • 35,506
  • 7
  • 89
  • 126
  • 1
    If you're tight on memory, the much smaller `uClibc` can substitute for `glibc`. However you would need a *gcc* compiler built to use `uClibc`. One (relatively) easy method of obtaining a working toolchain of *gcc*, *uClibc* (or *glibc*) and friends plus building the Linux kernel, Busybox and other packages all from source is to use `BuildRoot`. With a good compiler + libc combination, you can link your app statically, and be independent of the target's libraries. – sawdust Sep 20 '12 at 18:54

1 Answers1

5

What you should probably do is to install libc6 on the embedded system. Read this thread about a similar problem. The solution in post #5 was to install:

libc6_2.3.6.ds1-13etch9_arm.deb
linux-kernel-headers_2.6.18-7_arm.deb
libc6-dev_2.3.6.ds1-13etch9_arm.deb

Your other option is to get the libc from the embedded system onto your VM and then pass it to the gcc linker and use the -static option.

This solution was also mentioned in the above thread. Read more about static linking here.

Other things to try:

In this thread they suggest removing the -mabi=apcs-gnu flag from your makefile if you're using one.

This article suggests feedint gcc the -nostdlib flag if you're compiling from the command line.

Or you could switch to using the arm-none-eabi-gcc compiler. References on this can be found here and here.

embedded.kyle
  • 10,976
  • 5
  • 37
  • 56
  • I cannot install software on the embedded system, but linking to the system's libc brought up this error: `ld: error: Source object ../libc.so.0 has EABI version 0, but target main has EABI version 5`. The google results for this error imply that I actually need a different gcc, is this correct? – flyx Sep 20 '12 at 13:01
  • @flyx Are you using a makefile or are you running gcc directly on the command line? – embedded.kyle Sep 20 '12 at 13:23
  • arm-none-eabi-gcc is probably the right choice. I didn't try because I got a working toolchain from the hardware manufacturer, but I'll mark this as correct answer anyway. The links were quite helpful. – flyx Oct 02 '12 at 08:49