Fix data leak in fs_file_write()
[akaros.git] / kern / src / hexdump.c
1 /*
2  * Copyright 2013 Google Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but without any warranty; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <kdebug.h>
24 #include <kmalloc.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <smp.h>
28 #include <pmap.h>
29
30 static int isprint(int c)
31 {
32         return (c >= 32 && c <= 126);
33 }
34
35 void hexdump(void *v, int length)
36 {
37         int i;
38         uint8_t *m = v;
39         uintptr_t memory = (uintptr_t) v;
40         int all_zero = 0;
41
42         print_lock();
43         for (i = 0; i < length; i += 16) {
44                 int j;
45
46                 all_zero++;
47                 for (j = 0; (j < 16) && (i + j < length); j++) {
48                         if (m[i + j] != 0) {
49                                 all_zero = 0;
50                                 break;
51                         }
52                 }
53
54                 if (all_zero < 2) {
55                         printk("%08lx:", memory + i);
56                         for (j = 0; j < 16; j++)
57                                 printk(" %02x", m[i + j]);
58                         printk("  ");
59                         for (j = 0; j < 16; j++)
60                                 printk("%c", isprint(m[i + j]) ? m[i + j] : '.');
61                         printk("\n");
62                 } else if (all_zero == 2) {
63                         printk("...\n");
64                 }
65         }
66         print_unlock();
67 }
68
69 /* easier in monitor */
70 void pahexdump(uintptr_t pa, int len)
71 {
72         void *v = KADDR(pa);
73         hexdump(v, len);
74 }
75
76 /* Print a string, with printables preserved, and \xxx where not possible. */
77 int printdump(char *buf, int numprint, int buflen, uint8_t *data)
78 {
79         int ret = 0;
80         int ix = 0;
81
82         if (buflen < 1)
83                 return ret;
84         buf[ret++] = '\'';
85         /* we want 2 bytes left in the buf (which is ret < buflen - 1), one for the
86          * char, and one for the \' after the loop. */
87         while (ix < numprint && ret < (buflen - 1)) {
88                 if (isprint(data[ix])) {
89                         buf[ret++] = data[ix];
90                 } else if (ret < buflen - 4) {
91                         /* guarantee there is room for a \xxx sequence */
92                         ret += snprintf(&buf[ret], buflen-ret, "\\%03o", data[ix]);
93                 } else {
94                         break;
95                 }
96                 ix++;
97         }
98         buf[ret++] = '\'';
99         return ret;
100 }