hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/scripts/kallsyms.c
....@@ -18,15 +18,14 @@
1818 *
1919 */
2020
21
+#include <stdbool.h>
2122 #include <stdio.h>
2223 #include <stdlib.h>
2324 #include <string.h>
2425 #include <ctype.h>
2526 #include <limits.h>
2627
27
-#ifndef ARRAY_SIZE
2828 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
29
-#endif
3029
3130 #define KSYM_NAME_LEN 128
3231
....@@ -34,8 +33,8 @@
3433 unsigned long long addr;
3534 unsigned int len;
3635 unsigned int start_pos;
37
- unsigned char *sym;
3836 unsigned int percpu_absolute;
37
+ unsigned char sym[];
3938 };
4039
4140 struct addr_range {
....@@ -48,8 +47,6 @@
4847 static struct addr_range text_ranges[] = {
4948 { "_stext", "_etext" },
5049 { "_sinittext", "_einittext" },
51
- { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */
52
- { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */
5350 };
5451 #define text_range_text (&text_ranges[0])
5552 #define text_range_inittext (&text_ranges[1])
....@@ -58,17 +55,17 @@
5855 "__per_cpu_start", "__per_cpu_end", -1ULL, 0
5956 };
6057
61
-static struct sym_entry *table;
58
+static struct sym_entry **table;
6259 static unsigned int table_size, table_cnt;
63
-static int all_symbols = 0;
64
-static int absolute_percpu = 0;
65
-static int base_relative = 0;
60
+static int all_symbols;
61
+static int absolute_percpu;
62
+static int base_relative;
6663
67
-int token_profit[0x10000];
64
+static int token_profit[0x10000];
6865
6966 /* the table that holds the result of the compression */
70
-unsigned char best_table[256][2];
71
-unsigned char best_table_len[256];
67
+static unsigned char best_table[256][2];
68
+static unsigned char best_table_len[256];
7269
7370
7471 static void usage(void)
....@@ -78,18 +75,109 @@
7875 exit(1);
7976 }
8077
81
-/*
82
- * This ignores the intensely annoying "mapping symbols" found
83
- * in ARM ELF files: $a, $t and $d.
84
- */
85
-static inline int is_arm_mapping_symbol(const char *str)
78
+static char *sym_name(const struct sym_entry *s)
8679 {
87
- return str[0] == '$' && strchr("axtd", str[1])
88
- && (str[2] == '\0' || str[2] == '.');
80
+ return (char *)s->sym + 1;
8981 }
9082
91
-static int check_symbol_range(const char *sym, unsigned long long addr,
92
- struct addr_range *ranges, int entries)
83
+static bool is_ignored_symbol(const char *name, char type)
84
+{
85
+ /* Symbol names that exactly match to the following are ignored.*/
86
+ static const char * const ignored_symbols[] = {
87
+ /*
88
+ * Symbols which vary between passes. Passes 1 and 2 must have
89
+ * identical symbol lists. The kallsyms_* symbols below are
90
+ * only added after pass 1, they would be included in pass 2
91
+ * when --all-symbols is specified so exclude them to get a
92
+ * stable symbol list.
93
+ */
94
+ "kallsyms_addresses",
95
+ "kallsyms_offsets",
96
+ "kallsyms_relative_base",
97
+ "kallsyms_num_syms",
98
+ "kallsyms_names",
99
+ "kallsyms_markers",
100
+ "kallsyms_token_table",
101
+ "kallsyms_token_index",
102
+ /* Exclude linker generated symbols which vary between passes */
103
+ "_SDA_BASE_", /* ppc */
104
+ "_SDA2_BASE_", /* ppc */
105
+ NULL
106
+ };
107
+
108
+ /* Symbol names that begin with the following are ignored.*/
109
+ static const char * const ignored_prefixes[] = {
110
+ "$", /* local symbols for ARM, MIPS, etc. */
111
+ ".LASANPC", /* s390 kasan local symbols */
112
+ "__crc_", /* modversions */
113
+ "__efistub_", /* arm64 EFI stub namespace */
114
+ "__kvm_nvhe_", /* arm64 non-VHE KVM namespace */
115
+ "__AArch64ADRPThunk_", /* arm64 lld */
116
+ "__ARMV5PILongThunk_", /* arm lld */
117
+ "__ARMV7PILongThunk_",
118
+ "__ThumbV7PILongThunk_",
119
+ "__LA25Thunk_", /* mips lld */
120
+ "__microLA25Thunk_",
121
+ NULL
122
+ };
123
+
124
+ /* Symbol names that end with the following are ignored.*/
125
+ static const char * const ignored_suffixes[] = {
126
+ "_from_arm", /* arm */
127
+ "_from_thumb", /* arm */
128
+ "_veneer", /* arm */
129
+ NULL
130
+ };
131
+
132
+ /* Symbol names that contain the following are ignored.*/
133
+ static const char * const ignored_matches[] = {
134
+ ".long_branch.", /* ppc stub */
135
+ ".plt_branch.", /* ppc stub */
136
+ NULL
137
+ };
138
+
139
+ const char * const *p;
140
+
141
+ for (p = ignored_symbols; *p; p++)
142
+ if (!strcmp(name, *p))
143
+ return true;
144
+
145
+ for (p = ignored_prefixes; *p; p++)
146
+ if (!strncmp(name, *p, strlen(*p)))
147
+ return true;
148
+
149
+ for (p = ignored_suffixes; *p; p++) {
150
+ int l = strlen(name) - strlen(*p);
151
+
152
+ if (l >= 0 && !strcmp(name + l, *p))
153
+ return true;
154
+ }
155
+
156
+ for (p = ignored_matches; *p; p++) {
157
+ if (strstr(name, *p))
158
+ return true;
159
+ }
160
+
161
+ if (type == 'U' || type == 'u')
162
+ return true;
163
+ /* exclude debugging symbols */
164
+ if (type == 'N' || type == 'n')
165
+ return true;
166
+
167
+ if (toupper(type) == 'A') {
168
+ /* Keep these useful absolute symbols */
169
+ if (strcmp(name, "__kernel_syscall_via_break") &&
170
+ strcmp(name, "__kernel_syscall_via_epc") &&
171
+ strcmp(name, "__kernel_sigtramp") &&
172
+ strcmp(name, "__gp"))
173
+ return true;
174
+ }
175
+
176
+ return false;
177
+}
178
+
179
+static void check_symbol_range(const char *sym, unsigned long long addr,
180
+ struct addr_range *ranges, int entries)
93181 {
94182 size_t i;
95183 struct addr_range *ar;
....@@ -99,88 +187,70 @@
99187
100188 if (strcmp(sym, ar->start_sym) == 0) {
101189 ar->start = addr;
102
- return 0;
190
+ return;
103191 } else if (strcmp(sym, ar->end_sym) == 0) {
104192 ar->end = addr;
105
- return 0;
193
+ return;
106194 }
107195 }
108
-
109
- return 1;
110196 }
111197
112
-static int read_symbol(FILE *in, struct sym_entry *s)
198
+static struct sym_entry *read_symbol(FILE *in)
113199 {
114
- char sym[500], stype;
200
+ char name[500], type;
201
+ unsigned long long addr;
202
+ unsigned int len;
203
+ struct sym_entry *sym;
115204 int rc;
116205
117
- rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, sym);
206
+ rc = fscanf(in, "%llx %c %499s\n", &addr, &type, name);
118207 if (rc != 3) {
119
- if (rc != EOF && fgets(sym, 500, in) == NULL)
208
+ if (rc != EOF && fgets(name, 500, in) == NULL)
120209 fprintf(stderr, "Read error or end of file.\n");
121
- return -1;
210
+ return NULL;
122211 }
123
- if (strlen(sym) >= KSYM_NAME_LEN) {
212
+ if (strlen(name) >= KSYM_NAME_LEN) {
124213 fprintf(stderr, "Symbol %s too long for kallsyms (%zu >= %d).\n"
125214 "Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
126
- sym, strlen(sym), KSYM_NAME_LEN);
127
- return -1;
215
+ name, strlen(name), KSYM_NAME_LEN);
216
+ return NULL;
128217 }
218
+
219
+ if (strcmp(name, "_text") == 0)
220
+ _text = addr;
129221
130222 /* Ignore most absolute/undefined (?) symbols. */
131
- if (strcmp(sym, "_text") == 0)
132
- _text = s->addr;
133
- else if (check_symbol_range(sym, s->addr, text_ranges,
134
- ARRAY_SIZE(text_ranges)) == 0)
135
- /* nothing to do */;
136
- else if (toupper(stype) == 'A')
137
- {
138
- /* Keep these useful absolute symbols */
139
- if (strcmp(sym, "__kernel_syscall_via_break") &&
140
- strcmp(sym, "__kernel_syscall_via_epc") &&
141
- strcmp(sym, "__kernel_sigtramp") &&
142
- strcmp(sym, "__gp"))
143
- return -1;
223
+ if (is_ignored_symbol(name, type))
224
+ return NULL;
144225
145
- }
146
- else if (toupper(stype) == 'U' ||
147
- is_arm_mapping_symbol(sym))
148
- return -1;
149
- /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
150
- else if (sym[0] == '$')
151
- return -1;
152
- /* exclude debugging symbols */
153
- else if (stype == 'N' || stype == 'n')
154
- return -1;
155
- /* exclude s390 kasan local symbols */
156
- else if (!strncmp(sym, ".LASANPC", 8))
157
- return -1;
226
+ check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
227
+ check_symbol_range(name, addr, &percpu_range, 1);
158228
159229 /* include the type field in the symbol name, so that it gets
160230 * compressed together */
161
- s->len = strlen(sym) + 1;
162
- s->sym = malloc(s->len + 1);
163
- if (!s->sym) {
231
+
232
+ len = strlen(name) + 1;
233
+
234
+ sym = malloc(sizeof(*sym) + len + 1);
235
+ if (!sym) {
164236 fprintf(stderr, "kallsyms failure: "
165237 "unable to allocate required amount of memory\n");
166238 exit(EXIT_FAILURE);
167239 }
168
- strcpy((char *)s->sym + 1, sym);
169
- s->sym[0] = stype;
240
+ sym->addr = addr;
241
+ sym->len = len;
242
+ sym->sym[0] = type;
243
+ strcpy(sym_name(sym), name);
244
+ sym->percpu_absolute = 0;
170245
171
- s->percpu_absolute = 0;
172
-
173
- /* Record if we've found __per_cpu_start/end. */
174
- check_symbol_range(sym, s->addr, &percpu_range, 1);
175
-
176
- return 0;
246
+ return sym;
177247 }
178248
179
-static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges,
180
- int entries)
249
+static int symbol_in_range(const struct sym_entry *s,
250
+ const struct addr_range *ranges, int entries)
181251 {
182252 size_t i;
183
- struct addr_range *ar;
253
+ const struct addr_range *ar;
184254
185255 for (i = 0; i < entries; ++i) {
186256 ar = &ranges[i];
....@@ -192,41 +262,9 @@
192262 return 0;
193263 }
194264
195
-static int symbol_valid(struct sym_entry *s)
265
+static int symbol_valid(const struct sym_entry *s)
196266 {
197
- /* Symbols which vary between passes. Passes 1 and 2 must have
198
- * identical symbol lists. The kallsyms_* symbols below are only added
199
- * after pass 1, they would be included in pass 2 when --all-symbols is
200
- * specified so exclude them to get a stable symbol list.
201
- */
202
- static char *special_symbols[] = {
203
- "kallsyms_addresses",
204
- "kallsyms_offsets",
205
- "kallsyms_relative_base",
206
- "kallsyms_num_syms",
207
- "kallsyms_names",
208
- "kallsyms_markers",
209
- "kallsyms_token_table",
210
- "kallsyms_token_index",
211
-
212
- /* Exclude linker generated symbols which vary between passes */
213
- "_SDA_BASE_", /* ppc */
214
- "_SDA2_BASE_", /* ppc */
215
- NULL };
216
-
217
- static char *special_prefixes[] = {
218
- "__crc_", /* modversions */
219
- "__efistub_", /* arm64 EFI stub namespace */
220
- NULL };
221
-
222
- static char *special_suffixes[] = {
223
- "_veneer", /* arm */
224
- "_from_arm", /* arm */
225
- "_from_thumb", /* arm */
226
- NULL };
227
-
228
- int i;
229
- char *sym_name = (char *)s->sym + 1;
267
+ const char *name = sym_name(s);
230268
231269 /* if --all-symbols is not specified, then symbols outside the text
232270 * and inittext sections are discarded */
....@@ -241,40 +279,50 @@
241279 * rules.
242280 */
243281 if ((s->addr == text_range_text->end &&
244
- strcmp(sym_name,
245
- text_range_text->end_sym)) ||
282
+ strcmp(name, text_range_text->end_sym)) ||
246283 (s->addr == text_range_inittext->end &&
247
- strcmp(sym_name,
248
- text_range_inittext->end_sym)))
249
- return 0;
250
- }
251
-
252
- /* Exclude symbols which vary between passes. */
253
- for (i = 0; special_symbols[i]; i++)
254
- if (strcmp(sym_name, special_symbols[i]) == 0)
255
- return 0;
256
-
257
- for (i = 0; special_prefixes[i]; i++) {
258
- int l = strlen(special_prefixes[i]);
259
-
260
- if (l <= strlen(sym_name) &&
261
- strncmp(sym_name, special_prefixes[i], l) == 0)
262
- return 0;
263
- }
264
-
265
- for (i = 0; special_suffixes[i]; i++) {
266
- int l = strlen(sym_name) - strlen(special_suffixes[i]);
267
-
268
- if (l >= 0 && strcmp(sym_name + l, special_suffixes[i]) == 0)
284
+ strcmp(name, text_range_inittext->end_sym)))
269285 return 0;
270286 }
271287
272288 return 1;
273289 }
274290
291
+/* remove all the invalid symbols from the table */
292
+static void shrink_table(void)
293
+{
294
+ unsigned int i, pos;
295
+
296
+ pos = 0;
297
+ for (i = 0; i < table_cnt; i++) {
298
+ if (symbol_valid(table[i])) {
299
+ if (pos != i)
300
+ table[pos] = table[i];
301
+ pos++;
302
+ } else {
303
+ free(table[i]);
304
+ }
305
+ }
306
+ table_cnt = pos;
307
+
308
+ /* When valid symbol is not registered, exit to error */
309
+ if (!table_cnt) {
310
+ fprintf(stderr, "No valid symbol.\n");
311
+ exit(1);
312
+ }
313
+}
314
+
275315 static void read_map(FILE *in)
276316 {
317
+ struct sym_entry *sym;
318
+
277319 while (!feof(in)) {
320
+ sym = read_symbol(in);
321
+ if (!sym)
322
+ continue;
323
+
324
+ sym->start_pos = table_cnt;
325
+
278326 if (table_cnt >= table_size) {
279327 table_size += 10000;
280328 table = realloc(table, sizeof(*table) * table_size);
....@@ -283,23 +331,30 @@
283331 exit (1);
284332 }
285333 }
286
- if (read_symbol(in, &table[table_cnt]) == 0) {
287
- table[table_cnt].start_pos = table_cnt;
288
- table_cnt++;
289
- }
334
+
335
+ table[table_cnt++] = sym;
290336 }
291337 }
292338
293
-static void output_label(char *label)
339
+static void output_label(const char *label)
294340 {
295341 printf(".globl %s\n", label);
296342 printf("\tALGN\n");
297343 printf("%s:\n", label);
298344 }
299345
346
+/* Provide proper symbols relocatability by their '_text' relativeness. */
347
+static void output_address(unsigned long long addr)
348
+{
349
+ if (_text <= addr)
350
+ printf("\tPTR\t_text + %#llx\n", addr - _text);
351
+ else
352
+ printf("\tPTR\t_text - %#llx\n", _text - addr);
353
+}
354
+
300355 /* uncompress a compressed symbol. When this function is called, the best table
301356 * might still be compressed itself, so the function needs to be recursive */
302
-static int expand_symbol(unsigned char *data, int len, char *result)
357
+static int expand_symbol(const unsigned char *data, int len, char *result)
303358 {
304359 int c, rlen, total=0;
305360
....@@ -324,7 +379,7 @@
324379 return total;
325380 }
326381
327
-static int symbol_absolute(struct sym_entry *s)
382
+static int symbol_absolute(const struct sym_entry *s)
328383 {
329384 return s->percpu_absolute;
330385 }
....@@ -336,30 +391,17 @@
336391 unsigned int *markers;
337392 char buf[KSYM_NAME_LEN];
338393
339
- printf("#include <asm/types.h>\n");
394
+ printf("#include <asm/bitsperlong.h>\n");
340395 printf("#if BITS_PER_LONG == 64\n");
341396 printf("#define PTR .quad\n");
342
- printf("#define ALGN .align 8\n");
397
+ printf("#define ALGN .balign 8\n");
343398 printf("#else\n");
344399 printf("#define PTR .long\n");
345
- printf("#define ALGN .align 4\n");
400
+ printf("#define ALGN .balign 4\n");
346401 printf("#endif\n");
347402
348403 printf("\t.section .rodata, \"a\"\n");
349404
350
- /* Provide proper symbols relocatability by their relativeness
351
- * to a fixed anchor point in the runtime image, either '_text'
352
- * for absolute address tables, in which case the linker will
353
- * emit the final addresses at build time. Otherwise, use the
354
- * offset relative to the lowest value encountered of all relative
355
- * symbols, and emit non-relocatable fixed offsets that will be fixed
356
- * up at runtime.
357
- *
358
- * The symbol names cannot be used to construct normal symbol
359
- * references as the list of symbols contains symbols that are
360
- * declared static and are private to their .o files. This prevents
361
- * .tmp_kallsyms.o or any other object from referencing them.
362
- */
363405 if (!base_relative)
364406 output_label("kallsyms_addresses");
365407 else
....@@ -367,48 +409,50 @@
367409
368410 for (i = 0; i < table_cnt; i++) {
369411 if (base_relative) {
412
+ /*
413
+ * Use the offset relative to the lowest value
414
+ * encountered of all relative symbols, and emit
415
+ * non-relocatable fixed offsets that will be fixed
416
+ * up at runtime.
417
+ */
418
+
370419 long long offset;
371420 int overflow;
372421
373422 if (!absolute_percpu) {
374
- offset = table[i].addr - relative_base;
423
+ offset = table[i]->addr - relative_base;
375424 overflow = (offset < 0 || offset > UINT_MAX);
376
- } else if (symbol_absolute(&table[i])) {
377
- offset = table[i].addr;
425
+ } else if (symbol_absolute(table[i])) {
426
+ offset = table[i]->addr;
378427 overflow = (offset < 0 || offset > INT_MAX);
379428 } else {
380
- offset = relative_base - table[i].addr - 1;
429
+ offset = relative_base - table[i]->addr - 1;
381430 overflow = (offset < INT_MIN || offset >= 0);
382431 }
383432 if (overflow) {
384433 fprintf(stderr, "kallsyms failure: "
385434 "%s symbol value %#llx out of range in relative mode\n",
386
- symbol_absolute(&table[i]) ? "absolute" : "relative",
387
- table[i].addr);
435
+ symbol_absolute(table[i]) ? "absolute" : "relative",
436
+ table[i]->addr);
388437 exit(EXIT_FAILURE);
389438 }
390439 printf("\t.long\t%#x\n", (int)offset);
391
- } else if (!symbol_absolute(&table[i])) {
392
- if (_text <= table[i].addr)
393
- printf("\tPTR\t_text + %#llx\n",
394
- table[i].addr - _text);
395
- else
396
- printf("\tPTR\t_text - %#llx\n",
397
- _text - table[i].addr);
440
+ } else if (!symbol_absolute(table[i])) {
441
+ output_address(table[i]->addr);
398442 } else {
399
- printf("\tPTR\t%#llx\n", table[i].addr);
443
+ printf("\tPTR\t%#llx\n", table[i]->addr);
400444 }
401445 }
402446 printf("\n");
403447
404448 if (base_relative) {
405449 output_label("kallsyms_relative_base");
406
- printf("\tPTR\t_text - %#llx\n", _text - relative_base);
450
+ output_address(relative_base);
407451 printf("\n");
408452 }
409453
410454 output_label("kallsyms_num_syms");
411
- printf("\tPTR\t%u\n", table_cnt);
455
+ printf("\t.long\t%u\n", table_cnt);
412456 printf("\n");
413457
414458 /* table of offset markers, that give the offset in the compressed stream
....@@ -426,18 +470,18 @@
426470 if ((i & 0xFF) == 0)
427471 markers[i >> 8] = off;
428472
429
- printf("\t.byte 0x%02x", table[i].len);
430
- for (k = 0; k < table[i].len; k++)
431
- printf(", 0x%02x", table[i].sym[k]);
473
+ printf("\t.byte 0x%02x", table[i]->len);
474
+ for (k = 0; k < table[i]->len; k++)
475
+ printf(", 0x%02x", table[i]->sym[k]);
432476 printf("\n");
433477
434
- off += table[i].len + 1;
478
+ off += table[i]->len + 1;
435479 }
436480 printf("\n");
437481
438482 output_label("kallsyms_markers");
439483 for (i = 0; i < ((table_cnt + 255) >> 8); i++)
440
- printf("\tPTR\t%d\n", markers[i]);
484
+ printf("\t.long\t%u\n", markers[i]);
441485 printf("\n");
442486
443487 free(markers);
....@@ -462,7 +506,7 @@
462506 /* table lookup compression functions */
463507
464508 /* count all the possible tokens in a symbol */
465
-static void learn_symbol(unsigned char *symbol, int len)
509
+static void learn_symbol(const unsigned char *symbol, int len)
466510 {
467511 int i;
468512
....@@ -471,7 +515,7 @@
471515 }
472516
473517 /* decrease the count for all the possible tokens in a symbol */
474
-static void forget_symbol(unsigned char *symbol, int len)
518
+static void forget_symbol(const unsigned char *symbol, int len)
475519 {
476520 int i;
477521
....@@ -479,26 +523,17 @@
479523 token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--;
480524 }
481525
482
-/* remove all the invalid symbols from the table and do the initial token count */
526
+/* do the initial token count */
483527 static void build_initial_tok_table(void)
484528 {
485
- unsigned int i, pos;
529
+ unsigned int i;
486530
487
- pos = 0;
488
- for (i = 0; i < table_cnt; i++) {
489
- if ( symbol_valid(&table[i]) ) {
490
- if (pos != i)
491
- table[pos] = table[i];
492
- learn_symbol(table[pos].sym, table[pos].len);
493
- pos++;
494
- } else {
495
- free(table[i].sym);
496
- }
497
- }
498
- table_cnt = pos;
531
+ for (i = 0; i < table_cnt; i++)
532
+ learn_symbol(table[i]->sym, table[i]->len);
499533 }
500534
501
-static void *find_token(unsigned char *str, int len, unsigned char *token)
535
+static unsigned char *find_token(unsigned char *str, int len,
536
+ const unsigned char *token)
502537 {
503538 int i;
504539
....@@ -511,22 +546,22 @@
511546
512547 /* replace a given token in all the valid symbols. Use the sampled symbols
513548 * to update the counts */
514
-static void compress_symbols(unsigned char *str, int idx)
549
+static void compress_symbols(const unsigned char *str, int idx)
515550 {
516551 unsigned int i, len, size;
517552 unsigned char *p1, *p2;
518553
519554 for (i = 0; i < table_cnt; i++) {
520555
521
- len = table[i].len;
522
- p1 = table[i].sym;
556
+ len = table[i]->len;
557
+ p1 = table[i]->sym;
523558
524559 /* find the token on the symbol */
525560 p2 = find_token(p1, len, str);
526561 if (!p2) continue;
527562
528563 /* decrease the counts for this symbol's tokens */
529
- forget_symbol(table[i].sym, len);
564
+ forget_symbol(table[i]->sym, len);
530565
531566 size = len;
532567
....@@ -545,10 +580,10 @@
545580
546581 } while (p2);
547582
548
- table[i].len = len;
583
+ table[i]->len = len;
549584
550585 /* increase the counts for this symbol's new tokens */
551
- learn_symbol(table[i].sym, len);
586
+ learn_symbol(table[i]->sym, len);
552587 }
553588 }
554589
....@@ -603,12 +638,9 @@
603638 {
604639 unsigned int i, j, c;
605640
606
- memset(best_table, 0, sizeof(best_table));
607
- memset(best_table_len, 0, sizeof(best_table_len));
608
-
609641 for (i = 0; i < table_cnt; i++) {
610
- for (j = 0; j < table[i].len; j++) {
611
- c = table[i].sym[j];
642
+ for (j = 0; j < table[i]->len; j++) {
643
+ c = table[i]->sym[j];
612644 best_table[c][0]=c;
613645 best_table_len[c]=1;
614646 }
....@@ -621,19 +653,13 @@
621653
622654 insert_real_symbols_in_table();
623655
624
- /* When valid symbol is not registered, exit to error */
625
- if (!table_cnt) {
626
- fprintf(stderr, "No valid symbol.\n");
627
- exit(1);
628
- }
629
-
630656 optimize_result();
631657 }
632658
633659 /* guess for "linker script provide" symbol */
634660 static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
635661 {
636
- const char *symbol = (char *)se->sym + 1;
662
+ const char *symbol = sym_name(se);
637663 int len = se->len - 1;
638664
639665 if (len < 8)
....@@ -665,24 +691,11 @@
665691 return 0;
666692 }
667693
668
-static int prefix_underscores_count(const char *str)
669
-{
670
- const char *tail = str;
671
-
672
- while (*tail == '_')
673
- tail++;
674
-
675
- return tail - str;
676
-}
677
-
678694 static int compare_symbols(const void *a, const void *b)
679695 {
680
- const struct sym_entry *sa;
681
- const struct sym_entry *sb;
696
+ const struct sym_entry *sa = *(const struct sym_entry **)a;
697
+ const struct sym_entry *sb = *(const struct sym_entry **)b;
682698 int wa, wb;
683
-
684
- sa = a;
685
- sb = b;
686699
687700 /* sort by address first */
688701 if (sa->addr > sb->addr)
....@@ -703,8 +716,8 @@
703716 return wa - wb;
704717
705718 /* sort by the number of prefix underscores */
706
- wa = prefix_underscores_count((const char *)sa->sym + 1);
707
- wb = prefix_underscores_count((const char *)sb->sym + 1);
719
+ wa = strspn(sym_name(sa), "_");
720
+ wb = strspn(sym_name(sb), "_");
708721 if (wa != wb)
709722 return wa - wb;
710723
....@@ -714,7 +727,7 @@
714727
715728 static void sort_symbols(void)
716729 {
717
- qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols);
730
+ qsort(table, table_cnt, sizeof(table[0]), compare_symbols);
718731 }
719732
720733 static void make_percpus_absolute(void)
....@@ -722,14 +735,14 @@
722735 unsigned int i;
723736
724737 for (i = 0; i < table_cnt; i++)
725
- if (symbol_in_range(&table[i], &percpu_range, 1)) {
738
+ if (symbol_in_range(table[i], &percpu_range, 1)) {
726739 /*
727740 * Keep the 'A' override for percpu symbols to
728741 * ensure consistent behavior compared to older
729742 * versions of this tool.
730743 */
731
- table[i].sym[0] = 'A';
732
- table[i].percpu_absolute = 1;
744
+ table[i]->sym[0] = 'A';
745
+ table[i]->percpu_absolute = 1;
733746 }
734747 }
735748
....@@ -738,11 +751,15 @@
738751 {
739752 unsigned int i;
740753
741
- relative_base = -1ULL;
742754 for (i = 0; i < table_cnt; i++)
743
- if (!symbol_absolute(&table[i]) &&
744
- table[i].addr < relative_base)
745
- relative_base = table[i].addr;
755
+ if (!symbol_absolute(table[i])) {
756
+ /*
757
+ * The table is sorted by address.
758
+ * Take the first non-absolute symbol value.
759
+ */
760
+ relative_base = table[i]->addr;
761
+ return;
762
+ }
746763 }
747764
748765 int main(int argc, char **argv)
....@@ -763,11 +780,12 @@
763780 usage();
764781
765782 read_map(stdin);
783
+ shrink_table();
766784 if (absolute_percpu)
767785 make_percpus_absolute();
786
+ sort_symbols();
768787 if (base_relative)
769788 record_relative_base();
770
- sort_symbols();
771789 optimize_token_table();
772790 write_src();
773791