Team LiB
Previous Section Next Section

Using a Dynamic Library

The program we will examine here is simple - it writes the characters hello world to the screen and exits. The regular program, helloworld-nolib. s, looks like this:

#PURPOSE:  This program writes the message "hello world" and
#          exits
#

 .include "linux.s"

 .section .data


helloworld:
 .ascii "hello world\n"
helloworld_end:

 .equ helloworld_len, helloworld_end - helloworld

 .section .text
 .globl _start
_start:
 movl  $STDOUT, %ebx
 movl  $helloworld, %ecx
 movl  $helloworld_len, %edx
 movl  $SYS_WRITE, %eax
 int   $LINUX_SYSCALL

 movl  $0, %ebx
 movl  $SYS_EXIT, %eax
 int   $LINUX_SYSCALL

That's not too long. However, take a look at how short helloworld-lib is which uses a library:

#PURPOSE:  This program writes the message "hello world" and
#          exits
#

 .section .data

helloworld:
 .ascii "hello world\n\0"

 .section .text
 .globl _start
_start:
 pushl $helloworld
 call  printf

 pushl $0
 call  exit

It's even shorter!

Now, building programs which use dynamic libraries is a little different than normal. You can build the first program normally by doing this:

as helloworld-nolib.s -o helloworld-nolib.o
ld helloworld-nolib.o -o helloworld-nolib

However, in order to build the second program, you have to do this:

as helloworld-lib.s -o helloworld-lib.o
ld -dynamic-linker /lib/ld-linux.so.2 \
   -o helloworld-lib helloworld-lib.o -1c

Remember, the backslash in the first line simply means that the command continues on the next line. The option -dynamic-linker /lib/ld-linux.so.2 allows our program to be linked to libraries. This builds the executable so that before executing, the operating system will load the program /lib/ld-linux.so.2 to load in external libraries and link them with the program. This program is known as a dynamic linker.

The -lc option says to link to the c library, named libc.so on GNU/Linux systems. Given a library name, c in this case (usually library names are longer than a single letter), the GNU/Linux linker prepends the string lib to the beginning of the library name and appends .so to the end of it to form the library's filename. This library contains many functions to automate all types of tasks. The two we are using are printf, which prints strings, and exit, which exits the program.

Notice that the symbols printf and exit are simply referred to by name within the program. In previous chapters, the linker would resolve all of the names to physical memory addresses, and the names would be thrown away. When using dynamic linking, the name itself resides within the executable, and is resolved by the dynamic linker when it is run. When the program is run by the user, the dynamic linker loads the dynamic libraries listed in our link statement, and then finds all of the function and variable names that were named by our program but not found at link time, and matches them up with corresponding entries in the shared libraries it loads. It then replaces all of the names with the addresses which they are loaded at. This sounds time-consuming. It is to a small degree, but it only happens once - at program startup time.


Team LiB
Previous Section Next Section