Changing which libc.so gets linked? - c

Im trying to cross compile for MIPSEL on my router. I got stuff working in assembly, but now Im moving to trying to compile basic C code.
Currently just have simple hello world c code, and using the mipsel-linux-gnu-gcc compiler, which works for assembly.
Compiler command:
mipsel-linux-gnu-gcc -L/home/uname/devel/extr/squashfs-root/lib -l:libc.so.0 -mips32 -Wl,--build-id=none -Wl,--dynamic-linker=/lib/ld-uClibc.so.0 ma.c
The libc.so.0 is extracted from the firmware for the router.
The program compiles, however in readelf, the issue is that it links against libc.so.6
0x00000001 (NEEDED) Shared library: [libc.so.6]
whereas pulling the busybox binary from the firmware and running readelf on it
0x00000001 (NEEDED) Shared library: [libc.so.0]
How do I get it to link against libc.so.0?

It looks like you need to negate the standard glibc path, as the compiler checks this first. This can be done by compiling with -nostdinc.
You'll then need to -I include the gcc headers and such, as discussed here.

Figured it out. Had to build a uClibc toolchain using buildroot.

Related

How to link specific standard library in gdb?

When analyzing core on different machine, that binary was built for I ran into:
warning: .dynamic section for "/lib64/libc.so.6" is not at the expected address (wrong library or version mismatch?)
Is there a way to change which libc gdb is looking for?
Thanks to #Kevin Boone!
set sysroot helped I set it to ./ and put desired libc in ./lib64 and then loaded core using core-file

qemu-arm running compiled binary

Trying to run a compiled binary I've extracted from a firmware on qemu, however I encounter this error:
root#ubuntu14:~# qemu-arm -L /usr/arm-linux-gnueabi ~/x
/system/bin/linker: No such file or directory
root#ubuntu14:~# file ./x
./x: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), stripped
I'm using the "-L" flag, as suggested in:
qemu-arm can't run arm compiled binary
However, this flag doesn't seem to make a different for me, neither does setting QEMU_LD_PREFIX
Could it be some missing dependencies?
It looks like the system is not able to find the dynamic linker (which in your case appears to be /system/bin/linker, rather than the the normal /lib/ld-linux-armhf.so.3 or similar.
Since I don't have access to your code, I've tried to reproduce this by mounting a Raspberry Pi "Raspbian" image on /mnt on my system. If I try to run /mnt/bin/echo hello, like this:
qemu-arm /mnt/bin/echo hello
I get a similar error:
/lib/ld-linux-armhf.so.3: No such file or directory
I can provide an explicit path to the dynamic linker like this:
qemu-arm /mnt/lib/ld-linux-armhf.so.3 /mnt/bin/echo hello
Now I get a different error:
/mnt/bin/echo: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
That's actually great, because that is a normal "I can't find my shared libraries" error, and the solution is to use LD_LIBRARY_PATH. Rather than setting this in our environment, we can set this in the environment created by qemu-arm with the -E flag:
qemu-arm -E LD_LIBRARY_PATH=/mnt/lib/arm-linux-gnueabihf/ /mnt/lib/ld-linux-armhf.so.3 /mnt/bin/echo hello
Which gets me the output:
hello
I suspect that these same two techniques -- providing an explicit path to the linker, and providing an explicit library search path in LD_LIBRARY_PATH -- may help you out. Let me know how it works!
/system/bin/linker is the Android dynamic linker, so you need a directory with the Android dynamic linker and dynamic libraries, not one for Linux (which is what /usr/arm-linux-gnueabi will be). You should be able to pull the relevant files out of your firmware image, I expect.

GCC 7.2 compiles shared library instead of executable

I have a virtual machine with ArchLinux installed. Here when I compile with GCC by running gcc file.c it gives me a shared library instead of an executable.
Later I find out that the problem is related only to GCC 7.2, in fact, when I compile with GCC 6.4, the output file is an executable.
How do I fix this?
The file utility is just incorrect in calling your program a shared library. It is a position-independent executable (PIE). If you really don't want this, you can specify -no-pie at link time, or build a gcc toolchain with --disable-default-pie, but in general you shouldn't need to change this.
To complement the answer that mentioned file as you pointed out in the comments, the default a.out generated by GCC is not a shared library but instead interpreted as a shared object by file maybe because of the content of your source code. Check this for more information.

Objdump doesn't recognize the architecture of a shared library

I built a shared library on Ubuntu 14.04 for ARM platform. The file has compiled and build successfully. I can inspect exported symbols with nm command but when I check .so file header I got the information that architecture is unknown.
Is this library built correctly, why is the library architecture unknown ?
objdump -f libMyLib.so
libMyLib.so: file format elf32-little
architecture: UNKNOWN!, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x000033a0
You need to use the objdump binary provided by the toolchain of your target system (ARM), not from host system(x86_64).
As a example: I have setup a host system Linux x86_64 targeting openwrt mips, my toolchain folder has some files:
mips-openwrt-linux-gnu-ar
mips-openwrt-linux-gnu-as
mips-openwrt-linux-gnu-gcc
mips-openwrt-linux-gnu-ld
mips-openwrt-linux-gnu-objdump
mips-openwrt-linux-gnu-nm
These are the tools to manipulate programs for openwrt mips system, so instead of just calling objdump, I need to call ./mips-openwrt-linux-gnu-objdump -f <bin file> to read and get the proper output for the compiled file.

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Resources