Changeset da13982 in mainline for kernel/generic/src/debug/symtab.c
- Timestamp:
- 2023-10-26T15:20:07Z (15 months ago)
- Branches:
- master, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2fbb42f
- Parents:
- d28bdbe
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-10-26 14:42:03)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-10-26 15:20:07)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/debug/symtab.c
rd28bdbe rda13982 44 44 #include <console/prompt.h> 45 45 46 /** Get name of a symbol that seems most likely to correspond to address. 47 * 48 * @param addr Address. 49 * @param name Place to store pointer to the symbol name. 50 * @param offset Place to store offset from the symbol address. 51 * 52 * @return Zero on success or an error code, ENOENT if not found, 53 * ENOTSUP if symbol table not available. 54 * 55 */ 56 errno_t symtab_name_lookup(uintptr_t addr, const char **name, uintptr_t *offset) 57 { 58 #ifdef CONFIG_SYMTAB 59 size_t i; 60 61 for (i = 1; symbol_table[i].address_le; i++) { 62 if (addr < uint64_t_le2host(symbol_table[i].address_le)) 46 #include <abi/elf.h> 47 #include <debug/sections.h> 48 49 static inline size_t symtab_len() 50 { 51 return symtab_size / sizeof(elf_symbol_t); 52 } 53 54 static inline const char *symtab_entry_name(int entry) 55 { 56 size_t index = symtab[entry].st_name; 57 58 if (index >= strtab_size) 59 return NULL; 60 61 return strtab + index; 62 } 63 64 static inline size_t symtab_next(size_t i) 65 { 66 for (; i < symtab_len(); i++) { 67 const char *name = symtab_entry_name(i); 68 int st_bind = elf_st_bind(symtab[i].st_info); 69 int st_type = elf_st_type(symtab[i].st_info); 70 71 if (st_bind == STB_LOCAL) 72 continue; 73 74 if (name == NULL || *name == '\0') 75 continue; 76 77 if (st_type == STT_FUNC || st_type == STT_OBJECT) 63 78 break; 64 79 } 65 80 66 if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) { 67 *name = symbol_table[i - 1].symbol_name; 68 if (offset) 69 *offset = addr - 70 uint64_t_le2host(symbol_table[i - 1].address_le); 71 return EOK; 72 } 73 74 *name = NULL; 75 return ENOENT; 76 77 #else 78 *name = NULL; 79 return ENOTSUP; 80 #endif 81 return i; 82 } 83 84 const char *symtab_name_lookup(uintptr_t addr, uintptr_t *symbol_addr) 85 { 86 if (symtab == NULL || strtab == NULL) 87 return NULL; 88 89 uintptr_t closest_symbol_addr = 0; 90 uintptr_t closest_symbol_name = 0; 91 92 for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) { 93 if (symtab[i].st_value > addr) 94 continue; 95 96 if (symtab[i].st_value + symtab[i].st_size > addr) { 97 closest_symbol_addr = symtab[i].st_value; 98 closest_symbol_name = symtab[i].st_name; 99 break; 100 } 101 102 if (symtab[i].st_value > closest_symbol_addr) { 103 closest_symbol_addr = symtab[i].st_value; 104 closest_symbol_name = symtab[i].st_name; 105 } 106 } 107 108 if (closest_symbol_addr == 0) 109 return NULL; 110 111 if (symbol_addr) 112 *symbol_addr = closest_symbol_addr; 113 114 if (closest_symbol_name >= strtab_size) 115 return NULL; 116 117 return strtab + closest_symbol_name; 81 118 } 82 119 … … 95 132 const char *symtab_fmt_name_lookup(uintptr_t addr) 96 133 { 97 const char *name; 98 errno_t rc = symtab_name_lookup(addr, &name, NULL); 99 100 switch (rc) { 101 case EOK: 102 return name; 103 case ENOENT: 104 return "unknown"; 105 default: 106 return "N/A"; 107 } 108 } 109 110 #ifdef CONFIG_SYMTAB 111 112 /** Find symbols that match the parameter forward and print them. 113 * 114 * @param name Search string 115 * @param startpos Starting position, changes to found position 116 * 117 * @return Pointer to the part of string that should be completed or NULL. 118 * 119 */ 120 static const char *symtab_search_one(const char *name, size_t *startpos) 121 { 122 size_t namelen = str_length(name); 123 124 size_t pos; 125 for (pos = *startpos; symbol_table[pos].address_le; pos++) { 126 const char *curname = symbol_table[pos].symbol_name; 127 128 /* Find a ':' in curname */ 129 const char *colon = str_chr(curname, ':'); 130 if (colon == NULL) 131 continue; 132 133 if (str_length(curname) < namelen) 134 continue; 135 136 if (str_lcmp(name, curname, namelen) == 0) { 137 *startpos = pos; 138 return (curname + str_lsize(curname, namelen)); 139 } 140 } 141 142 return NULL; 143 } 144 145 #endif 134 const char *name = symtab_name_lookup(addr, NULL); 135 if (name == NULL) 136 name = "<unknown>"; 137 return name; 138 } 146 139 147 140 /** Return address that corresponds to the entry. … … 152 145 * @param addr Place to store symbol address 153 146 * 154 * @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate 155 * symbol, ENOTSUP - no symbol information available. 147 * @return Zero on success, ENOENT - not found 156 148 * 157 149 */ 158 150 errno_t symtab_addr_lookup(const char *name, uintptr_t *addr) 159 151 { 160 #ifdef CONFIG_SYMTAB 161 size_t found = 0; 162 size_t pos = 0; 163 const char *hint; 164 165 while ((hint = symtab_search_one(name, &pos))) { 166 if (str_length(hint) == 0) { 167 *addr = uint64_t_le2host(symbol_table[pos].address_le); 168 found++; 169 } 170 pos++; 171 } 172 173 if (found > 1) 174 return EOVERFLOW; 175 176 if (found < 1) 177 return ENOENT; 178 179 return EOK; 180 181 #else 182 return ENOTSUP; 183 #endif 152 for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) { 153 if (str_cmp(name, symtab_entry_name(i)) == 0) { 154 *addr = symtab[i].st_value; 155 return EOK; 156 } 157 } 158 159 return ENOENT; 184 160 } 185 161 … … 187 163 void symtab_print_search(const char *name) 188 164 { 189 #ifdef CONFIG_SYMTAB 190 size_t pos = 0; 191 while (symtab_search_one(name, &pos)) { 192 uintptr_t addr = uint64_t_le2host(symbol_table[pos].address_le); 193 char *realname = symbol_table[pos].symbol_name; 194 printf("%p: %s\n", (void *) addr, realname); 195 pos++; 196 } 197 198 #else 199 printf("No symbol information available.\n"); 200 #endif 165 if (symtab == NULL || strtab == NULL) { 166 printf("No symbol information available.\n"); 167 return; 168 } 169 170 size_t namelen = str_length(name); 171 172 for (size_t i = symtab_next(0); i < symtab_len(); i = symtab_next(i + 1)) { 173 const char *n = symtab_entry_name(i); 174 175 if (str_lcmp(name, n, namelen) == 0) { 176 printf("%p: %s\n", (void *) symtab[i].st_value, n); 177 } 178 } 201 179 } 202 180 203 181 /** Symtab completion enum, see kernel/generic/include/kconsole.h */ 204 const char *symtab_hints_enum(const char *input, const char **help, 205 void **ctx) 206 { 207 #ifdef CONFIG_SYMTAB 182 const char *symtab_hints_enum(const char *input, const char **help, void **ctx) 183 { 184 if (symtab == NULL || strtab == NULL) 185 return NULL; 186 187 if (help) 188 *help = NULL; 189 208 190 size_t len = str_length(input); 209 struct symtab_entry **entry = (struct symtab_entry **)ctx; 210 211 if (*entry == NULL) 212 *entry = symbol_table; 213 214 for (; (*entry)->address_le; (*entry)++) { 215 const char *curname = (*entry)->symbol_name; 216 217 /* Find a ':' in curname */ 218 const char *colon = str_chr(curname, ':'); 219 if (colon == NULL) 220 continue; 221 222 if (str_length(curname) < len) 223 continue; 191 for (size_t i = symtab_next((size_t) *ctx); i < symtab_len(); i = symtab_next(i + 1)) { 192 const char *curname = symtab_entry_name(i); 224 193 225 194 if (str_lcmp(input, curname, len) == 0) { 226 (*entry)++; 227 if (help) 228 *help = NULL; 195 *ctx = (void *) (i + 1); 229 196 return (curname + str_lsize(curname, len)); 230 197 } … … 232 199 233 200 return NULL; 234 235 #else236 return NULL;237 #endif238 201 } 239 202
Note:
See TracChangeset
for help on using the changeset viewer.