123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- #include <kernel.h>
- #include <string.h>
- #include <stdio.h>
- #include <kallsyms.h>
- #include <sdfs.h>
- #if 0
- extern const unsigned long kallsyms_addresses[] __attribute__((weak));
- extern const u8_t kallsyms_names[] __attribute__((weak));
- extern const unsigned long kallsyms_num_syms
- __attribute__((weak, section(".rodata")));
- extern const u8_t kallsyms_token_table[] __attribute__((weak));
- extern const u16_t kallsyms_token_index[] __attribute__((weak));
- extern const unsigned long kallsyms_markers[] __attribute__((weak));
- extern const unsigned long __text_region_start, __text_region_end;
- extern const unsigned long __ramfunc_start, __ramfunc_end;
- int is_ksym_addr(unsigned long addr)
- {
- if ((addr >= (unsigned long)&__text_region_start &&
- addr <= (unsigned long)&__text_region_end))
- return 1;
- if ((addr >= (unsigned long)&__ramfunc_start &&
- addr <= (unsigned long)&__ramfunc_end))
- return 1;
- return 0;
- }
- static unsigned int kallsyms_expand_symbol(unsigned int off,
- char *result, size_t maxlen)
- {
- int len, skipped_first = 0;
- const u8_t *tptr, *data;
-
- data = &kallsyms_names[off];
- len = *data;
- data++;
-
- off += len + 1;
-
- while (len) {
- tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
- data++;
- len--;
- while (*tptr) {
- if (skipped_first) {
- if (maxlen <= 1)
- goto tail;
- *result = *tptr;
- result++;
- maxlen--;
- } else
- skipped_first = 1;
- tptr++;
- }
- }
- tail:
- if (maxlen)
- *result = '\0';
-
- return off;
- }
- static unsigned int get_symbol_offset(unsigned long pos)
- {
- const u8_t *name;
- int i;
-
- name = &kallsyms_names[kallsyms_markers[pos >> 8]];
-
- for (i = 0; i < (pos & 0xFF); i++)
- name = name + (*name) + 1;
- return name - kallsyms_names;
- }
- 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;
-
- low = 0;
- high = kallsyms_num_syms;
- while (high - low > 1) {
- mid = low + (high - low) / 2;
- if (kallsyms_addresses[mid] <= addr)
- low = mid;
- else
- high = mid;
- }
-
- while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
- --low;
- symbol_start = kallsyms_addresses[low];
-
- for (i = low + 1; i < kallsyms_num_syms; i++) {
- if (kallsyms_addresses[i] > symbol_start) {
- symbol_end = kallsyms_addresses[i];
- break;
- }
- }
-
- if (!symbol_end) {
- symbol_end = (unsigned long)__text_region_end;
- }
- if (symbolsize)
- *symbolsize = symbol_end - symbol_start;
- if (offset)
- *offset = addr - symbol_start;
- return low;
- }
- int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
- unsigned long *offset)
- {
- if (is_ksym_addr(addr))
- return !!get_symbol_pos(addr, symbolsize, offset);
- return 0;
- }
- const char *kallsyms_lookup(unsigned long addr,
- unsigned long *symbolsize,
- unsigned long *offset,
- char **modname, char *namebuf)
- {
- namebuf[KSYM_NAME_LEN - 1] = 0;
- namebuf[0] = 0;
- if (is_ksym_addr(addr)) {
- unsigned long pos;
- pos = get_symbol_pos(addr, symbolsize, offset);
-
- kallsyms_expand_symbol(get_symbol_offset(pos),
- namebuf, KSYM_NAME_LEN);
- if (modname)
- *modname = NULL;
- return namebuf;
- }
- return NULL;
- }
- static int __sprint_symbol(char *buffer, unsigned long address,
- int symbol_offset, int add_offset)
- {
- char *modname;
- const char *name;
- unsigned long offset, size;
- int len;
- address += symbol_offset;
- name = kallsyms_lookup(address, &size, &offset, &modname, buffer);
- if (!name)
- return sprintf(buffer, "0x%x", (unsigned int)address);
- if (name != buffer)
- strcpy(buffer, name);
- len = strlen(buffer);
- offset -= symbol_offset;
- if (add_offset)
- len += sprintf(buffer + len, "+%#x/%#x", (unsigned int)offset, (unsigned int)size);
- if (modname)
- len += sprintf(buffer + len, " [%s]", modname);
- return len;
- }
- int sprint_symbol(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, 0, 1);
- }
- int sprint_symbol_no_offset(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, 0, 0);
- }
- int sprint_backtrace(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, -1, 1);
- }
- static void __print_symbol(const char *fmt, unsigned long address)
- {
- char buffer[KSYM_SYMBOL_LEN];
- sprint_symbol(buffer, address);
- printk(fmt, buffer);
- }
- void print_symbol(const char *fmt, unsigned long addr)
- {
- __print_symbol(fmt, (unsigned long)
- __builtin_extract_return_addr((void *)addr));
- }
- #else
- static unsigned long *kallsyms_addresses;
- static u8_t *kallsyms_names;
- static unsigned long kallsyms_num_syms;
- static u8_t *kallsyms_token_table;
- static u16_t *kallsyms_token_index;
- static unsigned long *kallsyms_markers;
- extern const unsigned long __text_region_start, __text_region_end;
- extern const unsigned long __ramfunc_start, __ramfunc_end;
- int is_ksym_addr(unsigned long addr)
- {
- if ((addr >= (unsigned long)&__text_region_start &&
- addr <= (unsigned long)&__text_region_end))
- return 1;
- if ((addr >= (unsigned long)&__ramfunc_start &&
- addr <= (unsigned long)&__ramfunc_end))
- return 1;
- return 0;
- }
- static unsigned int kallsyms_expand_symbol(unsigned int off,
- char *result, size_t maxlen)
- {
- int len, skipped_first = 0;
- const u8_t *tptr, *data;
-
- data = &kallsyms_names[off];
- len = *data;
- data++;
-
- off += len + 1;
-
- while (len) {
- tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
- data++;
- len--;
- while (*tptr) {
- if (skipped_first) {
- if (maxlen <= 1)
- goto tail;
- *result = *tptr;
- result++;
- maxlen--;
- } else
- skipped_first = 1;
- tptr++;
- }
- }
- tail:
- if (maxlen)
- *result = '\0';
-
- return off;
- }
- static unsigned int get_symbol_offset(unsigned long pos)
- {
- const u8_t *name;
- int i;
-
- name = &kallsyms_names[kallsyms_markers[pos >> 8]];
-
- for (i = 0; i < (pos & 0xFF); i++)
- name = name + (*name) + 1;
- return name - kallsyms_names;
- }
- 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;
-
- low = 0;
- high = kallsyms_num_syms;
- while (high - low > 1) {
- mid = low + (high - low) / 2;
- if (kallsyms_addresses[mid] <= addr)
- low = mid;
- else
- high = mid;
- }
-
- while (low && kallsyms_addresses[low-1] == kallsyms_addresses[low])
- --low;
- symbol_start = kallsyms_addresses[low];
-
- for (i = low + 1; i < kallsyms_num_syms; i++) {
- if (kallsyms_addresses[i] > symbol_start) {
- symbol_end = kallsyms_addresses[i];
- break;
- }
- }
-
- if (!symbol_end) {
- symbol_end = (unsigned long)__text_region_end;
- }
- if (symbolsize)
- *symbolsize = symbol_end - symbol_start;
- if (offset)
- *offset = addr - symbol_start;
- return low;
- }
- int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
- unsigned long *offset)
- {
- if (is_ksym_addr(addr))
- return !!get_symbol_pos(addr, symbolsize, offset);
- return 0;
- }
- const char *kallsyms_lookup(unsigned long addr,
- unsigned long *symbolsize,
- unsigned long *offset,
- char **modname, char *namebuf)
- {
- namebuf[KSYM_NAME_LEN - 1] = 0;
- namebuf[0] = 0;
- if (is_ksym_addr(addr)) {
- unsigned long pos;
- pos = get_symbol_pos(addr, symbolsize, offset);
-
- kallsyms_expand_symbol(get_symbol_offset(pos),
- namebuf, KSYM_NAME_LEN);
- if (modname)
- *modname = NULL;
- return namebuf;
- }
- return NULL;
- }
- static int __sprint_symbol(char *buffer, unsigned long address,
- int symbol_offset, int add_offset)
- {
- char *modname;
- const char *name;
- unsigned long offset, size;
- int len;
- if(kallsyms_addresses == NULL){
- buffer[0] = '@';
- buffer[1] = 0;
- return 2;
- }
- address += symbol_offset;
- name = kallsyms_lookup(address, &size, &offset, &modname, buffer);
- if (!name)
- return sprintf(buffer, "0x%x", (unsigned int)address);
- if (name != buffer)
- strcpy(buffer, name);
- len = strlen(buffer);
- offset -= symbol_offset;
- if (add_offset)
- len += sprintf(buffer + len, "+%#x/%#x", (unsigned int)offset, (unsigned int)size);
- if (modname)
- len += sprintf(buffer + len, " [%s]", modname);
- return len;
- }
- int sprint_symbol(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, 0, 1);
- }
- int sprint_symbol_no_offset(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, 0, 0);
- }
- int sprint_backtrace(char *buffer, unsigned long address)
- {
- return __sprint_symbol(buffer, address, -1, 1);
- }
- static void __print_symbol(const char *fmt, unsigned long address)
- {
- char buffer[KSYM_SYMBOL_LEN];
- sprint_symbol(buffer, address);
- printk(fmt, buffer);
- }
- void print_symbol(const char *fmt, unsigned long addr)
- {
- __print_symbol(fmt, (unsigned long)
- __builtin_extract_return_addr((void *)addr));
- }
- #define TLV_MAGIC 0x59355935
- #define TYPE_KYMS_ADDR 0x01
- #define TYPE_KYMS_NUM 0x02
- #define TYPE_KYMS_NAME 0x03
- #define TYPE_KYMS_MARKERS 0x04
- #define TYPE_KYMS_TOKEN_TABEL 0x05
- #define TYPE_KYMS_TOKEN_INDEX 0x06
- #include <device.h>
- #if 0
- static unsigned long *kallsyms_addresses;
- static u8_t *kallsyms_names;
- static unsigned long kallsyms_num_syms;
- static u8_t *kallsyms_token_table;
- static u16_t *kallsyms_token_index;
- static unsigned long kallsyms_markers;
- #endif
- static int print_symb_init(const struct device *dev)
- {
- unsigned int *sym_addr;
- unsigned int len, off;
- if(sd_fmap("ksym.bin", (void**)&sym_addr, &len)){
- printk("ksym.bin not in sdfs\n");
- return 0;
- }
- printk("ksym=%p, len=0x%x\n", sym_addr, len);
- if(sym_addr[0] != TLV_MAGIC){
- printk("sym:magic=0x%x != 0x59355935\n", sym_addr[0]);
- return 0;
- }
- off = 0x10/4;
- printk("1.off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_ADDR){
- printk("KYMS_ADDR type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_addresses = (long unsigned int *)&sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- printk("2. off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_NUM){
- printk("TYPE_KYMS_NUM type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_num_syms = sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- printk("3. off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_NAME){
- printk("TYPE_KYMS_NAME type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_names =(u8_t *) &sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- printk("4. off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_MARKERS){
- printk("TYPE_KYMS_MARKERS type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_markers = (long unsigned int *)&sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- printk("5. off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_TOKEN_TABEL){
- printk("TYPE_KYMS_TOKEN_TABEL type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_token_table = (u8_t *) &sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- printk("6. off=0x%x, type=%d, len=0x%x\n", off*4, sym_addr[off], sym_addr[off+1]);
- if(sym_addr[off] != TYPE_KYMS_TOKEN_INDEX){
- printk("TYPE_KYMS_TOKEN_TABEL type=%d invalid\n", sym_addr[off]);
- return 0;
- }
- kallsyms_token_index = (u16_t *) &sym_addr[off+2];
- off += sym_addr[off+1]/4+2;
- return 0;
- }
- SYS_INIT(print_symb_init, PRE_KERNEL_1, 81);
- #endif
|