/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
- char *name, char *module_name, int *exported);
+ char *name, char *module_name, unsigned long *size,
+ int *exported);
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name);
}
static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
- char *type, char *name,
- char *module_name, int *exported)
+ char *type, char *name, char *module_name,
+ unsigned long *size, int *exported)
{
return -ERANGE;
}
}
EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
+static unsigned long get_symbol_size(unsigned long kallsyms_addr)
+{
+ unsigned long size = 0;
+ unsigned long sym_addr = kallsyms_addresses[kallsyms_addr];
+ unsigned long used_i = 0;
+ unsigned long used_i_addr = 0;
+
+ /*
+ * __per_cpu_end always has size zero.
+ */
+ if (sym_addr == (unsigned long)__per_cpu_end)
+ return 0;
+
+ /*
+ * Search for next non-aliased symbol. Aliased symbols are symbols with
+ * the same address.
+ */
+ if (kallsyms_addr < (kallsyms_num_syms - 1)) {
+ unsigned long i;
+
+ for (i = kallsyms_addr + 1; i < kallsyms_num_syms; i++)
+ if (kallsyms_addresses[i] > sym_addr) {
+ size = kallsyms_addresses[i] - sym_addr;
+ used_i = i;
+ used_i_addr = kallsyms_addresses[i];
+ break;
+ }
+ }
+
+ /* If we found no next symbol, we use the end of the section. */
+ if (!size) {
+ unsigned long symbol_end;
+
+ if (is_kernel_inittext(sym_addr))
+ symbol_end = (unsigned long)_einittext;
+ else if (all_var)
+ symbol_end = (unsigned long)_end;
+ else
+ symbol_end = (unsigned long)_etext;
+
+ size = symbol_end - sym_addr;
+ }
+
+ return size;
+}
+
+
static unsigned long get_symbol_pos(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)
{
- unsigned long symbol_start = 0, symbol_end = 0;
- unsigned long i, low, high, mid;
+ unsigned long low, high, mid;
/* This kernel should never had been booted. */
BUG_ON(!kallsyms_addresses);
}
/*
- * Search for the first aliased symbol. Aliased
- * symbols are symbols with the same address.
+ * Search for the first aliased symbol.
*/
while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
--low;
- symbol_start = kallsyms_addresses[low];
-
- /* Search for next non-aliased symbol. */
- for (i = low + 1; i < kallsyms_num_syms; i++) {
- if (kallsyms_addresses[i] > symbol_start) {
- symbol_end = kallsyms_addresses[i];
- break;
- }
- }
-
- /* If we found no next symbol, we use the end of the section. */
- if (!symbol_end) {
- if (is_kernel_inittext(addr))
- symbol_end = (unsigned long)_einittext;
- else if (all_var)
- symbol_end = (unsigned long)_end;
- else
- symbol_end = (unsigned long)_etext;
- }
-
if (symbolsize)
- *symbolsize = symbol_end - symbol_start;
+ *symbolsize = get_symbol_size(low);
if (offset)
- *offset = addr - symbol_start;
+ *offset = addr - kallsyms_addresses[low];
return low;
}
{
iter->builtin_module = 0;
if (module_get_kallsym(iter->pos - kallsyms_num_syms, &iter->value,
- &iter->type, iter->name, iter->module_name,
- &iter->exported) < 0)
+ &iter->type, iter->name, iter->module_name,
+ &iter->size, &iter->exported) < 0)
return 0;
return 1;
}
iter->exported = 0;
iter->value = kallsyms_addresses[iter->pos];
+ iter->size = get_symbol_size(iter->pos);
iter->type = kallsyms_get_symbol_type(off);
off = kallsyms_expand_symbol(off, iter->name, ARRAY_SIZE(iter->name));
*/
type = iter->exported ? toupper(iter->type) :
tolower(iter->type);
- seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
- type, iter->name, iter->module_name);
- } else {
+ if (builtin_modules)
+ seq_printf(m, "%pK %lx %c %s\t[%s]\n", (void *)iter->value,
+ iter->size, type, iter->name, iter->module_name);
+ else
+ seq_printf(m, "%pK %c %s\t[%s]\n", (void *)iter->value,
+ type, iter->name, iter->module_name);
+ } else if (builtin_modules)
+ seq_printf(m, "%pK %lx %c %s\n", (void *)iter->value,
+ iter->size, iter->type, iter->name);
+ else
seq_printf(m, "%pK %c %s\n", (void *)iter->value,
iter->type, iter->name);
- }
return 0;
}