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, I've 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 haven't 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?
I'm running Linux, on an x86 machine.
The ld utility combines object files and archive files into an output executable file, resolving external references. ld runs the Program Management Binder. To export the trace output to a z/OS UNIX file, use the _LD_DEBUG_TRACE environment variable.
In Unix-like systems, the traditional place for the basic system libraries is /lib/ , with many additional libraries are found in /usr/lib/ , sometimes in sub-directories. Furthermore, locally built libraries are traditionally placed in /usr/local/lib/ .
The GNU Assembler, commonly known as gas or as, is the assembler developed by the GNU Project. It is the default back-end of GCC. It is used to assemble the GNU operating system and the Linux kernel, and various other software. It is a part of the GNU Binutils package.
There are at least three things that you need to do to successfully use libc with dynamic linking:
/usr/lib/crt1.o
, which contains _start
, which will be the entry point for the ELF binary;/usr/lib/crti.o
(before libc) and /usr/lib/crtn.o
(after), which provide some initialisation and finalisation code;/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!
$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With