patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / kernel / kallsyms.c
index ab39819..2138708 100644 (file)
@@ -88,14 +88,20 @@ const char *kallsyms_lookup(unsigned long addr,
                        name += strlen(name) + 1;
                }
 
-               /* Base symbol size on next symbol. */
-               if (best + 1 < kallsyms_num_syms)
-                       symbol_end = kallsyms_addresses[best + 1];
-               else if (is_kernel_inittext(addr))
+               /* At worst, symbol ends at end of section. */
+               if (is_kernel_inittext(addr))
                        symbol_end = (unsigned long)_einittext;
                else
                        symbol_end = (unsigned long)_etext;
 
+               /* Search for next non-aliased symbol */
+               for (i = best+1; i < kallsyms_num_syms; i++) {
+                       if (kallsyms_addresses[i] > kallsyms_addresses[best]) {
+                               symbol_end = kallsyms_addresses[i];
+                               break;
+                       }
+               }
+
                *symbolsize = symbol_end - kallsyms_addresses[best];
                *modname = NULL;
                *offset = addr - kallsyms_addresses[best];
@@ -171,21 +177,26 @@ static int get_ksymbol_mod(struct kallsym_iter *iter)
        return 1;
 }
 
-static void get_ksymbol_core(struct kallsym_iter *iter)
+/* Returns space to next name. */
+static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
 {
-       unsigned stemlen;
+       unsigned stemlen, off = iter->nameoff;
 
        /* First char of each symbol name indicates prefix length
           shared with previous name (stem compression). */
-       stemlen = kallsyms_names[iter->nameoff++];
+       stemlen = kallsyms_names[off++];
 
-       strlcpy(iter->name+stemlen, kallsyms_names+iter->nameoff, 128-stemlen);
-       iter->nameoff += strlen(kallsyms_names + iter->nameoff) + 1;
+       strlcpy(iter->name+stemlen, kallsyms_names + off, 128-stemlen);
+       off += strlen(kallsyms_names + off) + 1;
        iter->owner = NULL;
        iter->value = kallsyms_addresses[iter->pos];
-       iter->type = 't';
+       if (is_kernel_text(iter->value) || is_kernel_inittext(iter->value))
+               iter->type = 't';
+       else
+               iter->type = 'd';
 
        upcase_if_global(iter);
+       return off - iter->nameoff;
 }
 
 static void reset_iter(struct kallsym_iter *iter)
@@ -210,9 +221,10 @@ static int update_iter(struct kallsym_iter *iter, loff_t pos)
 
        /* We need to iterate through the previous symbols: can be slow */
        for (; iter->pos != pos; iter->pos++) {
-               get_ksymbol_core(iter);
+               iter->nameoff += get_ksymbol_core(iter);
                cond_resched();
        }
+       get_ksymbol_core(iter);
        return 1;
 }