diff options
Diffstat (limited to 'scripts/kallsyms.c')
| -rw-r--r-- | scripts/kallsyms.c | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 090ffda4adbc..fe11df83d1fc 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
| @@ -69,6 +69,7 @@ static struct sym_entry *table; | |||
| 69 | static int size, cnt; | 69 | static int size, cnt; |
| 70 | static unsigned long long _stext, _etext, _sinittext, _einittext; | 70 | static unsigned long long _stext, _etext, _sinittext, _einittext; |
| 71 | static int all_symbols = 0; | 71 | static int all_symbols = 0; |
| 72 | static char symbol_prefix_char = '\0'; | ||
| 72 | 73 | ||
| 73 | struct token { | 74 | struct token { |
| 74 | unsigned char data[MAX_TOK_SIZE]; | 75 | unsigned char data[MAX_TOK_SIZE]; |
| @@ -93,7 +94,7 @@ unsigned char best_table_len[256]; | |||
| 93 | static void | 94 | static void |
| 94 | usage(void) | 95 | usage(void) |
| 95 | { | 96 | { |
| 96 | fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n"); | 97 | fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n"); |
| 97 | exit(1); | 98 | exit(1); |
| 98 | } | 99 | } |
| 99 | 100 | ||
| @@ -112,6 +113,7 @@ static int | |||
| 112 | read_symbol(FILE *in, struct sym_entry *s) | 113 | read_symbol(FILE *in, struct sym_entry *s) |
| 113 | { | 114 | { |
| 114 | char str[500]; | 115 | char str[500]; |
| 116 | char *sym; | ||
| 115 | int rc; | 117 | int rc; |
| 116 | 118 | ||
| 117 | rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str); | 119 | rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str); |
| @@ -123,27 +125,32 @@ read_symbol(FILE *in, struct sym_entry *s) | |||
| 123 | return -1; | 125 | return -1; |
| 124 | } | 126 | } |
| 125 | 127 | ||
| 128 | sym = str; | ||
| 129 | /* skip prefix char */ | ||
| 130 | if (symbol_prefix_char && str[0] == symbol_prefix_char) | ||
| 131 | sym++; | ||
| 132 | |||
| 126 | /* Ignore most absolute/undefined (?) symbols. */ | 133 | /* Ignore most absolute/undefined (?) symbols. */ |
| 127 | if (strcmp(str, "_stext") == 0) | 134 | if (strcmp(sym, "_stext") == 0) |
| 128 | _stext = s->addr; | 135 | _stext = s->addr; |
| 129 | else if (strcmp(str, "_etext") == 0) | 136 | else if (strcmp(sym, "_etext") == 0) |
| 130 | _etext = s->addr; | 137 | _etext = s->addr; |
| 131 | else if (strcmp(str, "_sinittext") == 0) | 138 | else if (strcmp(sym, "_sinittext") == 0) |
| 132 | _sinittext = s->addr; | 139 | _sinittext = s->addr; |
| 133 | else if (strcmp(str, "_einittext") == 0) | 140 | else if (strcmp(sym, "_einittext") == 0) |
| 134 | _einittext = s->addr; | 141 | _einittext = s->addr; |
| 135 | else if (toupper(s->type) == 'A') | 142 | else if (toupper(s->type) == 'A') |
| 136 | { | 143 | { |
| 137 | /* Keep these useful absolute symbols */ | 144 | /* Keep these useful absolute symbols */ |
| 138 | if (strcmp(str, "__kernel_syscall_via_break") && | 145 | if (strcmp(sym, "__kernel_syscall_via_break") && |
| 139 | strcmp(str, "__kernel_syscall_via_epc") && | 146 | strcmp(sym, "__kernel_syscall_via_epc") && |
| 140 | strcmp(str, "__kernel_sigtramp") && | 147 | strcmp(sym, "__kernel_sigtramp") && |
| 141 | strcmp(str, "__gp")) | 148 | strcmp(sym, "__gp")) |
| 142 | return -1; | 149 | return -1; |
| 143 | 150 | ||
| 144 | } | 151 | } |
| 145 | else if (toupper(s->type) == 'U' || | 152 | else if (toupper(s->type) == 'U' || |
| 146 | is_arm_mapping_symbol(str)) | 153 | is_arm_mapping_symbol(sym)) |
| 147 | return -1; | 154 | return -1; |
| 148 | 155 | ||
| 149 | /* include the type field in the symbol name, so that it gets | 156 | /* include the type field in the symbol name, so that it gets |
| @@ -177,6 +184,11 @@ symbol_valid(struct sym_entry *s) | |||
| 177 | "_SDA2_BASE_", /* ppc */ | 184 | "_SDA2_BASE_", /* ppc */ |
| 178 | NULL }; | 185 | NULL }; |
| 179 | int i; | 186 | int i; |
| 187 | int offset = 1; | ||
| 188 | |||
| 189 | /* skip prefix char */ | ||
| 190 | if (symbol_prefix_char && *(s->sym + 1) == symbol_prefix_char) | ||
| 191 | offset++; | ||
| 180 | 192 | ||
| 181 | /* if --all-symbols is not specified, then symbols outside the text | 193 | /* if --all-symbols is not specified, then symbols outside the text |
| 182 | * and inittext sections are discarded */ | 194 | * and inittext sections are discarded */ |
| @@ -190,17 +202,17 @@ symbol_valid(struct sym_entry *s) | |||
| 190 | * they may get dropped in pass 2, which breaks the kallsyms | 202 | * they may get dropped in pass 2, which breaks the kallsyms |
| 191 | * rules. | 203 | * rules. |
| 192 | */ | 204 | */ |
| 193 | if ((s->addr == _etext && strcmp(s->sym + 1, "_etext")) || | 205 | if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) || |
| 194 | (s->addr == _einittext && strcmp(s->sym + 1, "_einittext"))) | 206 | (s->addr == _einittext && strcmp(s->sym + offset, "_einittext"))) |
| 195 | return 0; | 207 | return 0; |
| 196 | } | 208 | } |
| 197 | 209 | ||
| 198 | /* Exclude symbols which vary between passes. */ | 210 | /* Exclude symbols which vary between passes. */ |
| 199 | if (strstr(s->sym + 1, "_compiled.")) | 211 | if (strstr(s->sym + offset, "_compiled.")) |
| 200 | return 0; | 212 | return 0; |
| 201 | 213 | ||
| 202 | for (i = 0; special_symbols[i]; i++) | 214 | for (i = 0; special_symbols[i]; i++) |
| 203 | if( strcmp(s->sym + 1, special_symbols[i]) == 0 ) | 215 | if( strcmp(s->sym + offset, special_symbols[i]) == 0 ) |
| 204 | return 0; | 216 | return 0; |
| 205 | 217 | ||
| 206 | return 1; | 218 | return 1; |
| @@ -225,9 +237,15 @@ read_map(FILE *in) | |||
| 225 | 237 | ||
| 226 | static void output_label(char *label) | 238 | static void output_label(char *label) |
| 227 | { | 239 | { |
| 228 | printf(".globl %s\n",label); | 240 | if (symbol_prefix_char) |
| 241 | printf(".globl %c%s\n", symbol_prefix_char, label); | ||
| 242 | else | ||
| 243 | printf(".globl %s\n", label); | ||
| 229 | printf("\tALGN\n"); | 244 | printf("\tALGN\n"); |
| 230 | printf("%s:\n",label); | 245 | if (symbol_prefix_char) |
| 246 | printf("%c%s:\n", symbol_prefix_char, label); | ||
| 247 | else | ||
| 248 | printf("%s:\n", label); | ||
| 231 | } | 249 | } |
| 232 | 250 | ||
| 233 | /* uncompress a compressed symbol. When this function is called, the best table | 251 | /* uncompress a compressed symbol. When this function is called, the best table |
| @@ -665,6 +683,13 @@ static void optimize_token_table(void) | |||
| 665 | 683 | ||
| 666 | insert_real_symbols_in_table(); | 684 | insert_real_symbols_in_table(); |
| 667 | 685 | ||
| 686 | /* When valid symbol is not registered, exit to error */ | ||
| 687 | if (good_head.left == good_head.right && | ||
| 688 | bad_head.left == bad_head.right) { | ||
| 689 | fprintf(stderr, "No valid symbol.\n"); | ||
| 690 | exit(1); | ||
| 691 | } | ||
| 692 | |||
| 668 | optimize_result(); | 693 | optimize_result(); |
| 669 | } | 694 | } |
| 670 | 695 | ||
| @@ -672,9 +697,21 @@ static void optimize_token_table(void) | |||
| 672 | int | 697 | int |
| 673 | main(int argc, char **argv) | 698 | main(int argc, char **argv) |
| 674 | { | 699 | { |
| 675 | if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0) | 700 | if (argc >= 2) { |
| 676 | all_symbols = 1; | 701 | int i; |
| 677 | else if (argc != 1) | 702 | for (i = 1; i < argc; i++) { |
| 703 | if(strcmp(argv[i], "--all-symbols") == 0) | ||
| 704 | all_symbols = 1; | ||
| 705 | else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { | ||
| 706 | char *p = &argv[i][16]; | ||
| 707 | /* skip quote */ | ||
| 708 | if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\'')) | ||
| 709 | p++; | ||
| 710 | symbol_prefix_char = *p; | ||
| 711 | } else | ||
| 712 | usage(); | ||
| 713 | } | ||
| 714 | } else if (argc != 1) | ||
| 678 | usage(); | 715 | usage(); |
| 679 | 716 | ||
| 680 | read_map(stdin); | 717 | read_map(stdin); |
| @@ -683,4 +720,3 @@ main(int argc, char **argv) | |||
| 683 | 720 | ||
| 684 | return 0; | 721 | return 0; |
| 685 | } | 722 | } |
| 686 | |||
