Project 3 - Spy vs. Spy

FAQ

Updated: 14 April 2010

Final three test teams posted

See the updated project description in CMS.

Taunter double fail and GCC calling conventions (April 19)

Several people have pointed out that taunter is broken, and I agree. Taunter tries to overwrite the return address at 0($fp). But even without optimizations, GCC does not use the same calling convention as we used in class. In fact, GCC uses $fp = $sp, so taunter is overwriting the bottom slot on the opponent's stack instead of the top slot. We will leave taunter as-is for grading, but if you want to use this same approach for your code, you will need to write somewhere other than 0($fp).

Even worse: The $fp value from the opponent's register file will be a small number, something in the low half of memory (which, to the opponent's core, is its half of memory). If taunter writes to that location, it will be writing to the taunter's own half of memory. Fail: the taunter is overwriting its own stack frames.

Debugger bug (April 21)

The debugger gets stuck when a core dies and needs to be reset. Instead of resetting the core and continuing, the debugger simply loops trying keeps trying the failing instruction. If "-vvv" is not used, the error messages don't even show, so it may look like the simulation is still running. I have updated the spyvspy binaries in the course directory to fix this bug.

Pointer arithmetic in C (April 21)

When you do pointer arithmetic in C, the compiler implicitly multiplies by the size of the data type that is pointed to. For instance:

  char *byteptr = (char *)0x1000;
  byteptr[3] = color; // store one byte at memory three BYTES after ptr, so address 0x1000+3 = 0x1003
  byteptr += 5; // increments pointer by three five BYTES, to address 0x1005

  int *wordptr = (int *)0x1000;
  wordptr[3] = color4; // store one word at memory three WORDS after ptr, so address 0x1000+12 = 0x100c
  wordptr += 5; // increments pointer by three five WORDS, to address 0x1000+20 = 0x1014

From this, we can see that the following code is almost certainly a bug (two bugs, in fact), since the first statement advances by 12 cache lines instead of 3 cache lines, and the second statement advances by 8 cache lines instead of 2 cache lines:

  int *ptr = (int *)HOME_DATA_START + 3*CACHE_LINE;
  pre += 2*CACHE_LINE;

To advance by 3 cache lines (first statement) or 2 cache lines (second statement) when using integer pointers, one could do:

  int *ptr = (int *)(HOME_DATA_START + 3*CACHE_LINE);
  pre = (int *)((int)pre + 2*CACHE_LINE);
Or:
  int *ptr = (int *)HOME_DATA_START + (3*CACHE_LINE)/4;
  pre += (2*CACHE_LINE)/4;