Operating Systems 2014F: Tutorial 4
In this tutorial you will be learning how address spaces and segments are present on modern Linux systems.
For hello.c, syscall-hello.c, and csimpleshell.c (from Tutorial 2) do the following (substituting the appropriate source file for prog.c):
- Compile the program prog.c using gcc -O2 prog.c -o prog-dyn and run prog-dyn. What does it do?
- Statically compile and optimize prog.c by running gcc -O2 -static prog.c -o prog-static. How does the size compare with prog?
- See what system calls prog-static produces by running strace -o static.log ./prog-static. Do the same for prog-dyn. Which version generates more system calls?
- Using the nm command, see what symbols are defined in prog-static and prog-dyn.
- Run the command gcc -c -O2 prog.c to produce an object file. What file was produced? What symbols does it define?
- Look at the assembly code of the program by running gcc -S -O2 prog.c. What file was produced? Identify the following:
- A function call
- A system call (if any)
- A global/static variable (if any)
- A local variable
- Disassemble the object file using objdump -d. How does this disassembly compare with the output from gcc -S?
- Examine the headers of object file, dynamically linked executable, and the statically linked executable using objdump -h
- Examine the contents of object file, dynamically linked executable, and the statically linked executable using objdump -s
- Re-run all of the previous gcc commands adding the "-v" flag. What is all of that output?
- (optional) Look up the documentation for each of the system calls made by the static versions of the programs. You may need to append a 2 to the manpage invocation, e.g. "man 2 write" gets you the write system call documentation.
Code
hello.c
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello world!\n");
return 0;
}
syscall-hello.c
#include <unistd.h>
#include <sys/syscall.h>
char *buf = "Hello world!\n";
int main(int argc, char *argv) {
size_t result;
/* "man 2 write" to see arguments to write syscall */
result = syscall(SYS_write, 1, buf, 13);
return (int) result;
}