Operating Systems 2014F: Tutorial 4: Difference between revisions

From Soma-notes
No edit summary
No edit summary
 
Line 4: Line 4:
# Compile the program prog.c using <tt>gcc -O2 prog.c -o prog-dyn</tt> and run prog-dyn.  What does it do?
# Compile the program prog.c using <tt>gcc -O2 prog.c -o prog-dyn</tt> and run prog-dyn.  What does it do?
# Statically compile and optimize prog.c by running <tt>gcc -O2 -static prog.c -o prog-static</tt>.  How does the size compare with <tt>prog</tt>?
# Statically compile and optimize prog.c by running <tt>gcc -O2 -static prog.c -o prog-static</tt>.  How does the size compare with <tt>prog</tt>?
# See what system calls prog-static produces by running <tt>strace -o static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more system calls?
# See what system calls prog-static produces by running <tt>strace -o syscalls-static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more system calls?
# See what library calls prog-static produces by running <tt>ltrace -o library-static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more library calls?  (If ltrace isn't installed, run <tt>sudo apt-get install ltrace</tt>)
# Using the <tt>nm</tt> command, see what symbols are defined in prog-static and prog-dyn.
# Using the <tt>nm</tt> command, see what symbols are defined in prog-static and prog-dyn.
# Run the command <tt>gcc -c -O2 prog.c</tt> to produce an object file.  What file was produced?  What symbols does it define?
# Run the command <tt>gcc -c -O2 prog.c</tt> to produce an object file.  What file was produced?  What symbols does it define?

Latest revision as of 14:37, 26 September 2014

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):

  1. Compile the program prog.c using gcc -O2 prog.c -o prog-dyn and run prog-dyn. What does it do?
  2. Statically compile and optimize prog.c by running gcc -O2 -static prog.c -o prog-static. How does the size compare with prog?
  3. See what system calls prog-static produces by running strace -o syscalls-static.log ./prog-static. Do the same for prog-dyn. Which version generates more system calls?
  4. See what library calls prog-static produces by running ltrace -o library-static.log ./prog-static. Do the same for prog-dyn. Which version generates more library calls? (If ltrace isn't installed, run sudo apt-get install ltrace)
  5. Using the nm command, see what symbols are defined in prog-static and prog-dyn.
  6. Run the command gcc -c -O2 prog.c to produce an object file. What file was produced? What symbols does it define?
  7. 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
  8. Disassemble the object file using objdump -d. How does this disassembly compare with the output from gcc -S?
  9. Examine the headers of object file, dynamically linked executable, and the statically linked executable using objdump -h
  10. Examine the contents of object file, dynamically linked executable, and the statically linked executable using objdump -s
  11. Re-run all of the previous gcc commands adding the "-v" flag. What is all of that output?
  12. (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;
}