views:

50

answers:

2

Hey, as an exercise to learn more precisely how c programs work and what minimum level of content must exist for a program to be able to use libc, ive taken it upon myself to attempt to program primarily in x86 assembly using gas and ld. As a fun little challenge, I've successfully assembled and linked several programs linked to different self-made dynamic libraries, but i have failed to be able to code a program from scratch to use libc function calls without directly using gcc. I understand the calling conventions of individual c library functions, and have thoroughly inspected programs compiled out of gcc through use of objdump and readelf, but havent gotten anywhere as far as what information to include in a gas assembly file and what parameters to invoke in ld to successfully link to libc. Anyone have any insight to this?

btw, im running linux, using gnu toolchain on an x86 machine, to clarify the obvious.

A: 

I think something like this should work:

  1. make a simple C program
  2. gcc -S file.c
  3. edit file.s
  4. gas file.s
  5. ld file.o -lc crt1.o -o myprog
Igor Skochinsky
+1  A: 

There are at least three things that you need to do to successfully use libc with dynamic linking:

  1. Link /usr/lib/crt1.o, which contains _start, which will be the entry point for the ELF binary;
  2. Link /usr/lib/crti.o (before libc) and /usr/lib/crtn.o (after), which provide some initialisation and finalisation code;
  3. Tell the linker that the binary will use the dynamic linker, /lib/ld-linux.so.

For example:

$ cat hello.s
 .text
 .globl main
main:
 push %ebp
 mov %esp, %ebp
 pushl $hw_str
 call puts
 add $4, %esp
 xor %eax, %eax
 leave
 ret

 .data
hw_str:
 .asciz "Hello world!"

$ as -o hello.o hello.s
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc hello.o /usr/lib/crtn.o
$ ./hello
Hello world!
$
Matthew Slattery
thats extremely helpful, that clarifies alot of information. upon applying that to my code, i am getting 2 errors, "undefined reference to '__libc_csu_fini'" and"undefined reference to '__libc_csu_init'"after doing a symbol dump on all of the object files, i failed to find those symbols, and crt1.o seems to call the symbols. is there anything that could possibly have those symbols inside of their object file?
Cyro
Those come from an unshared portion of the C library; linking with `-lc` should pull in `/usr/lib/libc.so`, which is actually a linker script fragment which references the right file (`/usr/lib/libc_nonshared.a`). Maybe a problem with link order? I'm pretty sure that you want `crt1.o` followed by `crti.o` first, then your objects and libraries, then `crtn.o` right at the end - but maybe `-lc` should come after your objects (just before `crtn.o`), not before.
Matthew Slattery
I went ahead and simply linked with /usr/lib/libc_nonshared.a right after typing in -lc and the whole thing worked! thanks a million!
Cyro