kdb
[Top] [All Lists]

[PATCH] fix symbol completion

To: kaos@xxxxxxx, kdb@xxxxxxxxxxx
Subject: [PATCH] fix symbol completion
From: Jim Houston <jim.houston@xxxxxxxxxxx>
Date: 29 Sep 2004 14:53:08 -0400
Reply-to: jim.houston@xxxxxxxxxxx
Sender: kdb-bounce@xxxxxxxxxxx
Hi Keith,

Attached is a patch which will fix the kdb symbol completion
problem I described yesterday.  It replaces most of the symbol
table handling with the version from the port I did last fall.

I have not looked at the code yet to check for the buffer
overflow you described.  As long as the buffers are larger
than the longest symbol in the kernel/module symbol tables
I would not expect a problem.

Jim Houston - Concurrent Computer Corp.

--

diff -urN -Xdontdiff linux-2.6.8.1.orig/include/linux/module.h 
linux-2.6.8.1/include/linux/module.h
--- linux-2.6.8.1.orig/include/linux/module.h   2004-08-23 16:38:06.000000000 
-0400
+++ linux-2.6.8.1/include/linux/module.h        2004-09-29 13:33:11.249170728 
-0400
@@ -437,6 +437,11 @@
                                  unsigned long *symbolsize,
                                  unsigned long *offset,
                                  char **modname);
+#ifdef CONFIG_KDB
+/* Kdb access to symbol table. */
+const char *module_symbol_index(unsigned int index,
+       unsigned long *value, const char **modname);
+#endif /* CONFIG_KDB */
 
 /* For extable.c to search modules' exception tables. */
 const struct exception_table_entry *search_module_extables(unsigned long addr);
@@ -518,6 +523,15 @@
        return 0;
 }
 
