views:

115

answers:

2

I've written an interface to the code generator that lets me produce shared objects. Though I do not want o implement support for section header table because that's where the majority complexity of ELF file format remains in.

GNU ld uses section headers for linking against shared objects. This means that when I try to put gcc link against my shared object with no section headers, it will fail because the ld doesn't find the symbols even if they exists in the library.

Does there exist some trick I could use to fool the compiler to make the linking succeed even if it wouldn't find certain symbols?

Here's some clarification on the trouble:

cheery@ruttunen:~/Documents/g386$ gcc dev/shared_test.c -L. -lshared -m32
/tmp/cc6qBViY.o: In function `main':
shared_test.c:(.text+0xa): undefined reference to `example_function'
collect2: ld returned 1 exit status
cheery@ruttunen:~/Documents/g386$ cat dev/shared_test.c 
// gcc shared_test.c -L. -lshared -m32
// LD_LIBRARY_PATH=. ./a.out
#include <stdio.h>

extern int example_function();

int main(){
    printf("hello %d\n", example_function());
}
cheery@ruttunen:~/Documents/g386$ readelf -D -s libshared.so 

Symbol table for image:
  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
    2   0: 00800164     0    FUNC GLOBAL DEFAULT ABS example_function
    1   0: 008000ac     0  OBJECT GLOBAL DEFAULT ABS _DYNAMIC
+1  A: 

gcc (that is, ld behind gcc) has a command line option to ignore unresolved externals. That'll suppress the error message you get from gcc. I'm not sure that that is going to make you happy.

+1  A: 

The best approach here is to add the section tables required by gcc. If you have a working dynamic linking mechanism in your generator, it requires all the same information as what you'd insert into the section tables.

For laziness I wrote a shared assembly file and used strip-command on it to get a reference point. ´readelf --sections´ shows couple of sections but you do not need them all. I worked through this and implemented sections in order until it started working correctly. Here's what I had to add:

cheery@ruttunen:~/Documents/g386$ readelf --sections dynamic_hello.app 
There are 5 section headers, starting at offset 0x1b9:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .shstrndx         STRTAB          00000000 000281 000024 00      0   0  1
  [ 2] .dynamic          DYNAMIC         00000000 0000b0 000050 08  WA  3   0  4
  [ 3] .dynstr           STRTAB          00000000 000158 000020 00   A  0   0  1
  [ 4] .dynsym           DYNSYM          00000000 000100 000040 10   A  3   0  4
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

It doesn't hurt if you put in more sections than these, but this is enough to get dynamic linking working.

Cheery