5

i'm trying to create a dynamically linked executable (elf_i386) without gcc. The program is very simple (only a printf)...here the commands:

$ gcc -c simple.c
$ ld -o simple -dynamic-linker /lib/ld-linux.so.2 --entry main /usr/lib/crt1.o /usr/lib/crti.o simple.o -lc /usr/lib/crtn.o

The executable is created and also file command and ldd command show the right output... However when i launch the program after the call to printf i get a segmentation fault...i've examined with objdump the executable and i think the problem is about the dtors...seems that compiling with:

$gcc -o simple simple.c

a section .dtors is present while it is not present inside the executable created directly with ld :(

Any ideas?

hjpotter92
  • 78,589
  • 36
  • 144
  • 183
MirkoBanchi
  • 2,173
  • 5
  • 35
  • 52

2 Answers2

7

Lose the --entry main. main isn't your entry point, _start is. Try this:

$ gcc -c hello.c
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o hello.o -lc /usr/lib/crtn.o
$ ./hello
hello, world
$ 
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • And for x86_64 + C++, use this : ld -o hello hello.o --dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o -lstdc++ -lc /usr/lib64/crtn.o -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2/ -lgcc_s -L /usr/lib64 Replace the .../x86_64-redhat-linux/ dir with the right path to your libstd++.so, use "g++ -print-search-dirs" – ACyclic Sep 28 '13 at 04:21
  • thank you, the magic is -dynamic-linker /lib/ld-linux* /lib/crt* – Eduen Sarceño Apr 22 '17 at 07:50
2

It is not necessary to include the C run time environment i guess unless you are using return from your main().

We can strip the CRT and just link using :

ld -o hello -lc -dynamic-linker /lib/ld-linux.so.2 hello.o -e main

Will work.

Tarunn
  • 1,038
  • 3
  • 23
  • 45
  • 1
    This works on Linux with glibc because glibc uses dynamic linking hooks to get its startup functions called. If you statically link glibc and call functions like printf or malloc without having manually called its init functions, you will segfault. https://stackoverflow.com/questions/36861903/assembling-32-bit-binaries-on-a-64-bit-system-gnu-toolchain – Peter Cordes Nov 08 '17 at 15:21
  • 1
    Other platforms, like MinGW, don't have this, and you need to manually call libc init functions from `_start` before you can use some functions. – Peter Cordes Nov 08 '17 at 15:25