Session 01: The Software Stack¶
This session is about what sits between a C program and the kernel, and how such a program is built and linked.
Learning objectives¶
By the end of this session you should be able to:
- Explain the software layers between a C program and the kernel: application, the standard C library (libc), and system calls.
- Implement basic string-handling functions typically part of libc (
strlen(),strcpy(),strcat(),memcpy()) and reason about their algorithmic cost. - Compare buffered (
printf()) and unbuffered (write()) output functions, and explain the buffering trade-off from measured data. - Build a static library and a shared library, and link a C program against each, as well as into a dynamically-linked and a statically-linked executable.
- Use
file,lddandnmto tell where a symbol is resolved: at link time or at load time. - Explain the difference between static linking (
.a,ar) and dynamic linking (.so).
Prerequisites and required tools¶
- Prior knowledge of C syntax.
- A Linux environment with
gcc,make,ar,file,ldd,nm,objdump,straceandtimeinstalled. - Comfort with the command line: running commands, redirecting output, reading
manpages.
Check that your system has all it needs for the lab, by downloading and running the check-prerequisites.sh script:
wget -O check-prerequisites.sh http://raw.githubusercontent.com/cs-pub-ro/operating-systems/refs/heads/main/scripts/check-prerequisites.sh
chmod a+x check-prerequisites.sh
./check-prerequisites.sh
The script installs nothing. It reports what is missing and prints the command that installs it on your distribution.
If something is missing, be sure to install and configure it.
Getting the lab archive¶
Download 01-software-stack.zip, then unzip it and change into the directory it creates:
wget -O 01-software-stack.zip https://github.com/cs-pub-ro/operating-systems/raw/lab-archives/01-software-stack.zip
unzip 01-software-stack.zip
cd 01-software-stack/
Work inside that directory for the rest of the session.
Exercise order¶
Each exercise has a directory.
Inside each exercise directory there is README.md file with instructions about the exercise.
There are three types of exercises that are to be worked on in order.
Demos come first, solved together with the teaching assistant. Core exercises are then solved individually or in teams, in the numeric order shown. Bonus exercises are optional: start them if you finish the core exercises, or take them home.
| Order | Exercise | Type | Objective |
|---|---|---|---|
| 1 | demo-printf-vs-write |
Demo | See why printf() can be faster or slower than write(), depending on buffering. |
| 2 | demo-copy-string |
Demo | Compare strcat()-based and strcpy()-based string building. |
| 3 | 01-string-functions |
Core | Implement strlen(), strcpy(), strcat() and memcpy() from scratch, and test them. |
| 4 | 02-xor-encryption |
Core | Follow a guided build of a static and a shared library, and of a program linked against each. |
| 5 | 03-stream-ciphers |
Core | Build the same program as a dynamic executable, a static executable, and against a shared and a static library; then write the Makefile rules. |
| 6 | bonus-static-vs-dynamic |
Bonus | Package your string functions as a static and a shared library, and measure static vs dynamic call and start-up cost. |
| 7 | bonus-per-stream-cipher-exec |
Bonus | Split the cipher program into one dedicated executable per cipher, in all four link formats. |
03-stream-ciphers repeats on your own what 02-xor-encryption walks you through.
bonus-static-vs-dynamic reuses your solution to 01-string-functions, and bonus-per-stream-cipher-exec reuses the commands from 03-stream-ciphers, so do the core exercises first.
Where there is also a FURTHER.md, it holds optional extensions and questions to dig into once the task is done.
Go through it only after completing all other exercises.