Commit 77e5ab66 authored by Mika Kukkonen's avatar Mika Kukkonen Committed by Linus Torvalds

[PATCH] sparse: define max kernel symbol length and clean up errors in kernel/kallsyms.c

  CHECK   kernel/kallsyms.c
kernel/kallsyms.c:136:7: warning: bad constant expression
kernel/kallsyms.c:136:7: warning: bad constant expression
kernel/kallsyms.c:136:7: warning: bad constant expression
kernel/kallsyms.c:143:22: warning: bad constant expression
kernel/kallsyms.c:143:22: warning: bad constant expression
kernel/kallsyms.c:143:22: warning: bad constant expression

Now the cause of sparse warnings is that it does not handle runtime array
dimensioning (which I take it is a sparse problem), but in this particular
case it _might_ make sense to change the runtime allocation to compile
time, as the upper size of the array is known, because the code in
kernel/kallsyms.c clearly uses 127 (or 128) as "magic constant" for kernel
symbol (array) length, and in the other hand in include/linux/module.h
there is: #define MODULE_NAME_LEN (64 - sizeof(unsigned long))

The only concern is that the array become quite big (the original comment
of it being "pretty small" no longer applies ...).  One way to help that
would be to use buffer[] also in place of namebuf[], but that would be
little tricky as the format string should be before the symbol name ... 
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7fe672b1
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <linux/config.h> #include <linux/config.h>
#define KSYM_NAME_LEN 127
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */ /* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name); unsigned long kallsyms_lookup_name(const char *name);
......
...@@ -40,14 +40,14 @@ static inline int is_kernel_text(unsigned long addr) ...@@ -40,14 +40,14 @@ static inline int is_kernel_text(unsigned long addr)
/* Lookup the address for this symbol. Returns 0 if not found. */ /* Lookup the address for this symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name) unsigned long kallsyms_lookup_name(const char *name)
{ {
char namebuf[128]; char namebuf[KSYM_NAME_LEN+1];
unsigned long i; unsigned long i;
char *knames; char *knames;
for (i = 0, knames = kallsyms_names; i < kallsyms_num_syms; i++) { for (i = 0, knames = kallsyms_names; i < kallsyms_num_syms; i++) {
unsigned prefix = *knames++; unsigned prefix = *knames++;
strlcpy(namebuf + prefix, knames, 127 - prefix); strlcpy(namebuf + prefix, knames, KSYM_NAME_LEN - prefix);
if (strcmp(namebuf, name) == 0) if (strcmp(namebuf, name) == 0)
return kallsyms_addresses[i]; return kallsyms_addresses[i];
...@@ -67,7 +67,7 @@ const char *kallsyms_lookup(unsigned long addr, ...@@ -67,7 +67,7 @@ const char *kallsyms_lookup(unsigned long addr,
/* This kernel should never had been booted. */ /* This kernel should never had been booted. */
BUG_ON(!kallsyms_addresses); BUG_ON(!kallsyms_addresses);
namebuf[127] = 0; namebuf[KSYM_NAME_LEN] = 0;
namebuf[0] = 0; namebuf[0] = 0;
if (is_kernel_text(addr) || is_kernel_inittext(addr)) { if (is_kernel_text(addr) || is_kernel_inittext(addr)) {
...@@ -84,7 +84,7 @@ const char *kallsyms_lookup(unsigned long addr, ...@@ -84,7 +84,7 @@ const char *kallsyms_lookup(unsigned long addr,
/* Grab name */ /* Grab name */
for (i = 0; i <= best; i++) { for (i = 0; i <= best; i++) {
unsigned prefix = *name++; unsigned prefix = *name++;
strncpy(namebuf + prefix, name, 127 - prefix); strncpy(namebuf + prefix, name, KSYM_NAME_LEN - prefix);
name += strlen(name) + 1; name += strlen(name) + 1;
} }
...@@ -117,34 +117,22 @@ void __print_symbol(const char *fmt, unsigned long address) ...@@ -117,34 +117,22 @@ void __print_symbol(const char *fmt, unsigned long address)
char *modname; char *modname;
const char *name; const char *name;
unsigned long offset, size; unsigned long offset, size;
char namebuf[128]; char namebuf[KSYM_NAME_LEN+1];
char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN +
2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1];
name = kallsyms_lookup(address, &size, &offset, &modname, namebuf); name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
if (!name) { if (!name)
char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)]; sprintf(buffer, "0x%lx", address);
else {
sprintf(addrstr, "0x%lx", address); if (modname)
printk(fmt, addrstr); sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset,
return; size, modname);
} else
if (modname) {
/* This is pretty small. */
char buffer[sizeof("%s+%#lx/%#lx [%s]")
+ strlen(name) + 2*(BITS_PER_LONG*3/10)
+ strlen(modname)];
sprintf(buffer, "%s+%#lx/%#lx [%s]",
name, offset, size, modname);
printk(fmt, buffer);
} else {
char buffer[sizeof("%s+%#lx/%#lx")
+ strlen(name) + 2*(BITS_PER_LONG*3/10)];
sprintf(buffer, "%s+%#lx/%#lx", name, offset, size); sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
printk(fmt, buffer);
} }
printk(fmt, buffer);
} }
/* To avoid O(n^2) iteration, we carry prefix along. */ /* To avoid O(n^2) iteration, we carry prefix along. */
...@@ -155,7 +143,7 @@ struct kallsym_iter ...@@ -155,7 +143,7 @@ struct kallsym_iter
unsigned long value; unsigned long value;
unsigned int nameoff; /* If iterating in core kernel symbols */ unsigned int nameoff; /* If iterating in core kernel symbols */
char type; char type;
char name[128]; char name[KSYM_NAME_LEN+1];
}; };
/* Only label it "global" if it is exported. */ /* Only label it "global" if it is exported. */
...@@ -186,7 +174,8 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter) ...@@ -186,7 +174,8 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
shared with previous name (stem compression). */ shared with previous name (stem compression). */
stemlen = kallsyms_names[off++]; stemlen = kallsyms_names[off++];
strlcpy(iter->name+stemlen, kallsyms_names + off, 128-stemlen); strlcpy(iter->name+stemlen, kallsyms_names + off,
KSYM_NAME_LEN+1-stemlen);
off += strlen(kallsyms_names + off) + 1; off += strlen(kallsyms_names + off) + 1;
iter->owner = NULL; iter->owner = NULL;
iter->value = kallsyms_addresses[iter->pos]; iter->value = kallsyms_addresses[iter->pos];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment