GCC link against .so file without souce code

1.8k Views Asked by At

I am trying to compile compile a simple "hello world" program for an Axis A210 (cris architecture). I managed to get download GCC from the vendor, but it came with glibc, and the camera is running uClibc-0.9.27. I pulled the file /lib/libuClibc-0.9.27.so from the device.

I managed to compile this program that segfaults:

#include <unistd.h>

int main(int argc, char** argv)
{
    *((unsigned int*)0) = 0xDEAD;
}

and this program that just hangs:

#include <unistd.h>

int main(int argc, char** argv)
{
    int a = 0;
}

with cris-gcc -g -static -nostdlib -o compiled main.c.

Now I'd like to use the functions in libuClibc, but I can't seem to get the linking to work: I've tried

cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.

but that just gives:

./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status

Is there a way to link to this .so file or to otherwise get some standard functions like exit working?

2

There are 2 best solutions below

4
user3629249 On

regarding:

cris-gcc -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.

The linker works with libraries in the order they are encountered. So they must be listed in the order needed.

The linker needs to know where the library is located before knowing which library to examine. Suggest:

cris-gcc -g -static -nostdlib -o compiled main.c -L.  -luClibc-0.9.27 

However, a *.so library is NOT a static library. It is a dynamic library, so the option: -static should be removed However, that requires that the dynamic library be available at 'run time' if the related *.a (a static library) is available then it should be used in the compile/link statement.

Note: the function: exit() has its' prototype exposed via the stdlib.h header file, not the unistd.h header file.

regarding:

#include <unistd.h>

int main(int argc, char** argv)
{
    *((unsigned int*)0) = 0xDEAD;
}

the parameters: argc and argv are not used, so the compiler will output two warning statements about 'unused parameters'. Suggest using the function signature: int main( void )

this code is trying to write to address 0. However, the application does not 'own' address 0, (an usually, such an address will be 'marked' as 'readonly' so the application will exit with a 'seg fault event')

it is poor programming practice to include header files those contents are not used. Suggest removing the statement: #include <unistd.h>

this statement: int a = 0; will result in the compiler outputting a warning message about a variable that is 'set' but never 'used'

regarding:

cris-gcc -g -static -nostdlib -o compiled main.c -L. -luClibc-0.9.27

When compiling, should always enable the warnings, then fix those warnings. Suggest:

cris-gcc -Wall -Wextra -Wconversion -pedantic -std=c99 -g -static -nostdlib -o compiled main.c -luClibc-0.9.27 -L.    
0
Luis Colorado On

Apart of all the problems noticed by @user3629249 in his answer (all of them are to be followed), the message:

./libuClibc-0.9.27.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status

means that the libuClibc-0.9.27.so binary has been stripped its symbols or you have not privileges to read the file, and so, the symbol table. The linker is unable to use that binary and it can only be loaded into memory. Anyway, you need a nonstripped shared object, and as suggested by @user3629249, don't use -static (by the reason stated in his answer), put the parameters in order (library dir before the library to be linked, also stated by him). Even you can link the shared by specifying it as:

cris-gcc -nostdlib -o compiled main.c libluClibc-0.9.27.so

and another thing: You need not only the standard C library to link an executable... you normally use a crt0.o at the beginning of your program with the C runtime and the start code for your program. You have not included that, and probably the compiler is getting it from another place.

One question: If you got the compiler, why do you intend to supply your own version of the standard library? isn't provided by the compiler? If you change the libc, then you must change also the crt0.o file. It defaults to some compiler provided, and you haven't received the message no definition for start.

Try to compile with just a main function, as you did, but don't specify shared libraries or directories... just the main code:

cris-gcc -o compiled main.c

and see what happens.... this will be very illustrative of what you lack in your system.