debuggers.hg

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