+#ifdef CONFIG_KDB
+/* Kdb access to symbol table. */
+static inline const char *module_symbol_index(unsigned int index,
+       unsigned long *value, const char **modname)
+{
+       return NULL;
+}
+#endif /* CONFIG_KDB */
+
 static inline int register_module_notifier(struct notifier_block * nb)
 {
        /* no events will happen anyway, so this can always succeed */
diff -urN -Xdontdiff linux-2.6.8.1.orig/kdb/kdbsupport.c 
linux-2.6.8.1/kdb/kdbsupport.c
--- linux-2.6.8.1.orig/kdb/kdbsupport.c 2004-09-02 15:18:00.000000000 -0400
+++ linux-2.6.8.1/kdb/kdbsupport.c      2004-09-29 13:22:21.707916008 -0400
@@ -27,14 +27,6 @@
 #include <linux/kdb.h>
 #include <linux/kdbprivate.h>
 
-#ifdef CONFIG_MODULES
-extern struct list_head *kdb_modules;
-#endif
-
-/* These will be re-linked against their real values during the second link 
stage */
-extern unsigned long kallsyms_addresses[] __attribute__((weak));;
-extern unsigned long kallsyms_num_syms __attribute__((weak));
-extern char kallsyms_names[] __attribute__((weak));
 
 /*
  * Symbol table functions.
@@ -46,7 +38,7 @@
  *     Return the address of the given symbol.
  *
  * Parameters:
- *     symname Character string containing symbol name
+ *     symname Character string containing symbol name
  *      symtab  Structure to receive results
  * Outputs:
  * Returns:
@@ -57,55 +49,12 @@
  * Remarks:
  */
 
-int
-kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
-{
-       int i;
-       char *name = kallsyms_names;
-       char namebuf[128];
 
-       if (KDB_DEBUG(AR))
-               kdb_printf("kdbgetsymval: symname=%s, symtab=%p\n", symname, 
symtab);
-       memset(symtab, 0, sizeof(*symtab));
-
-       namebuf[127] = 0;
-       namebuf[0] = 0;
-       for (i = 0; i < kallsyms_num_syms; i++) {
-               unsigned prefix = *name++;
-               strncpy(namebuf + prefix, name, 127 - prefix);
-               if (strcmp(namebuf, symname) == 0) {
-                       /* found */
-                       symtab->sym_start = kallsyms_addresses[i];
-                       if (KDB_DEBUG(AR))
-                               kdb_printf("kdbgetsymval: returns 1, 
symtab->sym_start=0x%lx\n", symtab->sym_start);
-                       return(1);
-               }
-               name += strlen(name) + 1;
-       }
-#ifdef CONFIG_MODULES
- {
-       struct module *mod;
-       /* look into modules */
-       list_for_each_entry(mod, kdb_modules, list) {
-               for (i = 1; i < mod->num_symtab; i++) {
-                       if (mod->symtab[i].st_shndx == SHN_UNDEF)
-                               continue;
-                       name =  mod->strtab + mod->symtab[i].st_name;
-                       if (strcmp(name, symname) == 0) {
-                               /* found */
-                               symtab->sym_start = mod->symtab[i].st_value;
-                               if (KDB_DEBUG(AR))
-                                       kdb_printf("kdbgetsymval: returns 1, 
symtab->sym_start=0x%lx\n", symtab->sym_start);
-                               return(1);
-                       }
-               }
-       }
- }
-#endif /* CONFIG_MODULES */
-       if (KDB_DEBUG(AR))
-               kdb_printf("kdbgetsymval: returns 0\n");
-       return(0);
-}
+/* These will be re-linked against their real values during the second link 
stage */
+extern unsigned long kallsyms_addresses[] __attribute__((weak));
+extern unsigned long kallsyms_num_syms __attribute__((weak));
+extern char kallsyms_names[] __attribute__((weak));
+extern char _end;
 
 /*
  * kdbnearsym
@@ -114,8 +63,8 @@
  *     less than 'addr'.
  *
  * Parameters:
- *     addr    Address to check for symbol near
- *     symtab  Structure to receive results
+ *     addr    Address to check for symbol near
+ *      symtab  Structure to receive results
  * Outputs:
  * Returns:
  *     0       No sections contain this address, symtab zero filled
@@ -123,189 +72,164 @@
  * Locking:
  *     None.
  * Remarks:
- *     2.6 kallsyms has a "feature" where it unpacks the name into a string.
- *     If that string is reused before the caller expects it then the caller
- *     sees its string change without warning.  To avoid cluttering up the
- *     main kdb code with lots of kdb_strdup, tests and kfree calls, kdbnearsym
- *     maintains an LRU list of the last few unique strings.  The list is sized
- *     large enough to hold active strings, no kdb caller of kdbnearsym makes
- *     more than ~20 later calls before using a saved value.
  */
 
 int
 kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
 {
-       int ret;
-       unsigned long symbolsize;
-       unsigned long offset;
-       static char *knt[100];  /* kdb name table, arbitrary size */
-#define knt1_size 128          /* must be >= kallsyms table size */
-       char *knt1 = kmalloc(knt1_size, GFP_ATOMIC);
+       const char *name;
+       char *modname;
+       long size, offset;
+       int h, l , m;
 
-       if (!knt1) {
-               kdb_printf("kdbnearsym: addr=0x%lx cannot kmalloc knt1\n", 
addr);
+       if (!kallsyms_addresses) {
+               kdb_printf("kdbnearsym: no symbol table\n");
                return 0;
        }
-
-       if (KDB_DEBUG(AR))
-               kdb_printf("kdbnearsym: addr=0x%lx, symtab=%p\n", addr, symtab);
-
+       name = NULL;
+       if (addr > (unsigned long)&_end) {
+               name = module_address_lookup(addr,  &size, &offset, &modname);
+       } else if (addr > PAGE_OFFSET) {
+               l = 0;
+               h = kallsyms_num_syms-1;
+               m = (h+l)/2;
+               while (h > l+1) {
+                       if (kallsyms_addresses[m] > addr)
+                               h = m;
+                       else
+                               l = m;
+                       m = (h+l)/2;
+               }
+               if (kallsyms_addresses[h] <= addr)
+                       l = h;
+               h = l+1;
+               name = kallsyms_names;
+               for (m = 0; m < l ; m++)
+                       name += strlen(name)+1;
+               size = kallsyms_addresses[h] - kallsyms_addresses[l];
+               offset = addr - kallsyms_addresses[l];
+               modname = NULL;
+       }
        memset(symtab, 0, sizeof(*symtab));
-       symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset, (char 
**)(&symtab->mod_name), knt1);
+       if (!name) 
+               return 0;
+       symtab->sym_name = name;
        symtab->sym_start = addr - offset;
-       symtab->sym_end = symtab->sym_start + symbolsize;
-       ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0';
+       symtab->sym_end = addr - offset + size;
+       symtab->mod_name = modname ? modname : "kernel";
+       return 1;
+}
 
-       if (ret) {
-               int i;
-               /* Another 2.6 kallsyms "feature".  Sometimes the sym_name is
-                * set but the buffer passed into kallsyms_lookup is not used,
-                * so it contains garbage.  The caller has to work out which
-                * buffer needs to be saved.
-                *
-                * What was Rusty smoking when he wrote that code?
-                */
-               if (symtab->sym_name != knt1) {
-                       strncpy(knt1, symtab->sym_name, knt1_size);
-                       knt1[knt1_size-1] = '\0';
-               }
-               for (i = 0; i < ARRAY_SIZE(knt); ++i) {
-                       if (knt[i] && strcmp(knt[i], knt1) == 0)
-                               break;
-               }
-               if (i >= ARRAY_SIZE(knt)) {
-                       memcpy(knt, knt+1, sizeof(knt[0])*(ARRAY_SIZE(knt)-1));
-                       i = ARRAY_SIZE(knt)-1;
-               } else {
-                       kfree(knt1);
-                       knt1 = knt[i];
-                       memcpy(knt+i, knt+i+1, 
sizeof(knt[0])*(ARRAY_SIZE(knt)-i-1));
-                       i = ARRAY_SIZE(knt) - 1;
-               }
-               knt[i] = knt1;
-               symtab->sym_name = knt[i];
-       }
+#define first_symbol(index, string, value, module) \
+       index = 0; \
+       string = kallsyms_names; \
+       module = NULL; \
+       value = kallsyms_addresses[0];
 
-       if (symtab->mod_name == NULL)
-               symtab->mod_name = "kernel";
-       if (KDB_DEBUG(AR))
-               kdb_printf("kdbnearsym: returns %d symtab->sym_start=0x%lx, 
symtab->mod_name=%p, symtab->sym_name=%p (%s)\n", ret, symtab->sym_start, 
symtab->mod_name, symtab->sym_name, symtab->sym_name);
 
-       return ret;
-}
+#define next_symbol(index, string, value, module) \
+       if (++index < kallsyms_num_syms) { \
+               string += strlen(string)+1; \
+               value = kallsyms_addresses[index]; \
+       } else { \
+               string = module_symbol_index(index-kallsyms_num_syms, &value, 
&module); \
+       }
 
-/*
- * kallsyms_symbol_complete
- *
- * Parameters:
- *     prefix_name     prefix of a symbol name to lookup
- * Returns:
- *     Number of symbols which match the given prefix.
- */
 
+/* paramter prefix_name is a buffer provided by the caller, it must ends with 
'\0'. */
+/* return the extra string together with the given prefix of a symbol name. */
+/* return 0 means no prefix string is found. */
+/* return >0 means prefix string is found. */
+/* Prefix of a symbol name to lookup */
 int kallsyms_symbol_complete(char *prefix_name)
 {
-       char *name = kallsyms_names;
-       int i;
-       char namebuf[128];
-       int prefix_len = strlen(prefix_name);
-       int number = 0;
-
-       /* look into kernel symbols */
-
-       for (i=0; i < kallsyms_num_syms; i++) {
-               unsigned prefix = *name++;
-               strncpy(namebuf + prefix, name, 127 - prefix);
-               if (strncmp(namebuf, prefix_name, prefix_len) == 0) {
-                       /* found */
-                       ++number;
-               }
-               name += strlen(name) + 1;
-       }
-#ifdef CONFIG_MODULES
- {
-       struct module *mod;
-       /* look into modules symbols */
-       list_for_each_entry(mod, kdb_modules, list) {
-               for (i = 1; i < mod->num_symtab; i++) {
-                       if (mod->symtab[i].st_shndx == SHN_UNDEF)
-                               continue;
-                       name =  mod->strtab + mod->symtab[i].st_name;
-                       if (strncmp(name, prefix_name, prefix_len) == 0) {
-                               /* found */
-                               ++number;
+       int prefix_len=strlen(prefix_name);
+       int last_pos=0;
+       int number=0;
+       const char *p, *mod;
+       unsigned long value;
+       int i, j;
+
+       first_symbol(i, p, value, mod);
+       while (p) {
+               if (strncmp(p, prefix_name,prefix_len) == 0) {
+                       if (number++ == 0) {
+                               last_pos = strlen(p);
+                               strncpy(prefix_name, p, last_pos+1);
+                       } else {
+                               for (j = prefix_len ; j < last_pos; j++) {
+                                       if (!p[j] || p[j] != prefix_name[j]) {
+                                               last_pos = j;
+                                               prefix_name[j] = '\0';
+                                               break;
+                                       }
+                               }
                        }
                }
+               next_symbol(i, p, value, mod);
        }
- }
-#endif /* CONFIG_MODULES */
+
        return number;
 }
 
-/*
- * kallsyms_symbol_next
- *
- * Parameters:
- *     prefix_name     prefix of a symbol name to lookup
- *     flag    0 means search from the head, 1 means continue search.
- * Returns:
- *     1 if a symbol matches the given prefix.
- *     0 if no string found
- */
+/* paramter prefix_name is a buffer provided by the caller, it must ends with 
'\0'. */
+/* parameter flag = 0 means search from the head, flag = 1 means continue 
search. */
+/* return a symbol string which matches the given prefix. */
+/* return 0 means no prefix string is found. */
+/* return >0 means prefix string is found. */
+
+static unsigned int current_index;
+static const char *current_string;
 
-int kallsyms_symbol_next(char *prefix_name, int flag)
+/* Prefix of a symbol name to lookup */
+/* Indicate if search from the head */
+int kallsyms_symbol_next( char *prefix_name, int flag)
 {
-       int prefix_len = strlen(prefix_name);
-       char namebuf[128];
-       static int i;
-       static char *name;
-       static struct module *mod;
-
-       if (flag) {
-               /* continue searching */
-               i++;
-               name += strlen(name) + 1;
-       } else {
-               /* new search */
-               i = 0;
-               name = kallsyms_names;
-               mod = (struct module *)NULL;
+       int prefix_len=strlen(prefix_name);
+       unsigned long value;
+       const char *p, *mod;
+
+
+       if(!flag) {
+               first_symbol(current_index, current_string, value, mod);
        }
 
-       if (mod == (struct module *)NULL) {
-               /* look into kernel symbols */
-               for (; i < kallsyms_num_syms; i++) {
-                       unsigned prefix = *name++;
-                       strncpy(namebuf + prefix, name, 127 - prefix);
-                       if (strncmp(namebuf, prefix_name, prefix_len) == 0) {
-                               /* found */
-                               strncpy(prefix_name, namebuf, 
strlen(namebuf)+1);
-                               return(1);
-                       }
-                       name += strlen(name) + 1;
+       while ((p = current_string)) {
+               next_symbol(current_index, current_string, value, mod);
+               if (strncmp(p, prefix_name,prefix_len) == 0) {
+                       strncpy(prefix_name, p, strlen(p)+1);
+                       return 1;
                }
-#ifdef CONFIG_MODULES
-               /* not found */
-               i = 1;
-               mod = list_entry(kdb_modules->next, struct module, list);
-       }
-       /* look into modules */
-       for (; &mod->list != kdb_modules; mod =
-                    list_entry(mod->list.next, struct module, list))
-               for (; i < mod->num_symtab; i++) {
-                       if (mod->symtab[i].st_shndx == SHN_UNDEF)
-                               continue;
-                       name =  mod->strtab + mod->symtab[i].st_name;
-                       if (strncmp(name, prefix_name, prefix_len) == 0) {
-                               /* found */
-                               strncpy(prefix_name, name, strlen(name)+1);
-                               return(1);
-                       }
-               }
-#else /* CONFIG_MODULES */
        }
-#endif /* CONFIG_MODULES */
-       return(0);
+       return 0;
+}
+
+int
+kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
+{
+       unsigned long value;
+       const char *p, *mod;
+       int i;
+
+       if (!kallsyms_addresses) {
+               kdb_printf("kdbgetsymval: no symbol table\n");
+               return 0;
+       }
+       first_symbol(i, p, value, mod);
+       while (p) {
+               if (strcmp(p, symname) == 0)
+                       break;
+               next_symbol (i, p, value, mod);
+       }
+       if (!p)
+               return 0;
+       /*
+        * Use the value based lookup to find the symbol's size.
+        */
+       i = kdbnearsym(value, symtab);
+       /* return the name we matched. */
+       symtab->sym_name = p;
+       return(i);
 }
 
 #if defined(CONFIG_SMP)
Binary files linux-2.6.8.1.orig/kernel/config_data.gz and 
linux-2.6.8.1/kernel/config_data.gz differ
diff -urN -Xdontdiff linux-2.6.8.1.orig/kernel/kallsyms.c 
linux-2.6.8.1/kernel/kallsyms.c
--- linux-2.6.8.1.orig/kernel/kallsyms.c        2004-09-02 15:18:00.000000000 
-0400
+++ linux-2.6.8.1/kernel/kallsyms.c     2004-09-29 12:20:44.000000000 -0400
@@ -14,11 +14,7 @@
 #include <linux/err.h>
 #include <linux/proc_fs.h>
 
-#ifdef CONFIG_KDB
-#define kdb 1
-#else
-#define kdb 0
-#endif
+static int stem_compression = 1;
 
 /* These will be re-linked against their real values during the second link 
stage */
 extern unsigned long kallsyms_addresses[] __attribute__((weak));
@@ -27,7 +23,6 @@
 
 /* Defined by the linker script. */
 extern char _stext[], _etext[], _sinittext[], _einittext[];
-extern char _end[];    /* for CONFIG_KDB */
 
 static inline int is_kernel_inittext(unsigned long addr)
 {
@@ -44,12 +39,6 @@
        return 0;
 }
 
-/* kdb treats all kernel addresses as valid, including data */
-static inline int is_kernel(unsigned long addr)
-{
-       return (addr >= (unsigned long)_stext && addr <= (unsigned long)_end);
-}
-
 /* Lookup the address for this symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name)
 {
@@ -82,30 +71,26 @@
 
        namebuf[KSYM_NAME_LEN] = 0;
        namebuf[0] = 0;
-       if ((kdb && is_kernel(addr)) ||
-           (!kdb && (is_kernel_text(addr) || is_kernel_inittext(addr)))) {
+
+       if (is_kernel_text(addr) || is_kernel_inittext(addr)) {
                unsigned long symbol_end;
                char *name = kallsyms_names;
 
                /* They're sorted, we could be clever here, but who cares? */
                for (i = 0; i < kallsyms_num_syms; i++) {
-                       if (kallsyms_addresses[i] > kallsyms_addresses[best] &&
+                       if (kallsyms_addresses[i] >= kallsyms_addresses[best] &&
                            kallsyms_addresses[i] <= addr)
                                best = i;
                }
 
+
                /* Grab name */
-               for (i = 0; i <= best; i++) { 
-                       unsigned prefix = *name++;
-                       strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix);
-                       name += strlen(name) + 1;
-               }
 
                /* At worst, symbol ends at end of section. */
                if (is_kernel_inittext(addr))
                        symbol_end = (unsigned long)_einittext;
                else
-                       symbol_end = kdb ? (unsigned long)_end : (unsigned 
long)_etext;
+                       symbol_end = (unsigned long)_etext;
 
                /* Search for next non-aliased symbol */
                for (i = best+1; i < kallsyms_num_syms; i++) {
@@ -118,7 +103,18 @@
                *symbolsize = symbol_end - kallsyms_addresses[best];
                *modname = NULL;
                *offset = addr - kallsyms_addresses[best];
-               return namebuf;
+               if (stem_compression) {
+                       for (i = 0; i <= best; i++) { 
+                               unsigned prefix = *name++;
+                               strncpy(namebuf + prefix, name, KSYM_NAME_LEN - 
prefix);
+                               name += strlen(name) + 1;
+                       }
+                       return namebuf;
+               }
+               for (i = 0; i < best; i++)
+                       name += strlen(name)+1;
+               strncpy(namebuf, name, KSYM_NAME_LEN);
+               return name;
        }
 
        return module_address_lookup(addr, symbolsize, offset, modname);
@@ -185,7 +181,11 @@
 
        /* First char of each symbol name indicates prefix length
           shared with previous name (stem compression). */
-       stemlen = kallsyms_names[off++];
+       if (stem_compression) {
+               stemlen = kallsyms_names[off++];
+       } else {
+               stemlen = 0;
+       }
 
        strlcpy(iter->name+stemlen, kallsyms_names + off,
                KSYM_NAME_LEN+1-stemlen);
@@ -318,6 +318,8 @@
        entry = create_proc_entry("kallsyms", 0444, NULL);
        if (entry)
                entry->proc_fops = &kallsyms_operations;
+
+       stem_compression = kallsyms_names ? (*kallsyms_names == 0) : 0;
        return 0;
 }
 __initcall(kallsyms_init);
diff -urN -Xdontdiff linux-2.6.8.1.orig/kernel/module.c 
linux-2.6.8.1/kernel/module.c
--- linux-2.6.8.1.orig/kernel/module.c  2004-09-02 15:18:00.000000000 -0400
+++ linux-2.6.8.1/kernel/module.c       2004-09-29 12:20:44.000000000 -0400
@@ -38,6 +38,10 @@
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
 
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif
+
 #if 0
 #define DEBUGP printk
 #else
@@ -2038,6 +2042,30 @@
 }
 #endif /* CONFIG_KALLSYMS */
 
+#ifdef CONFIG_KDB
+/*
+ * Allow the debugger to iterate over the symbols for all of
+ * the currently loaded modules.  The  enumeration of the
+ * symbols will change when ever a module loaded or unloaded.
+ */
+const char *module_symbol_index(unsigned int index,
+       unsigned long *value, const char **modname)
+{
+       struct module *mod;
+
+       list_for_each_entry(mod, &modules, list) {
+               if (index < mod->num_symtab) { 
+                       *value = mod->symtab[index].st_value;
+                       *modname = mod->name;
+                       return mod->strtab + mod->symtab[index].st_name;
+               }
+               index -= mod->num_symtab;
+       }
+       return NULL;
+
+}
+#endif
+
 /* Called by the /proc file system to return a list of modules. */
 static void *m_start(struct seq_file *m, loff_t *pos)
 {
diff -urN -Xdontdiff linux-2.6.8.1.orig/Makefile linux-2.6.8.1/Makefile
--- linux-2.6.8.1.orig/Makefile 2004-09-02 15:18:00.000000000 -0400
+++ linux-2.6.8.1/Makefile      2004-09-29 12:24:14.000000000 -0400
@@ -577,7 +577,12 @@
 endef
 
 quiet_cmd_kallsyms = KSYM    $@
+# Disable stem compression and add data symbols for kdb
+ifdef CONFIG_KDB
+cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) --no-stem-compression --all-symbols > 
$@
+else
 cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach 
x,$(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
+endif
 
 .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
        $(call if_changed_dep,as_o_S)
diff -urN -Xdontdiff linux-2.6.8.1.orig/scripts/kallsyms.c 
linux-2.6.8.1/scripts/kallsyms.c
--- linux-2.6.8.1.orig/scripts/kallsyms.c       2004-08-23 16:38:09.000000000 
-0400
+++ linux-2.6.8.1/scripts/kallsyms.c    2004-09-29 12:20:44.000000000 -0400
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <unistd.h>
 
 struct sym_entry {
        unsigned long long addr;
@@ -24,11 +25,12 @@
 static int size, cnt;
 static unsigned long long _stext, _etext, _sinittext, _einittext;
 static int all_symbols = 0;
+static int stem_compression = 1;
 
 static void
 usage(void)
 {
-       fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n");
+       fprintf(stderr, "Usage: kallsyms [--no-stem-compression][--all-symbols] 
< in.map > out.S\n");
        exit(1);
 }
 
@@ -131,7 +133,7 @@
        for (i = 0; i < cnt; i++) {
                if (!symbol_valid(&table[i]))
                        continue;
-
+               
                printf("\tPTR\t%#llx\n", table[i].addr);
                valid++;
        }
@@ -153,10 +155,16 @@
                if (!symbol_valid(&table[i]))
                        continue;
 
-               for (k = 0; table[i].sym[k] && table[i].sym[k] == prev[k]; ++k)
-                       ; 
+               if (stem_compression) {
+                       for (k = 0; table[i].sym[k] && table[i].sym[k] == 
prev[k]; ++k)
+                               ; 
+
+                       printf("\t.byte 0x%02x\n\t.asciz\t\"%s\"\n",
+                                k, table[i].sym + k);
+               } else {
+                       printf("\t.asciz\t\"%s\"\n", table[i].sym);
+               }
 
-               printf("\t.byte 0x%02x\n\t.asciz\t\"%s\"\n", k, table[i].sym + 
k);
                prev = table[i].sym;
        }
        printf("\n");
@@ -165,10 +173,13 @@
 int
 main(int argc, char **argv)
 {
-       if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0)
-               all_symbols = 1;
-       else if (argc != 1)
-               usage();
+       while(++argv,--argc) {
+               if (strcmp(*argv, "--all-symbols") == 0)
+                       all_symbols = 1;
+               else if (strcmp(*argv, "--no-stem-compression") == 0)
+                       stem_compression = 0;
+               else usage();
+       }
 
        read_map(stdin);
        write_src();
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.
<Prev in Thread] Current Thread [Next in Thread>