CPSC 422/522: Operating Systems


Homework: dynamic linking

Read: xv6 chapter 9 and ELF chapter 2, especially the section on Dynamic Linking.

Hand-In Procedure

You are to turn in this homework during lecture. Please write up your answers to the exercises below and hand them in to a staff member at the beginning of lecture.

Assignment

In this homework you will explore dynamic linking in the context of Linux, since xv6 does not support dynamic linking.

Enter the following trivial program test.c on a Linux x86 machine, such as any of the Zoo machines:

#include <stdio.h>

int main()
{
        printf("%p\n", stdin);
}

First, compile it to both dynamically-linked and statically-linked executables, as follows:

$ gcc -m32 -o test-dynamic test.c
$ gcc -m32 -static -o test-static test.c
$ ls -l test-*

Turn in: How big is each version of the program, and what accounts for this difference in executable size? Use the nm command to get a clearer picture of exactly what all each executable contains. Why are a few symbols marked 'U' in test-dynamic and 'T' in test-static?

Note that not all the contents of executables such as these actually get loaded into memory when running the program normally — a lot of space is typically consumed by symbol/debugging information that only debuggers and utilities like nm look at. You can remove this symbol/debugging information using the strip command to get an idea of the sizes of the "bare-bones" executable content that actually does get loaded into memory when you run the program, but the difference between dynamically-linked and statically-linked executables should be quite apparent either way.

Now compile test.c to two different assembly language files (not .o files) with and without the -fPIC option, and compare the differences, as follows:

$ gcc -m32 -S -o test.s test.c
$ gcc -m32 -S -fPIC -o test-pic.s test.c
$ diff -c test.s test-pic.s >test.diff

The -fPIC option tells GCC to create position-independent code (PIC), which is how ELF dynamic link libraries must be compiled so that they can be loaded at any virtual address instead of being fixed at a particular virtual address like normal ELF executables are.

Print the resulting test.diff and study it to see if you can figure out exactly what the compiler is doing to make the code position-independent. See the Dynamic Linking section of the ELF specification, particularly the part on the Global Offset Table (GOT) and the Procedure Linkage Table (PLT), for important clues.

Turn in: Annotate your printout with brief comments describing what is happening where in the PIC version of the code, and why.

This completes the homework.


Bryan Ford, Department of Computer Science, Yale University
[an error occurred while processing this directive] Based on MIT 6.828 materials by Frans Kaashoek and others