CS61C
Summer 2004
Linker Practice


Note

On your unix account computers, MIPSgcc is aliased to always use the -S option which generates assembly code. For this assignment, you'll need to unalias it in order to generate object code. So, before you start the questions, type:

% alias MIPSgcc mips-dec-ultrix4.3-gcc

Tasks

Start by downloading the files stack.c, stack.h, and teststack.c. Look at the code and learn what it does.

From class, we know that the compiler executes the following steps to make your executable:

  1. takes your source files and creates assembly files
  2. takes your assembly files and creates object files
  3. takes your object files and makes an executable file

Right now, we'll tell the compiler to do steps one and two, but to stop before doing 3. To do this, we use the MIPSgcc -c option like this:

MIPSgcc -c -fno-delayed-branch inputfile

Run this command on the files stack.c and teststack.c. This creates the object files stack.o and teststack.o. As we know from lecture, these object files each have a .text section where the code lives, a .data section where some of the data lives, a symbol table that indicates where the symbols are defined, etc. If you were to open these files in a normal text editor, however, you would not see these sections. This is because the file is already binary. To read these files, use a utility called an object dumper. The one we will be using is MIPSobjdump. Invoke it on the two object files like this:

MIPSobjdump -x -d stack.o > stack.o.dump 

MIPSobjdump -x -d teststack.o > teststack.o.dump 

The -x option tells MIPSobjdump to print information about all of the sections and the -d option tells it to disassemble the instructions in the .text section. Open the .dump files in your favorite text editor and look them over. There will be many fields that you do not understand but you should recognize certain things. In particular, the part that begins with the label "Sections:" tells you the section name, size size of the section, virtual memory address of the section (VMA), and some interesting flags (CONTENTS, ALLOC, etc.)

Question i: When the object files are created, the absolute addresses of functions and data are unknown. Instead, relative addresses are specified in the left most column. What are the relative addresses of the functions isEmpty, Push, and Pop in stack.o?

Question ii: Look at teststack.o.dump. The main function calls several functions that are in the stack.o object file. However, at this stage of creating the executable, the addresses of those functions are unknown. What does the assembler put in place of the actual addresses in the jal instructions that call these funcitons?

Now we are going to use the linker to make an executable. To do this, we simply invoke MIPSgcc with the names of the object files. It knows based on the .o file extension that these are object files and do not require compilation or assembly. Here's how you do it:

MIPSgcc teststack.o stack.o

The output file is called a.out. It too is an object file. However, it does not have any unresolved references so it is executable. Like the other object file, opening it in a text editor is not very revealing. Instead, dump it using MIPSobjdump like we did before and open the resulting file. Note that there are MANY symbols in this file that we did not define. These are all linked in by default. You may ignore these symbols.

Question iii: What are the actual addresses of the funcitons isEmpty, Push, and Pop in a.out?

Question iv: What is the address of the structure ourStack in the final executable? What section is ourStack in?


Do it yourself!

Assume the compiler has produced the following assembly files:

main.s

      .global main

      .data
count:.word 4,1,3

      .text
main:
      addiu $sp $sp -8
      sw $ra 0($sp)   
      sw $s0 4($sp)

      la $s0 count

loop: beq $s0 $0 done
      move $a0 $s0
      jal fact
      addiu $s0 $s0 -1
      j loop

done: lw $ra 0($sp)
      lw $s0 4($sp)
      addiu $sp $sp 8
      jr $ra

fact.s

      .global fact
      .text

fact:
      li $v0 1
      beq $a0 $0 done
      mul $v0 $a0 $v0
      addi $a0 $a0 -1
      beq $0 $0 fact
done: jr $ra

Question v: Pretend you are an assembler. Provide human-readable object file equivalents to main.s and fact.s. You can use any format you like, as long as it contains enough information for the linker to relocate the labels. (Don't forget pseudos.) We suggest you use symbol/relocation tables simialr to those in lecture.

Question vi: Pretend you are a linker. Show the final text and data segments, with the main label at address 0x00000000 and the data segment starting at 0x8fff0000. Show the symbol and relocation tables with all the values filled in.