strace: Fix issues with a few syscalls
[akaros.git] / kern / src / err.c
1 /*
2  * Copyright 2013 Google Inc.
3  */
4 //#define DEBUG
5 #include <setjmp.h>
6 #include <slab.h>
7 #include <kmalloc.h>
8 #include <kref.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12 #include <error.h>
13 #include <cpio.h>
14 #include <pmap.h>
15 #include <smp.h>
16 #include <err.h>
17
18 /* General idea: if we're at the base for this func (base of ERRSTACK in the
19  * scope where ERRSTACK and waserror are used), we need to find and save the
20  * previous errbuf, so we know how to pop back.
21  *
22  * The main goal of this is to track and advertise (via pcpui) the errbuf that
23  * should be jumped to next (when we call error()).  Note that the caller of
24  * this (waserror()) will fill the jumpbuf shortly with its context.
25  *
26  * When we enter, curindex points to the slot we should use.  First time, it is
27  * 0, and we'll set cur_eb to slot 0.  When we leave, curindex is set to the
28  * next free slot. */
29 struct errbuf *errpush(struct errbuf *errstack, int stacksize, int *curindex,
30                                            struct errbuf **prev_errbuf)
31 {
32         struct errbuf *cbuf;
33
34         printd("pushe %p %d %dp\n", errstack, stacksize, *curindex);
35         if (*curindex == 0)
36                 *prev_errbuf = get_cur_errbuf();
37
38         if (*curindex >= stacksize)
39                 panic("Error stack overflow");
40
41         cbuf = &errstack[*curindex];
42         set_cur_errbuf(cbuf);
43         (*curindex)++;
44
45         return cbuf;
46 }
47
48 /* Undo the work of errpush, and advertise the new errbuf used by error() calls.
49  * We only need to be tricky when we reached the beginning of the stack and need
50  * to check the prev_errbuf from a previous ERRSTACK/function.
51  *
52  * When we enter, curindex is the slot of the next *free* errstack (the one we'd
53  * push into if we were pushing.  When we leave, it will be decreased by one,
54  * and will still point to the next free errstack (the one we are popping).
55  * */
56 struct errbuf *errpop(struct errbuf *errstack, int stacksize, int *curindex,
57                                           struct errbuf *prev_errbuf)
58 {
59         struct errbuf *cbuf;
60
61         printd("pope %p %d %d\n", errstack, stacksize, *curindex);
62         /* curindex now points to the slot we are popping*/
63         *curindex = *curindex - 1;
64         /* We still need to advertise the previous slot, which is one back from
65          * curindex.  If curindex is 0, that means the next free slot is the first
66          * of our errstack.  In this case, we need to advertise the prev. */
67         if (*curindex < 0)
68                 panic("Error stack underflow");
69
70         cbuf = (*curindex == 0) ? prev_errbuf: &errstack[*curindex - 1];
71         set_cur_errbuf(cbuf);
72
73         return cbuf;
74 }