/trunk/kernel/generic/include/symtab.h |
---|
44,15 → 44,20 |
char symbol_name[MAX_SYMBOL_NAME]; |
}; |
extern char * get_symtab_entry(unative_t addr); |
extern uintptr_t get_symbol_addr(const char *name); |
extern int symtab_name_lookup(unative_t addr, char **name); |
extern char *symtab_fmt_name_lookup(unative_t addr); |
extern int symtab_addr_lookup(const char *name, uintptr_t *addr); |
extern void symtab_print_search(const char *name); |
extern int symtab_compl(char *name); |
#ifdef CONFIG_SYMTAB |
/* Symtable linked together by build process */ |
extern struct symtab_entry symbol_table[]; |
#endif |
#endif |
/** @} |
*/ |
/trunk/kernel/generic/src/synch/spinlock.c |
---|
42,10 → 42,7 |
#include <preemption.h> |
#include <print.h> |
#include <debug.h> |
#ifdef CONFIG_SYMTAB |
#include <symtab.h> |
#endif |
#ifdef CONFIG_FB |
#include <genarch/fb/fb.h> |
80,9 → 77,6 |
{ |
count_t i = 0; |
bool deadlock_reported = false; |
#ifdef CONFIG_SYMTAB |
char *symbol; |
#endif |
preemption_disable(); |
while (test_and_set(&sl->val)) { |
111,14 → 105,10 |
continue; |
#endif |
if (i++ > DEADLOCK_THRESHOLD) { |
printf("cpu%u: looping on spinlock %" PRIp ":%s, caller=%" PRIp, |
CPU->id, sl, sl->name, CALLER); |
#ifdef CONFIG_SYMTAB |
symbol = get_symtab_entry(CALLER); |
if (symbol) |
printf("(%s)", symbol); |
#endif |
printf("\n"); |
printf("cpu%u: looping on spinlock %" PRIp ":%s, " |
"caller=%" PRIp "(%s)", CPU->id, sl, sl->name, |
CALLER, symtab_fmt_name_lookup(CALLER)); |
i = 0; |
deadlock_reported = true; |
} |
/trunk/kernel/generic/src/debug/symtab.c |
---|
41,18 → 41,19 |
#include <print.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <errno.h> |
/** Return entry that seems most likely to correspond to argument. |
/** Get name of symbol that seems most likely to correspond to address. |
* |
* Return entry that seems most likely to correspond |
* to address passed in the argument. |
* @param addr Address. |
* @param name Place to store pointer to the symbol name. |
* |
* @param addr Address. |
* |
* @return Pointer to respective symbol string on success, NULL otherwise. |
* @return Zero on success or negative error code, ENOENT if not found, |
* ENOTSUP if symbol table not available. |
*/ |
char * get_symtab_entry(unative_t addr) |
int symtab_name_lookup(unative_t addr, char **name) |
{ |
#ifdef CONFIG_SYMTAB |
count_t i; |
for (i = 1; symbol_table[i].address_le; ++i) { |
59,11 → 60,44 |
if (addr < uint64_t_le2host(symbol_table[i].address_le)) |
break; |
} |
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) |
return symbol_table[i - 1].symbol_name; |
return NULL; |
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) { |
*name = symbol_table[i - 1].symbol_name; |
return EOK; |
} |
*name = NULL; |
return ENOENT; |
#else |
*name = NULL; |
return ENOTSUP; |
#endif |
} |
/** Lookup symbol by address and format for display. |
* |
* Returns name of closest corresponding symbol, "Not found" if none exists |
* or "N/A" if no symbol information is available. |
* |
* @param addr Address. |
* @param name Place to store pointer to the symbol name. |
* |
* @return Pointer to a human-readable string. |
*/ |
char *symtab_fmt_name_lookup(unative_t addr) |
{ |
int rc; |
char *name; |
rc = symtab_name_lookup(addr, &name); |
switch (rc) { |
case EOK: return name; |
case ENOENT: return "Not found"; |
default: return "N/A"; |
} |
} |
#ifdef CONFIG_SYMTAB |
/** Find symbols that match the parameter forward and print them. |
* |
* @param name - search string |
102,17 → 136,22 |
return NULL; |
} |
#endif |
/** Return address that corresponds to the entry |
* |
* Search symbol table, and if there is one match, return it |
* |
* @param name Name of the symbol |
* @return 0 - Not found, -1 - Duplicate symbol, other - address of symbol |
* @param name Name of the symbol |
* @param addr Place to store symbol address |
* |
* @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate |
* symbol, ENOTSUP - no symbol information available. |
*/ |
uintptr_t get_symbol_addr(const char *name) |
int symtab_addr_lookup(const char *name, uintptr_t *addr) |
{ |
#ifdef CONFIG_SYMTAB |
count_t found = 0; |
uintptr_t addr = NULL; |
char *hint; |
int i; |
119,19 → 158,25 |
i = 0; |
while ((hint = symtab_search_one(name, &i))) { |
if (!strlen(hint)) { |
addr = uint64_t_le2host(symbol_table[i].address_le); |
*addr = uint64_t_le2host(symbol_table[i].address_le); |
found++; |
} |
i++; |
} |
if (found > 1) |
return ((uintptr_t) -1); |
return addr; |
return EOVERFLOW; |
if (found < 1) |
return ENOENT; |
return EOK; |
#else |
return ENOTSUP; |
#endif |
} |
/** Find symbols that match parameter and prints them */ |
void symtab_print_search(const char *name) |
{ |
#ifdef CONFIG_SYMTAB |
int i; |
uintptr_t addr; |
char *realname; |
144,6 → 189,9 |
printf("%p: %s\n", addr, realname); |
i++; |
} |
#else |
printf("No symbol information available.\n"); |
#endif |
} |
/** Symtab completion |
153,6 → 201,7 |
*/ |
int symtab_compl(char *input) |
{ |
#ifdef CONFIG_SYMTAB |
char output[MAX_SYMBOL_NAME + 1]; |
int startpos = 0; |
char *foundtxt; |
196,7 → 245,9 |
} |
strncpy(input, output, MAX_SYMBOL_NAME); |
return found; |
#else |
return 0; |
#endif |
} |
/** @} |
/trunk/kernel/generic/src/interrupt/interrupt.c |
---|
45,10 → 45,7 |
#include <console/cmd.h> |
#include <panic.h> |
#include <print.h> |
#ifdef CONFIG_SYMTAB |
#include <symtab.h> |
#endif |
static struct { |
const char *name; |
133,13 → 130,7 |
#endif |
for (i = 0; i < IVT_ITEMS; i++) { |
#ifdef CONFIG_SYMTAB |
symbol = get_symtab_entry((unative_t) exc_table[i].f); |
if (!symbol) |
symbol = "not found"; |
#else |
symbol = "n/a"; |
#endif |
symbol = symtab_fmt_name_lookup((unative_t) exc_table[i].f); |
#ifdef __32_BITS__ |
printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name, |
/trunk/kernel/generic/src/console/cmd.c |
---|
64,10 → 64,8 |
#include <proc/task.h> |
#include <ipc/ipc.h> |
#include <ipc/irq.h> |
#ifdef CONFIG_SYMTAB |
#include <symtab.h> |
#endif |
#include <errno.h> |
#ifdef CONFIG_TEST |
#include <test.h> |
170,7 → 168,6 |
.argv = &desc_argv |
}; |
#ifdef CONFIG_SYMTAB |
/* Data and methods for 'symaddr' command. */ |
static int cmd_symaddr(cmd_arg_t *argv); |
static char symaddr_buf[MAX_CMDLINE+1]; |
186,7 → 183,6 |
.argc = 1, |
.argv = &symaddr_argv |
}; |
#endif |
static char set_buf[MAX_CMDLINE+1]; |
static int cmd_set4(cmd_arg_t *argv); |
463,9 → 459,7 |
&ipc_info, |
&set4_info, |
&slabs_info, |
#ifdef CONFIG_SYMTAB |
&symaddr_info, |
#endif |
&sched_info, |
&threads_info, |
&tasks_info, |
612,8 → 606,6 |
return 1; |
} |
#ifdef CONFIG_SYMTAB |
/** Search symbol table */ |
int cmd_symaddr(cmd_arg_t *argv) |
{ |
622,28 → 614,31 |
return 1; |
} |
#endif |
/** Call function with zero parameters */ |
int cmd_call0(cmd_arg_t *argv) |
{ |
#ifdef CONFIG_SYMTAB |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(void); |
fncptr_t fptr; |
int rc; |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (uintptr_t) -1) { |
symtab_print_search((char *) argv->buffer); |
symbol = (char *) argv->buffer; |
rc = symtab_addr_lookup(symbol, &symaddr); |
if (rc == ENOENT) |
printf("Symbol %s not found.\n", symbol); |
else if (rc == EOVERFLOW) { |
symtab_print_search(symbol); |
printf("Duplicate symbol, be more specific.\n"); |
} else if (rc == EOK) { |
fnc = (unative_t (*)(void)) arch_construct_function(&fptr, |
(void *) symaddr, (void *) cmd_call0); |
printf("Calling %s() (%p)\n", symbol, symaddr); |
printf("Result: %#" PRIxn "\n", fnc()); |
} else { |
fnc = (unative_t (*)(void)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call0); |
printf("Calling %s() (%p)\n", argv->buffer, symaddr); |
printf("Result: %#" PRIxn "\n", fnc()); |
printf("No symbol information available.\n"); |
} |
#endif |
return 1; |
} |
679,27 → 674,29 |
/** Call function with one parameter */ |
int cmd_call1(cmd_arg_t *argv) |
{ |
#ifdef CONFIG_SYMTAB |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, ...); |
unative_t arg1 = argv[1].intval; |
fncptr_t fptr; |
symaddr = get_symbol_addr((char *) argv->buffer); |
int rc; |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (uintptr_t) -1) { |
symtab_print_search((char *) argv->buffer); |
symbol = (char *) argv->buffer; |
rc = symtab_addr_lookup(symbol, &symaddr); |
if (rc == ENOENT) { |
printf("Symbol %s not found.\n", symbol); |
} else if (rc == EOVERFLOW) { |
symtab_print_search(symbol); |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
} else if (rc == EOK) { |
fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1); |
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1)); |
} else { |
printf("No symbol information available.\n"); |
} |
#endif |
return 1; |
} |
706,7 → 703,6 |
/** Call function with two parameters */ |
int cmd_call2(cmd_arg_t *argv) |
{ |
#ifdef CONFIG_SYMTAB |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, unative_t, ...); |
713,21 → 709,24 |
unative_t arg1 = argv[1].intval; |
unative_t arg2 = argv[2].intval; |
fncptr_t fptr; |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (uintptr_t) -1) { |
symtab_print_search((char *) argv->buffer); |
int rc; |
symbol = (char *) argv->buffer; |
rc = symtab_addr_lookup(symbol, &symaddr); |
if (rc == ENOENT) { |
printf("Symbol %s not found.\n", symbol); |
} else if (rc == EOVERFLOW) { |
symtab_print_search(symbol); |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
} else if (rc == EOK) { |
fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2); |
printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", |
arg1, arg2, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2)); |
} |
#endif |
} else { |
printf("No symbol information available.\n"); |
} |
return 1; |
} |
734,7 → 733,6 |
/** Call function with three parameters */ |
int cmd_call3(cmd_arg_t *argv) |
{ |
#ifdef CONFIG_SYMTAB |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, unative_t, unative_t, ...); |
742,21 → 740,24 |
unative_t arg2 = argv[2].intval; |
unative_t arg3 = argv[3].intval; |
fncptr_t fptr; |
int rc; |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (symaddr == (uintptr_t) -1) { |
symtab_print_search((char *) argv->buffer); |
symbol = (char *) argv->buffer; |
rc = symtab_addr_lookup(symbol, &symaddr); |
if (rc == ENOENT) { |
printf("Symbol %s not found.\n", symbol); |
} else if (rc == EOVERFLOW) { |
symtab_print_search(symbol); |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
} else if (rc == EOK) { |
fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3); |
printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", |
arg1, arg2, arg3, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3)); |
} else { |
printf("No symbol information available.\n"); |
} |
#endif |
return 1; |
} |
806,41 → 807,34 |
/** Write 4 byte value to address */ |
int cmd_set4(cmd_arg_t *argv) |
{ |
uint32_t *addr; |
uintptr_t addr; |
uint32_t arg1 = argv[1].intval; |
bool pointer = false; |
int rc; |
if (((char *)argv->buffer)[0] == '*') { |
#ifdef CONFIG_SYMTAB |
addr = (uint32_t *) get_symbol_addr((char *) argv->buffer + 1); |
#else |
addr = 0; |
#endif |
rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr); |
pointer = true; |
} else if (((char *) argv->buffer)[0] >= '0' && |
((char *)argv->buffer)[0] <= '9') { |
addr = (uint32_t *)atoi((char *)argv->buffer); |
rc = EOK; |
addr = atoi((char *)argv->buffer); |
} else { |
#ifdef CONFIG_SYMTAB |
addr = (uint32_t *)get_symbol_addr((char *) argv->buffer); |
#else |
addr = 0; |
#endif |
rc = symtab_addr_lookup((char *) argv->buffer, &addr); |
} |
if (!addr) |
if (rc == ENOENT) |
printf("Symbol %s not found.\n", argv->buffer); |
else if (addr == (uint32_t *) -1) { |
#ifdef CONFIG_SYMTAB |
else if (rc == EOVERFLOW) { |
symtab_print_search((char *) argv->buffer); |
#endif |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
} else if (rc == EOK) { |
if (pointer) |
addr = (uint32_t *)(*(unative_t *)addr); |
addr = *(uintptr_t *) addr; |
printf("Writing %#" PRIx64 " -> %p\n", arg1, addr); |
*addr = arg1; |
*(uint32_t *) addr = arg1; |
} else { |
printf("No symbol information available.\n"); |
} |
return 1; |
/trunk/kernel/generic/src/console/kconsole.c |
---|
53,10 → 53,8 |
#include <macros.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/device.h> |
#ifdef CONFIG_SYMTAB |
#include <symtab.h> |
#endif |
#include <errno.h> |
/** Simple kernel console. |
* |
349,11 → 347,7 |
if (i == 0) { /* Command completion */ |
found = cmdtab_compl(tmp); |
} else { /* Symtab completion */ |
#ifdef CONFIG_SYMTAB |
found = symtab_compl(tmp); |
#else |
found = 0; |
#endif |
} |
if (found == 0) |
524,10 → 518,9 |
uintptr_t symaddr; |
bool isaddr = false; |
bool isptr = false; |
int rc; |
#ifdef CONFIG_SYMTAB |
static char symname[MAX_SYMBOL_NAME]; |
#endif |
/* If we get a name, try to find it in symbol table */ |
if (text[0] == '&') { |
540,21 → 533,21 |
len--; |
} |
if (text[0] < '0' || text[0] > '9') { |
#ifdef CONFIG_SYMTAB |
strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
symaddr = get_symbol_addr(symname); |
if (!symaddr) { |
rc = symtab_addr_lookup(symname, &symaddr); |
switch (rc) { |
case ENOENT: |
printf("Symbol %s not found.\n", symname); |
return -1; |
} |
if (symaddr == (uintptr_t) -1) { |
case EOVERFLOW: |
printf("Duplicate symbol %s.\n", symname); |
symtab_print_search(symname); |
return -1; |
default: |
printf("No symbol information available.\n"); |
return -1; |
} |
#else |
symaddr = 0; |
#endif |
if (isaddr) |
*result = (unative_t)symaddr; |
else if (isptr) |