1

For learning purposes I've created (using a hex editor and some macros) the following ELF file:

hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

xxd hello.o:

00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0100 3e00 0100 0000 0000 0000 0000 0000  ..>.............
00000020: 0000 0000 0000 0000 4000 0000 0000 0000  ........@.......
00000030: 0000 0000 4000 3800 0000 4000 0400 0300  ....@.8...@.....
00000040: 0c00 0000 0300 0000 2000 0000 0000 0000  ........ .......
00000050: 0000 0000 0000 0000 4001 0000 0000 0000  ........@.......
00000060: 0600 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0600 0000 0100 0000 2200 0000 0000 0000  ........".......
00000090: 0000 0000 0000 0000 4601 0000 0000 0000  ........F.......
000000a0: 0e00 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 1400 0000 0200 0000 2000 0000 0000 0000  ........ .......
000000d0: 0000 0000 0000 0000 5401 0000 0000 0000  ........T.......
000000e0: 1800 0000 0000 0000 0300 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 1800 0000 0000 0000  ................
00000100: 1c00 0000 0300 0000 2000 0000 0000 0000  ........ .......
00000110: 0000 0000 0000 0000 6c01 0000 0000 0000  ........l.......
00000120: 2600 0000 0000 0000 0000 0000 0000 0000  &...............
00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000140: 6865 6c6c 6f00 4865 6c6c 6f2c 2077 6f72  hello.Hello, wor
00000150: 6c64 2100 0000 0000 1100 0100 0000 0000  ld!.............
00000160: 0000 0000 0e00 0000 0000 0000 6865 6c6c  ............hell
00000170: 6f00 2e64 6174 6100 2e73 7472 7461 6200  o..data..strtab.
00000180: 2e73 796d 7461 6200 2e73 6873 7472 7461  .symtab..shstrta
00000190: 6200                                     b.

I wish to link it together with a C program (main.c):

#include <stdio.h>

extern char hello[];

int main() {
    printf("%s\n", hello);
    return 0;
}

However, running gcc main.o hello.o shows an error:

/usr/bin/ld: main.o: in function `main':
main.c:(.text+0x7): undefined reference to `hello'
collect2: error: ld returned 1 exit status

readelf -s hello.o:

Symbol table '.symtab' contains 1 entry:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000    14 OBJECT  GLOBAL DEFAULT    1 hello

(readelf output is similar to object files created by GCC)

Why doesn't GCC accept my created object file?

1
+100

I tried running the same commands as you with the file you provided but it failed in the same way as yours. However with a newer hellow.c as such

char hello[] = "Hello World";

with the following commands it worked

$ gcc -c hellow.c
$ gcc main.c hellow.o -o main
$ ./main
Hello World

There are some key differences between hellow.o and your hello.o

$ nm hellow.o
0000000000000000 D hello
$ nm hello.o 
nm: hello.o: no symbols
$ readelf -s hellow.o
Symbol table '.symtab' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hellow.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    2 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     7: 0000000000000000    12 OBJECT  GLOBAL DEFAULT    2 hello

If we strip hellow.o it won't work as expected. The file looks like this

$ xxd hellow.o
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0100 3e00 0100 0000 0000 0000 0000 0000  ..>.............
00000020: 0000 0000 0000 0000 9801 0000 0000 0000  ................
00000030: 0000 0000 4000 0000 0000 4000 0900 0800  ....@.....@.....
00000040: 4865 6c6c 6f20 576f 726c 6400 0047 4343  Hello World..GCC
00000050: 3a20 2844 6562 6961 6e20 362e 332e 302d  : (Debian 6.3.0-
00000060: 3138 2b64 6562 3975 3129 2036 2e33 2e30  18+deb9u1) 6.3.0
00000070: 2032 3031 3730 3531 3600 0000 0000 0000   20170516.......
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0100 0000 0400 f1ff  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0300 0100 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0300 0200  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0300 0300 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0300 0500  ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0300 0400 0000 0000 0000 0000  ................
00000120: 0000 0000 0000 0000 0a00 0000 1100 0200  ................
00000130: 0000 0000 0000 0000 0c00 0000 0000 0000  ................
00000140: 0068 656c 6c6f 772e 6300 6865 6c6c 6f00  .hellow.c.hello.
00000150: 002e 7379 6d74 6162 002e 7374 7274 6162  ..symtab..strtab
00000160: 002e 7368 7374 7274 6162 002e 7465 7874  ..shstrtab..text
00000170: 002e 6461 7461 002e 6273 7300 2e63 6f6d  ..data..bss..com
00000180: 6d65 6e74 002e 6e6f 7465 2e47 4e55 2d73  ment..note.GNU-s
00000190: 7461 636b 0000 0000 0000 0000 0000 0000  tack............
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001d0: 0000 0000 0000 0000 1b00 0000 0100 0000  ................
000001e0: 0600 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 4000 0000 0000 0000 0000 0000 0000 0000  @...............
00000200: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000210: 0000 0000 0000 0000 2100 0000 0100 0000  ........!.......
00000220: 0300 0000 0000 0000 0000 0000 0000 0000  ................
00000230: 4000 0000 0000 0000 0c00 0000 0000 0000  @...............
00000240: 0000 0000 0000 0000 0800 0000 0000 0000  ................
00000250: 0000 0000 0000 0000 2700 0000 0800 0000  ........'.......
00000260: 0300 0000 0000 0000 0000 0000 0000 0000  ................
00000270: 4c00 0000 0000 0000 0000 0000 0000 0000  L...............
00000280: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000290: 0000 0000 0000 0000 2c00 0000 0100 0000  ........,.......
000002a0: 3000 0000 0000 0000 0000 0000 0000 0000  0...............
000002b0: 4c00 0000 0000 0000 2e00 0000 0000 0000  L...............
000002c0: 0000 0000 0000 0000 0100 0000 0000 0000  ................
000002d0: 0100 0000 0000 0000 3500 0000 0100 0000  ........5.......
000002e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002f0: 7a00 0000 0000 0000 0000 0000 0000 0000  z...............
00000300: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000310: 0000 0000 0000 0000 0100 0000 0200 0000  ................
00000320: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000330: 8000 0000 0000 0000 c000 0000 0000 0000  ................
00000340: 0700 0000 0700 0000 0800 0000 0000 0000  ................
00000350: 1800 0000 0000 0000 0900 0000 0300 0000  ................
00000360: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000370: 4001 0000 0000 0000 1000 0000 0000 0000  @...............
00000380: 0000 0000 0000 0000 0100 0000 0000 0000  ................
00000390: 0000 0000 0000 0000 1100 0000 0300 0000  ................
000003a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003b0: 5001 0000 0000 0000 4500 0000 0000 0000  P.......E.......
000003c0: 0000 0000 0000 0000 0100 0000 0000 0000  ................
000003d0: 0000 0000 0000 0000                      ........
  • If nothing else comes up, I'm going to award the bounty to your answer, because by taking a closer look at the symbols, I realized that I was missing an empty, zero-filled symbol which ELF files require. After the change, GCC and Clang still refuse to link the files, but it works with TCC. The original question still stands - what magic does GCC and Clang expect in object files that I'm missing? – PhilipRoman Feb 18 '20 at 17:48
  • I am reading source code for nm. Will update when I find what's the reason for this. – sudhackar Feb 18 '20 at 18:13
  • elf_slurp_symbol_table from elfcode.h in binutils returns 0 for your file for nm to read symbols for nm. Then the error is printed out from display_rel_file in line nm.c:1126 for binutils 2.34 for me. – sudhackar Feb 19 '20 at 8:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.