Update Checkbochs patches.
[pintos-anon] / src / misc / checkbochs.patch
1 diff -X ignore -urpN pintos.orig/src/lib/debug.h pintos.eraser/src/lib/debug.h
2 --- pintos.orig/src/lib/debug.h 2005-06-18 20:20:49.000000000 -0700
3 +++ pintos.eraser/src/lib/debug.h       2005-06-29 22:38:01.000000000 -0700
4 @@ -1,6 +1,8 @@
5  #ifndef __LIB_DEBUG_H
6  #define __LIB_DEBUG_H
7  
8 +#include <eraser.h>
9 +
10  /* GCC lets us add "attributes" to functions, function
11     parameters, etc. to indicate their properties.
12     See the GCC manual for details. */
13 @@ -27,10 +29,13 @@ void debug_backtrace (void);
14  #undef NOT_REACHED
15  
16  #ifndef NDEBUG
17 -#define ASSERT(CONDITION)                                       \
18 -        if (CONDITION) { } else {                               \
19 -                PANIC ("assertion `%s' failed.", #CONDITION);   \
20 -        }
21 +#define ASSERT(CONDITION)                                               \
22 +        do {                                                            \
23 +          eraser_ignore_on ();                                         \
24 +          if (!(CONDITION))                                             \
25 +            PANIC ("assertion `%s' failed.", #CONDITION);               \
26 +          eraser_ignore_off ();                                         \
27 +        } while (0)
28  #define NOT_REACHED() PANIC ("executed an unreachable statement");
29  #else
30  #define ASSERT(CONDITION) ((void) 0)
31 diff -X ignore -urpN pintos.orig/src/lib/eraser.h pintos.eraser/src/lib/eraser.h
32 --- pintos.orig/src/lib/eraser.h        1969-12-31 16:00:00.000000000 -0800
33 +++ pintos.eraser/src/lib/eraser.h      2005-07-02 16:12:28.000000000 -0700
34 @@ -0,0 +1,115 @@
35 +#ifndef __LIB_ERASER_H
36 +#define __LIB_ERASER_H
37 +
38 +/* New instruction to indicate the lock at ECX is locked. */
39 +#define ERASER_LOCK ".byte 0x0f, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00;"
40 +
41 +/* New instruction to indicate the lock at ECX is unlocked. */
42 +#define ERASER_UNLOCK ".byte 0x0f, 0x04, 0x18, 0x00, 0x00, 0x00, 0x00;"
43 +
44 +/* New instruction for various Eraser purposes.
45 +   EAX indicates an operation subcode.
46 +   ECX, EDX may be used for arguments. */
47 +#define ERASER_OPS ".byte 0x0f, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00;"
48 +
49 +/* Operation subcodes for ERASER_OPS. */
50 +#define ERASER_OP_IGNORE        0 /* Suppress warnings for ECX bytes at EDX. */
51 +#define ERASER_OP_INIT_LOCK     1 /* New lock at ECX. */
52 +#define ERASER_OP_IGNORE_ON     2 /* Suppress all warnings. */
53 +#define ERASER_OP_IGNORE_OFF    3 /* Re-enable warnings. */
54 +#define ERASER_OP_REUSE         4 /* ECX bytes at EDX are (re)allocated. */
55 +#define ERASER_OP_DBG_MARK      5 /* Debug message for file EDX, line ECX. */
56 +#define ERASER_OP_STARTUP       6 /* Start tracking locks. */
57 +
58 +/* Returns true if running under Checkbochs, false otherwise. */
59 +static inline bool
60 +running_on_checkbochs (void)
61 +{
62 +  unsigned dummy, cpuid;
63 +  asm ("cpuid"
64 +       : "=a" (dummy), "=b" (cpuid)
65 +       : "0" (3), "1" (0)
66 +       : "ecx", "edx");
67 +  return cpuid == 0x6e696154;
68 +}
69 +
70 +/* Registers LOCK as a lock. */
71 +static inline void
72 +eraser_init (unsigned lock)
73 +{
74 +  if (running_on_checkbochs ())
75 +    asm volatile (ERASER_OPS :: "a" (ERASER_OP_INIT_LOCK), "c" (lock));
76 +}
77 +
78 +/* Indicates that LOCK is locked. */
79 +static inline void
80 +eraser_lock (unsigned lock)
81 +{
82 +  if (running_on_checkbochs ())
83 +    {
84 +      asm volatile (ERASER_LOCK :: "c" (lock));
85 +      eraser_ignore ((void *) lock, 4);
86 +    }
87 +}
88 +
89 +/* Indicates that LOCK is unlocked. */
90 +static inline void
91 +eraser_unlock (unsigned lock)
92 +{
93 +  if (running_on_checkbochs ())
94 +    asm volatile (ERASER_UNLOCK :: "c" (lock));
95 +}
96 +
97 +/* Suppresses warnings for LENGTH bytes starting at START. */
98 +static inline void
99 +eraser_ignore (void *start, size_t length)
100 +{
101 +  if (running_on_checkbochs ())
102 +    asm volatile (ERASER_OPS
103 +                  :: "a" (ERASER_OP_IGNORE), "d" (start), "c" (length));
104 +}
105 +
106 +/* Suppresses all warnings. */
107 +static inline void
108 +eraser_ignore_on (void)
109 +{
110 +  if (running_on_checkbochs ())
111 +    asm volatile (ERASER_OPS :: "a" (ERASER_OP_IGNORE_ON));
112 +}
113 +
114 +/* Re-enables warnings. */
115 +static inline void
116 +eraser_ignore_off (void)
117 +{
118 +  if (running_on_checkbochs ())
119 +    asm volatile (ERASER_OPS :: "a" (ERASER_OP_IGNORE_OFF));
120 +}
121 +
122 +/* Indicates that LENGTH bytes starting at START have been
123 +   (re)allocated. */
124 +static inline void
125 +eraser_reuse (void *start, size_t length)
126 +{
127 +  if (running_on_checkbochs ())
128 +    asm volatile (ERASER_OPS
129 +                  :: "a" (ERASER_OP_REUSE), "d" (start), "c" (length));
130 +}
131 +
132 +/* Emits a debug message for the source file and line number of
133 +   the caller. */
134 +#define eraser_debug_mark() do {                        \
135 +  if (running_on_checkbochs ())                         \
136 +    asm volatile (ERASER_OPS                            \
137 +                  :: "a" (ERASER_OP_DBG_MARK),          \
138 +                     "d" (__FILE__), "c" (__LINE__));   \
139 +} while (0)
140 +
141 +/* Starts up the lock checking algorithm. */
142 +static inline void
143 +eraser_startup (void)
144 +{
145 +  if (running_on_checkbochs ())
146 +    asm volatile (ERASER_OPS :: "a" (ERASER_OP_STARTUP));
147 +}
148 +
149 +#endif /* lib/eraser.h */
150 diff -X ignore -urpN pintos.orig/src/threads/init.c pintos.eraser/src/threads/init.c
151 --- pintos.orig/src/threads/init.c      2005-06-18 20:21:19.000000000 -0700
152 +++ pintos.eraser/src/threads/init.c    2005-07-02 16:13:32.000000000 -0700
153 @@ -132,6 +132,8 @@ main (void)
154  #endif
155  
156    printf ("Boot complete.\n");
157 +
158 +  eraser_startup ();
159    
160    /* Run actions specified on kernel command line. */
161    run_actions (argv);
162 diff -X ignore -urpN pintos.orig/src/threads/interrupt.c pintos.eraser/src/threads/interrupt.c
163 --- pintos.orig/src/threads/interrupt.c 2005-06-18 20:21:19.000000000 -0700
164 +++ pintos.eraser/src/threads/interrupt.c       2005-06-29 22:38:37.000000000 -0700
165 @@ -135,6 +135,8 @@ intr_init (void)
166    intr_names[17] = "#AC Alignment Check Exception";
167    intr_names[18] = "#MC Machine-Check Exception";
168    intr_names[19] = "#XF SIMD Floating-Point Exception";
169 +
170 +  eraser_ignore (&in_external_intr, 4);
171  }
172  
173  /* Registers interrupt VEC_NO to invoke HANDLER with descriptor
174 diff -X ignore -urpN pintos.orig/src/threads/malloc.c pintos.eraser/src/threads/malloc.c
175 --- pintos.orig/src/threads/malloc.c    2005-06-18 20:21:19.000000000 -0700
176 +++ pintos.eraser/src/threads/malloc.c  2005-07-02 16:17:07.000000000 -0700
177 @@ -150,6 +150,7 @@ malloc (size_t size) 
178    a = block_to_arena (b);
179    a->free_cnt--;
180    lock_release (&d->lock);
181 +  eraser_reuse (b, size);
182    return b;
183  }
184  
185 @@ -171,6 +172,7 @@ calloc (size_t a, size_t b) 
186    if (p != NULL)
187      memset (p, 0, size);
188  
189 +  eraser_reuse (p, size);
190    return p;
191  }
192  
193 @@ -228,6 +230,7 @@ free (void *p) 
194          {
195            /* It's a normal block.  We handle it here. */
196  
197 +          eraser_reuse (b, d->block_size);
198  #ifndef NDEBUG
199            /* Clear the block to help detect use-after-free bugs. */
200            memset (b, 0xcc, d->block_size);
201 diff -X ignore -urpN pintos.orig/src/threads/palloc.c pintos.eraser/src/threads/palloc.c
202 --- pintos.orig/src/threads/palloc.c    2005-06-18 20:21:19.000000000 -0700
203 +++ pintos.eraser/src/threads/palloc.c  2005-07-02 16:16:18.000000000 -0700
204 @@ -104,6 +104,7 @@ palloc_get_multiple (enum palloc_flags f
205          PANIC ("palloc_get: out of pages");
206      }
207  
208 +  eraser_reuse (pages, PGSIZE * page_cnt);
209    return pages;
210  }
211  
212 @@ -139,6 +140,7 @@ palloc_free_multiple (void *pages, size_
213  
214    page_idx = pg_no (pages) - pg_no (pool->base);
215  
216 +  eraser_reuse (pages, PGSIZE * page_cnt);
217  #ifndef NDEBUG
218    memset (pages, 0xcc, PGSIZE * page_cnt);
219  #endif
220 diff -X ignore -urpN pintos.orig/src/threads/synch.c pintos.eraser/src/threads/synch.c
221 --- pintos.orig/src/threads/synch.c     2005-06-18 20:21:19.000000000 -0700
222 +++ pintos.eraser/src/threads/synch.c   2005-06-29 22:48:42.000000000 -0700
223 @@ -179,6 +179,7 @@ lock_init (struct lock *lock)
224  
225    lock->holder = NULL;
226    sema_init (&lock->semaphore, 1);
227 +  eraser_init (lock);
228  }
229  
230  /* Acquires LOCK, sleeping until it becomes available if
231 @@ -200,6 +201,7 @@ lock_acquire (struct lock *lock)
232  
233    old_level = intr_disable ();
234    sema_down (&lock->semaphore);
235 +  eraser_lock (lock);
236    lock->holder = thread_current ();
237    intr_set_level (old_level);
238  }
239 @@ -245,6 +247,7 @@ lock_release (struct lock *lock) 
240    lock->holder = NULL;
241    sema_up (&lock->semaphore);
242    intr_set_level (old_level);
243 +  eraser_unlock (lock);
244  }
245  
246  /* Returns true if the current thread holds LOCK, false
247 @@ -253,9 +256,15 @@ lock_release (struct lock *lock) 
248  bool
249  lock_held_by_current_thread (const struct lock *lock) 
250  {
251 +  bool ret;
252 +
253    ASSERT (lock != NULL);
254  
255 -  return lock->holder == thread_current ();
256 +  eraser_ignore_on ();
257 +  ret = lock->holder == thread_current ();
258 +  eraser_ignore_off ();
259 +
260 +  return ret;
261  }
262  \f
263  /* One semaphore in a list. */
264 diff -X ignore -urpN pintos.orig/src/threads/thread.c pintos.eraser/src/threads/thread.c
265 --- pintos.orig/src/threads/thread.c    2005-06-18 20:21:20.000000000 -0700
266 +++ pintos.eraser/src/threads/thread.c  2005-07-02 16:16:03.000000000 -0700
267 @@ -85,6 +85,7 @@ thread_init (void) 
268    init_thread (initial_thread, "main", PRI_DEFAULT);
269    initial_thread->status = THREAD_RUNNING;
270    initial_thread->tid = allocate_tid ();
271 +  eraser_ignore (&initial_thread->status, 4);
272  }
273  
274  /* Starts preemptive thread scheduling by enabling interrupts.
275 @@ -157,6 +158,9 @@ thread_create (const char *name, int pri
276    if (t == NULL)
277      return TID_ERROR;
278  
279 +  eraser_ignore (&t->status, 4);
280 +  eraser_ignore_on ();
281 +
282    /* Initialize thread. */
283    init_thread (t, name, priority);
284    tid = t->tid = allocate_tid ();
285 @@ -175,6 +179,8 @@ thread_create (const char *name, int pri
286    sf = alloc_frame (t, sizeof *sf);
287    sf->eip = switch_entry;
288  
289 +  eraser_ignore_off ();
290 +
291    /* Add to run queue. */
292    thread_unblock (t);
293  
294 @@ -361,6 +367,7 @@ kernel_thread (thread_func *function, vo
295  {
296    ASSERT (function != NULL);
297  
298 +  eraser_lock (thread_current ()->tid);
299    intr_enable ();       /* The scheduler runs with interrupts off. */
300    function (aux);       /* Execute the thread function. */
301    thread_exit ();       /* If function() returns, kill the thread. */
302 @@ -396,12 +403,16 @@ init_thread (struct thread *t, const cha
303    ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
304    ASSERT (name != NULL);
305  
306 +  eraser_ignore_on ();
307 +
308    memset (t, 0, sizeof *t);
309    t->status = THREAD_BLOCKED;
310    strlcpy (t->name, name, sizeof t->name);
311    t->stack = (uint8_t *) t + PGSIZE;
312    t->priority = priority;
313    t->magic = THREAD_MAGIC;
314 +
315 +  eraser_ignore_off ();
316  }
317  
318  /* Allocates a SIZE-byte frame at the top of thread T's stack and
319 @@ -471,7 +482,7 @@ schedule_tail (struct thread *prev) 
320    if (prev != NULL && prev->status == THREAD_DYING) 
321      {
322        ASSERT (prev != cur);
323 -      if (prev != initial_thread)
324 +      if (prev != initial_thread) 
325          palloc_free_page (prev);
326      }
327  }
328 diff -X ignore -urpN pintos.orig/src/userprog/tss.c pintos.eraser/src/userprog/tss.c
329 --- pintos.orig/src/userprog/tss.c      2004-09-22 17:58:29.000000000 -0700
330 +++ pintos.eraser/src/userprog/tss.c    2005-06-29 22:41:09.000000000 -0700
331 @@ -84,6 +84,8 @@ tss_init (void) 
332    tss->esp0 = ptov(0x20000);
333    tss->ss0 = SEL_KDSEG;
334    tss->bitmap = 0xdfff;
335 +
336 +  eraser_ignore (tss, sizeof *tss);
337  }
338  
339  /* Returns the kernel TSS. */