debuggers.hg

view xen/common/symbols.c @ 22855:1d1eec7e1fb4

xl: Perform minimal validation of virtual disk file while parsing config file

This patch performs some very basic validation on the virtual disk
file passed through the config file. This validation ensures that we
don't go too far with the initialization like spawn qemu and more
while there could be some potentially fundamental issues.

[ Patch fixed up to work with PHYSTYPE_EMPTY 22808:6ec61438713a -iwj ]

Signed-off-by: Kamala Narasimhan <kamala.narasimhan@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Kamala Narasimhan <kamala.narasimhan@gmail.com>
date Tue Jan 25 18:09:49 2011 +0000 (2011-01-25)
parents 75e63b73075a
children f5390bd0666b 700ac6445812
line source
1 /*
2 * symbols.c: in-kernel printing of symbolic oopses and stack traces.
3 *
4 * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
5 *
6 * ChangeLog:
7 *
8 * (25/Aug/2004) Paulo Marques <pmarques@grupopie.com>
9 * Changed the compression method from stem compression to "table lookup"
10 * compression (see tools/symbols.c for a more complete description)
11 */
13 #include <xen/config.h>
14 #include <xen/symbols.h>
15 #include <xen/kernel.h>
16 #include <xen/init.h>
17 #include <xen/lib.h>
18 #include <xen/string.h>
19 #include <xen/spinlock.h>
21 #ifdef SYMBOLS_ORIGIN
22 extern const unsigned int symbols_offsets[1];
23 #define symbols_address(n) (SYMBOLS_ORIGIN + symbols_offsets[n])
24 #else
25 extern const unsigned long symbols_addresses[];
26 #define symbols_address(n) symbols_addresses[n]
27 #endif
28 extern const unsigned int symbols_num_syms;
29 extern const u8 symbols_names[];
31 extern const u8 symbols_token_table[];
32 extern const u16 symbols_token_index[];
34 extern const unsigned int symbols_markers[];
36 /* expand a compressed symbol data into the resulting uncompressed string,
37 given the offset to where the symbol is in the compressed stream */
38 static unsigned int symbols_expand_symbol(unsigned int off, char *result)
39 {
40 int len, skipped_first = 0;
41 const u8 *tptr, *data;
43 /* get the compressed symbol length from the first symbol byte */
44 data = &symbols_names[off];
45 len = *data;
46 data++;
48 /* update the offset to return the offset for the next symbol on
49 * the compressed stream */
50 off += len + 1;
52 /* for every byte on the compressed symbol data, copy the table
53 entry for that byte */
54 while(len) {
55 tptr = &symbols_token_table[ symbols_token_index[*data] ];
56 data++;
57 len--;
59 while (*tptr) {
60 if(skipped_first) {
61 *result = *tptr;
62 result++;
63 } else
64 skipped_first = 1;
65 tptr++;
66 }
67 }
69 *result = '\0';
71 /* return to offset to the next symbol */
72 return off;
73 }
75 /* find the offset on the compressed stream given and index in the
76 * symbols array */
77 static unsigned int get_symbol_offset(unsigned long pos)
78 {
79 const u8 *name;
80 int i;
82 /* use the closest marker we have. We have markers every 256 positions,
83 * so that should be close enough */
84 name = &symbols_names[ symbols_markers[pos>>8] ];
86 /* sequentially scan all the symbols up to the point we're searching for.
87 * Every symbol is stored in a [<len>][<len> bytes of data] format, so we
88 * just need to add the len to the current pointer for every symbol we
89 * wish to skip */
90 for(i = 0; i < (pos&0xFF); i++)
91 name = name + (*name) + 1;
93 return name - symbols_names;
94 }
96 const char *symbols_lookup(unsigned long addr,
97 unsigned long *symbolsize,
98 unsigned long *offset,
99 char *namebuf)
100 {
101 unsigned long i, low, high, mid;
102 unsigned long symbol_end = 0;
104 namebuf[KSYM_NAME_LEN] = 0;
105 namebuf[0] = 0;
107 if (!is_kernel_text(addr) && !is_kernel_inittext(addr))
108 return NULL;
110 /* do a binary search on the sorted symbols_addresses array */
111 low = 0;
112 high = symbols_num_syms;
114 while (high-low > 1) {
115 mid = (low + high) / 2;
116 if (symbols_address(mid) <= addr) low = mid;
117 else high = mid;
118 }
120 /* search for the first aliased symbol. Aliased symbols are
121 symbols with the same address */
122 while (low && symbols_address(low - 1) == symbols_address(low))
123 --low;
125 /* Grab name */
126 symbols_expand_symbol(get_symbol_offset(low), namebuf);
128 /* Search for next non-aliased symbol */
129 for (i = low + 1; i < symbols_num_syms; i++) {
130 if (symbols_address(i) > symbols_address(low)) {
131 symbol_end = symbols_address(i);
132 break;
133 }
134 }
136 /* if we found no next symbol, we use the end of the section */
137 if (!symbol_end)
138 symbol_end = is_kernel_inittext(addr) ?
139 (unsigned long)_einittext : (unsigned long)_etext;
141 *symbolsize = symbol_end - symbols_address(low);
142 *offset = addr - symbols_address(low);
143 return namebuf;
144 }
146 /* Replace "%s" in format with address, or returns -errno. */
147 void __print_symbol(const char *fmt, unsigned long address)
148 {
149 const char *name;
150 unsigned long offset, size, flags;
152 static DEFINE_SPINLOCK(lock);
153 static char namebuf[KSYM_NAME_LEN+1];
154 #define BUFFER_SIZE sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN + \
155 2*(BITS_PER_LONG*3/10) + 1
156 static char buffer[BUFFER_SIZE];
158 spin_lock_irqsave(&lock, flags);
160 name = symbols_lookup(address, &size, &offset, namebuf);
162 if (!name)
163 snprintf(buffer, BUFFER_SIZE, "???");
164 else
165 snprintf(buffer, BUFFER_SIZE, "%s+%#lx/%#lx", name, offset, size);
167 printk(fmt, buffer);
169 spin_unlock_irqrestore(&lock, flags);
170 }