Changeset 68ad9d2 in mainline
- Timestamp:
- 2009-04-03T07:56:38Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 20cc877
- Parents:
- d1dabe1f
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/symtab.h
rd1dabe1f r68ad9d2 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ … … 49 49 extern int symtab_addr_lookup(const char *name, uintptr_t *addr); 50 50 extern void symtab_print_search(const char *name); 51 extern int symtab_compl(char * name);51 extern int symtab_compl(char *input, count_t size); 52 52 53 53 #ifdef CONFIG_SYMTAB -
kernel/generic/src/debug/symtab.c
rd1dabe1f r68ad9d2 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Kernel symbol resolver. 36 36 */ 37 37 … … 44 44 #include <errno.h> 45 45 46 /** Get name of 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 * 51 * @return Zero on success or negative error code, ENOENT if not found, 52 * ENOTSUP if symbol table not available. 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 * 51 * @return Zero on success or negative error code, ENOENT if not found, 52 * ENOTSUP if symbol table not available. 53 * 53 54 */ 54 55 int symtab_name_lookup(unative_t addr, char **name) … … 56 57 #ifdef CONFIG_SYMTAB 57 58 count_t i; 58 59 for (i = 1; symbol_table[i].address_le; ++i) {59 60 for (i = 1; symbol_table[i].address_le; i++) { 60 61 if (addr < uint64_t_le2host(symbol_table[i].address_le)) 61 62 break; 62 63 } 64 63 65 if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) { 64 66 *name = symbol_table[i - 1].symbol_name; 65 67 return EOK; 66 68 } 67 69 68 70 *name = NULL; 69 71 return ENOENT; 72 70 73 #else 71 74 *name = NULL; … … 79 82 * or "N/A" if no symbol information is available. 80 83 * 81 * @param addr Address. 82 * @param name Place to store pointer to the symbol name. 83 * 84 * @return Pointer to a human-readable string. 84 * @param addr Address. 85 * @param name Place to store pointer to the symbol name. 86 * 87 * @return Pointer to a human-readable string. 88 * 85 89 */ 86 90 char *symtab_fmt_name_lookup(unative_t addr) 87 91 { 88 int rc;89 92 char *name; 90 91 rc = symtab_name_lookup(addr, &name);93 int rc = symtab_name_lookup(addr, &name); 94 92 95 switch (rc) { 93 case EOK: return name; 94 case ENOENT: return "Not found"; 95 default: return "N/A"; 96 case EOK: 97 return name; 98 case ENOENT: 99 return "Not found"; 100 default: 101 return "N/A"; 96 102 } 97 103 } … … 101 107 /** Find symbols that match the parameter forward and print them. 102 108 * 103 * @param name - search string 104 * @param startpos - starting position, changes to found position 105 * @return Pointer to the part of string that should be completed or NULL 106 */ 107 static char * symtab_search_one(const char *name, int *startpos) 108 { 109 unsigned int namelen = str_size(name); 110 char *curname; 111 int i, j; 112 int colonoffset = -1; 113 114 for (i = 0; name[i]; i++) 115 if (name[i] == ':') { 116 colonoffset = i; 117 break; 109 * @param name Search string 110 * @param startpos Starting position, changes to found position 111 * 112 * @return Pointer to the part of string that should be completed or NULL. 113 * 114 */ 115 static const char *symtab_search_one(const char *name, count_t *startpos) 116 { 117 count_t namelen = str_length(name); 118 119 count_t pos; 120 for (pos = *startpos; symbol_table[pos].address_le; pos++) { 121 const char *curname = symbol_table[pos].symbol_name; 122 123 /* Find a ':' in name */ 124 const char *colon = str_chr(curname, ':'); 125 if (colon == NULL) 126 continue; 127 128 if (str_length(curname) < namelen) 129 continue; 130 131 if (str_lcmp(name, curname, namelen) == 0) { 132 *startpos = pos; 133 return (curname + str_lsize(curname, namelen)); 118 134 } 119 120 for (i = *startpos; symbol_table[i].address_le; ++i) { 121 /* Find a ':' in name */ 122 curname = symbol_table[i].symbol_name; 123 for (j = 0; curname[j] && curname[j] != ':'; j++) 124 ; 125 if (!curname[j]) 126 continue; 127 j -= colonoffset; 128 curname += j; 129 if (str_size(curname) < namelen) 130 continue; 131 if (strncmp(curname, name, namelen) == 0) { 132 *startpos = i; 133 return curname + namelen; 134 } 135 } 135 } 136 136 137 return NULL; 137 138 } … … 139 140 #endif 140 141 141 /** Return address that corresponds to the entry 142 /** Return address that corresponds to the entry. 142 143 * 143 144 * Search symbol table, and if there is one match, return it 144 145 * 145 * @param name Name of the symbol 146 * @param addr Place to store symbol address 147 * 148 * @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate 149 * symbol, ENOTSUP - no symbol information available. 146 * @param name Name of the symbol 147 * @param addr Place to store symbol address 148 * 149 * @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate 150 * symbol, ENOTSUP - no symbol information available. 151 * 150 152 */ 151 153 int symtab_addr_lookup(const char *name, uintptr_t *addr) … … 153 155 #ifdef CONFIG_SYMTAB 154 156 count_t found = 0; 155 char *hint; 156 int i; 157 158 i = 0; 159 while ((hint = symtab_search_one(name, &i))) { 160 if (!str_size(hint)) { 161 *addr = uint64_t_le2host(symbol_table[i].address_le); 157 count_t pos = 0; 158 const char *hint; 159 160 while ((hint = symtab_search_one(name, &pos))) { 161 if (str_length(hint) == 0) { 162 *addr = uint64_t_le2host(symbol_table[pos].address_le); 162 163 found++; 163 164 } 164 i++; 165 } 165 pos++; 166 } 167 166 168 if (found > 1) 167 169 return EOVERFLOW; 170 168 171 if (found < 1) 169 172 return ENOENT; 173 170 174 return EOK; 175 171 176 #else 172 177 return ENOTSUP; … … 174 179 } 175 180 176 /** Find symbols that match parameter and print sthem */181 /** Find symbols that match parameter and print them */ 177 182 void symtab_print_search(const char *name) 178 183 { 179 184 #ifdef CONFIG_SYMTAB 180 int i; 181 uintptr_t addr; 182 char *realname; 183 184 185 i = 0; 186 while (symtab_search_one(name, &i)) { 187 addr = uint64_t_le2host(symbol_table[i].address_le); 188 realname = symbol_table[i].symbol_name; 185 count_t pos = 0; 186 while (symtab_search_one(name, &pos)) { 187 uintptr_t addr = uint64_t_le2host(symbol_table[pos].address_le); 188 char *realname = symbol_table[pos].symbol_name; 189 189 printf("%p: %s\n", addr, realname); 190 i++; 191 } 190 pos++; 191 } 192 192 193 #else 193 194 printf("No symbol information available.\n"); … … 197 198 /** Symtab completion 198 199 * 199 * @param input - Search string, completes to symbol name 200 * @returns - 0 - nothing found, 1 - success, >1 print duplicates 201 */ 202 int symtab_compl(char *input) 203 { 204 #ifdef CONFIG_SYMTAB 205 char output[MAX_SYMBOL_NAME + 1]; 206 int startpos = 0; 207 char *foundtxt; 208 int found = 0; 209 int i; 210 char *name = input; 211 212 /* Allow completion of pointers */ 213 if (name[0] == '*' || name[0] == '&') 200 * @param input Search string, completes to symbol name 201 * @param size Input buffer size 202 * 203 * @return 0 - nothing found, 1 - success, >1 print duplicates 204 * 205 */ 206 int symtab_compl(char *input, count_t size) 207 { 208 #ifdef CONFIG_SYMTAB 209 const char *name = input; 210 211 /* Allow completion of pointers */ 212 if ((name[0] == '*') || (name[0] == '&')) 214 213 name++; 215 216 /* Do not print everything*/217 if ( !str_size(name))214 215 /* Do not print all symbols */ 216 if (str_length(name) == 0) 218 217 return 0; 219 218 220 221 output[0] = '\0'; 222 223 while ((foundtxt = symtab_search_one(name, &startpos))) { 224 startpos++; 225 if (!found) 226 strncpy(output, foundtxt, str_size(foundtxt) + 1); 227 else { 228 for (i = 0; output[i] && foundtxt[i] && 229 output[i] == foundtxt[i]; i++) 230 ; 231 output[i] = '\0'; 219 count_t found = 0; 220 count_t pos = 0; 221 const char *hint; 222 char output[MAX_SYMBOL_NAME]; 223 224 output[0] = 0; 225 226 while ((hint = symtab_search_one(name, &pos))) { 227 if ((found == 0) || (str_length(output) > str_length(hint))) 228 str_ncpy(output, hint, MAX_SYMBOL_NAME); 229 230 pos++; 231 found++; 232 } 233 234 if ((found > 1) && (str_length(output) != 0)) { 235 printf("\n"); 236 pos = 0; 237 while ((hint = symtab_search_one(name, &pos))) { 238 printf("%s\n", symbol_table[pos].symbol_name); 239 pos++; 232 240 } 233 found++; 234 } 235 if (!found) 236 return 0; 237 238 if (found > 1 && !str_size(output)) { 239 printf("\n"); 240 startpos = 0; 241 while ((foundtxt = symtab_search_one(name, &startpos))) { 242 printf("%s\n", symbol_table[startpos].symbol_name); 243 startpos++; 244 } 245 } 246 strncpy(input, output, MAX_SYMBOL_NAME); 241 } 242 243 if (found > 0) 244 str_ncpy(input, output, size); 245 247 246 return found; 247 248 248 #else 249 249 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.