xref: /linux/scripts/kallsyms.c (revision 505d66d1abfb90853e24ab6cbdf83b611473d6fc)
1 /* Generate assembler source containing symbol information
2  *
3  * Copyright 2002       by Kai Germaschewski
4  *
5  * This software may be used and distributed according to the terms
6  * of the GNU General Public License, incorporated herein by reference.
7  *
8  * Usage: kallsyms [--all-symbols] [--absolute-percpu]
9  *                         [--base-relative] [--lto-clang] in.map > out.S
10  *
11  *      Table compression uses all the unused char codes on the symbols and
12  *  maps these to the most used substrings (tokens). For instance, it might
13  *  map char code 0xF7 to represent "write_" and then in every symbol where
14  *  "write_" appears it can be replaced by 0xF7, saving 5 bytes.
15  *      The used codes themselves are also placed in the table so that the
16  *  decompresion can work without "special cases".
17  *      Applied to kernel symbols, this usually produces a compression ratio
18  *  of about 50%.
19  *
20  */
21 
22 #include <errno.h>
23 #include <getopt.h>
24 #include <stdbool.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <limits.h>
30 
31 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
32 
33 #define KSYM_NAME_LEN		512
34 
35 struct sym_entry {
36 	unsigned long long addr;
37 	unsigned int len;
38 	unsigned int seq;
39 	unsigned int start_pos;
40 	unsigned int percpu_absolute;
41 	unsigned char sym[];
42 };
43 
44 struct addr_range {
45 	const char *start_sym, *end_sym;
46 	unsigned long long start, end;
47 };
48 
49 static unsigned long long _text;
50 static unsigned long long relative_base;
51 static struct addr_range text_ranges[] = {
52 	{ "_stext",     "_etext"     },
53 	{ "_sinittext", "_einittext" },
54 };
55 #define text_range_text     (&text_ranges[0])
56 #define text_range_inittext (&text_ranges[1])
57 
58 static struct addr_range percpu_range = {
59 	"__per_cpu_start", "__per_cpu_end", -1ULL, 0
60 };
61 
62 static struct sym_entry **table;
63 static unsigned int table_size, table_cnt;
64 static int all_symbols;
65 static int absolute_percpu;
66 static int base_relative;
67 static int lto_clang;
68 
69 static int token_profit[0x10000];
70 
71 /* the table that holds the result of the compression */
72 static unsigned char best_table[256][2];
73 static unsigned char best_table_len[256];
74 
75 
76 static void usage(void)
77 {
78 	fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] "
79 			"[--base-relative] [--lto-clang] in.map > out.S\n");
80 	exit(1);
81 }
82 
83 static char *sym_name(const struct sym_entry *s)
84 {
85 	return (char *)s->sym + 1;
86 }
87 
88 static bool is_ignored_symbol(const char *name, char type)
89 {
90 	if (type == 'u' || type == 'n')
91 		return true;
92 
93 	if (toupper(type) == 'A') {
94 		/* Keep these useful absolute symbols */
95 		if (strcmp(name, "__kernel_syscall_via_break") &&
96 		    strcmp(name, "__kernel_syscall_via_epc") &&
97 		    strcmp(name, "__kernel_sigtramp") &&
98 		    strcmp(name, "__gp"))
99 			return true;
100 	}
101 
102 	return false;
103 }
104 
105 static void check_symbol_range(const char *sym, unsigned long long addr,
106 			       struct addr_range *ranges, int entries)
107 {
108 	size_t i;
109 	struct addr_range *ar;
110 
111 	for (i = 0; i < entries; ++i) {
112 		ar = &ranges[i];
113 
114 		if (strcmp(sym, ar->start_sym) == 0) {
115 			ar->start = addr;
116 			return;
117 		} else if (strcmp(sym, ar->end_sym) == 0) {
118 			ar->end = addr;
119 			return;
120 		}
121 	}
122 }
123 
124 static struct sym_entry *read_symbol(FILE *in, char **buf, size_t *buf_len)
125 {
126 	char *name, type, *p;
127 	unsigned long long addr;
128 	size_t len;
129 	ssize_t readlen;
130 	struct sym_entry *sym;
131 
132 	errno = 0;
133 	readlen = getline(buf, buf_len, in);
134 	if (readlen < 0) {
135 		if (errno) {
136 			perror("read_symbol");
137 			exit(EXIT_FAILURE);
138 		}
139 		return NULL;
140 	}
141 
142 	if ((*buf)[readlen - 1] == '\n')
143 		(*buf)[readlen - 1] = 0;
144 
145 	addr = strtoull(*buf, &p, 16);
146 
147 	if (*buf == p || *p++ != ' ' || !isascii((type = *p++)) || *p++ != ' ') {
148 		fprintf(stderr, "line format error\n");
149 		exit(EXIT_FAILURE);
150 	}
151 
152 	name = p;
153 	len = strlen(name);
154 
155 	if (len >= KSYM_NAME_LEN) {
156 		fprintf(stderr, "Symbol %s too long for kallsyms (%zu >= %d).\n"
157 				"Please increase KSYM_NAME_LEN both in kernel and kallsyms.c\n",
158 			name, len, KSYM_NAME_LEN);
159 		return NULL;
160 	}
161 
162 	if (strcmp(name, "_text") == 0)
163 		_text = addr;
164 
165 	/* Ignore most absolute/undefined (?) symbols. */
166 	if (is_ignored_symbol(name, type))
167 		return NULL;
168 
169 	check_symbol_range(name, addr, text_ranges, ARRAY_SIZE(text_ranges));
170 	check_symbol_range(name, addr, &percpu_range, 1);
171 
172 	/* include the type field in the symbol name, so that it gets
173 	 * compressed together */
174 	len++;
175 
176 	sym = malloc(sizeof(*sym) + len + 1);
177 	if (!sym) {
178 		fprintf(stderr, "kallsyms failure: "
179 			"unable to allocate required amount of memory\n");
180 		exit(EXIT_FAILURE);
181 	}
182 	sym->addr = addr;
183 	sym->len = len;
184 	sym->sym[0] = type;
185 	strcpy(sym_name(sym), name);
186 	sym->percpu_absolute = 0;
187 
188 	return sym;
189 }
190 
191 static int symbol_in_range(const struct sym_entry *s,
192 			   const struct addr_range *ranges, int entries)
193 {
194 	size_t i;
195 	const struct addr_range *ar;
196 
197 	for (i = 0; i < entries; ++i) {
198 		ar = &ranges[i];
199 
200 		if (s->addr >= ar->start && s->addr <= ar->end)
201 			return 1;
202 	}
203 
204 	return 0;
205 }
206 
207 static bool string_starts_with(const char *s, const char *prefix)
208 {
209 	return strncmp(s, prefix, strlen(prefix)) == 0;
210 }
211 
212 static int symbol_valid(const struct sym_entry *s)
213 {
214 	const char *name = sym_name(s);
215 
216 	/* if --all-symbols is not specified, then symbols outside the text
217 	 * and inittext sections are discarded */
218 	if (!all_symbols) {
219 		/*
220 		 * Symbols starting with __start and __stop are used to denote
221 		 * section boundaries, and should always be included:
222 		 */
223 		if (string_starts_with(name, "__start_") ||
224 		    string_starts_with(name, "__stop_"))
225 			return 1;
226 
227 		if (symbol_in_range(s, text_ranges,
228 				    ARRAY_SIZE(text_ranges)) == 0)
229 			return 0;
230 		/* Corner case.  Discard any symbols with the same value as
231 		 * _etext _einittext; they can move between pass 1 and 2 when
232 		 * the kallsyms data are added.  If these symbols move then
233 		 * they may get dropped in pass 2, which breaks the kallsyms
234 		 * rules.
235 		 */
236 		if ((s->addr == text_range_text->end &&
237 		     strcmp(name, text_range_text->end_sym)) ||
238 		    (s->addr == text_range_inittext->end &&
239 		     strcmp(name, text_range_inittext->end_sym)))
240 			return 0;
241 	}
242 
243 	return 1;
244 }
245 
246 /* remove all the invalid symbols from the table */
247 static void shrink_table(void)
248 {
249 	unsigned int i, pos;
250 
251 	pos = 0;
252 	for (i = 0; i < table_cnt; i++) {
253 		if (symbol_valid(table[i])) {
254 			if (pos != i)
255 				table[pos] = table[i];
256 			pos++;
257 		} else {
258 			free(table[i]);
259 		}
260 	}
261 	table_cnt = pos;
262 
263 	/* When valid symbol is not registered, exit to error */
264 	if (!table_cnt) {
265 		fprintf(stderr, "No valid symbol.\n");
266 		exit(1);
267 	}
268 }
269 
270 static void read_map(const char *in)
271 {
272 	FILE *fp;
273 	struct sym_entry *sym;
274 	char *buf = NULL;
275 	size_t buflen = 0;
276 
277 	fp = fopen(in, "r");
278 	if (!fp) {
279 		perror(in);
280 		exit(1);
281 	}
282 
283 	while (!feof(fp)) {
284 		sym = read_symbol(fp, &buf, &buflen);
285 		if (!sym)
286 			continue;
287 
288 		sym->start_pos = table_cnt;
289 
290 		if (table_cnt >= table_size) {
291 			table_size += 10000;
292 			table = realloc(table, sizeof(*table) * table_size);
293 			if (!table) {
294 				fprintf(stderr, "out of memory\n");
295 				fclose(fp);
296 				exit (1);
297 			}
298 		}
299 
300 		table[table_cnt++] = sym;
301 	}
302 
303 	free(buf);
304 	fclose(fp);
305 }
306 
307 static void output_label(const char *label)
308 {
309 	printf(".globl %s\n", label);
310 	printf("\tALGN\n");
311 	printf("%s:\n", label);
312 }
313 
314 /* Provide proper symbols relocatability by their '_text' relativeness. */
315 static void output_address(unsigned long long addr)
316 {
317 	if (_text <= addr)
318 		printf("\tPTR\t_text + %#llx\n", addr - _text);
319 	else
320 		printf("\tPTR\t_text - %#llx\n", _text - addr);
321 }
322 
323 /* uncompress a compressed symbol. When this function is called, the best table
324  * might still be compressed itself, so the function needs to be recursive */
325 static int expand_symbol(const unsigned char *data, int len, char *result)
326 {
327 	int c, rlen, total=0;
328 
329 	while (len) {
330 		c = *data;
331 		/* if the table holds a single char that is the same as the one
332 		 * we are looking for, then end the search */
333 		if (best_table[c][0]==c && best_table_len[c]==1) {
334 			*result++ = c;
335 			total++;
336 		} else {
337 			/* if not, recurse and expand */
338 			rlen = expand_symbol(best_table[c], best_table_len[c], result);
339 			total += rlen;
340 			result += rlen;
341 		}
342 		data++;
343 		len--;
344 	}
345 	*result=0;
346 
347 	return total;
348 }
349 
350 static int symbol_absolute(const struct sym_entry *s)
351 {
352 	return s->percpu_absolute;
353 }
354 
355 static void cleanup_symbol_name(char *s)
356 {
357 	char *p;
358 
359 	/*
360 	 * ASCII[.]   = 2e
361 	 * ASCII[0-9] = 30,39
362 	 * ASCII[A-Z] = 41,5a
363 	 * ASCII[_]   = 5f
364 	 * ASCII[a-z] = 61,7a
365 	 *
366 	 * As above, replacing the first '.' in ".llvm." with '\0' does not
367 	 * affect the main sorting, but it helps us with subsorting.
368 	 */
369 	p = strstr(s, ".llvm.");
370 	if (p)
371 		*p = '\0';
372 }
373 
374 static int compare_names(const void *a, const void *b)
375 {
376 	int ret;
377 	const struct sym_entry *sa = *(const struct sym_entry **)a;
378 	const struct sym_entry *sb = *(const struct sym_entry **)b;
379 
380 	ret = strcmp(sym_name(sa), sym_name(sb));
381 	if (!ret) {
382 		if (sa->addr > sb->addr)
383 			return 1;
384 		else if (sa->addr < sb->addr)
385 			return -1;
386 
387 		/* keep old order */
388 		return (int)(sa->seq - sb->seq);
389 	}
390 
391 	return ret;
392 }
393 
394 static void sort_symbols_by_name(void)
395 {
396 	qsort(table, table_cnt, sizeof(table[0]), compare_names);
397 }
398 
399 static void write_src(void)
400 {
401 	unsigned int i, k, off;
402 	unsigned int best_idx[256];
403 	unsigned int *markers;
404 	char buf[KSYM_NAME_LEN];
405 
406 	printf("#include <asm/bitsperlong.h>\n");
407 	printf("#if BITS_PER_LONG == 64\n");
408 	printf("#define PTR .quad\n");
409 	printf("#define ALGN .balign 8\n");
410 	printf("#else\n");
411 	printf("#define PTR .long\n");
412 	printf("#define ALGN .balign 4\n");
413 	printf("#endif\n");
414 
415 	printf("\t.section .rodata, \"a\"\n");
416 
417 	output_label("kallsyms_num_syms");
418 	printf("\t.long\t%u\n", table_cnt);
419 	printf("\n");
420 
421 	/* table of offset markers, that give the offset in the compressed stream
422 	 * every 256 symbols */
423 	markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256));
424 	if (!markers) {
425 		fprintf(stderr, "kallsyms failure: "
426 			"unable to allocate required memory\n");
427 		exit(EXIT_FAILURE);
428 	}
429 
430 	output_label("kallsyms_names");
431 	off = 0;
432 	for (i = 0; i < table_cnt; i++) {
433 		if ((i & 0xFF) == 0)
434 			markers[i >> 8] = off;
435 		table[i]->seq = i;
436 
437 		/* There cannot be any symbol of length zero. */
438 		if (table[i]->len == 0) {
439 			fprintf(stderr, "kallsyms failure: "
440 				"unexpected zero symbol length\n");
441 			exit(EXIT_FAILURE);
442 		}
443 
444 		/* Only lengths that fit in up-to-two-byte ULEB128 are supported. */
445 		if (table[i]->len > 0x3FFF) {
446 			fprintf(stderr, "kallsyms failure: "
447 				"unexpected huge symbol length\n");
448 			exit(EXIT_FAILURE);
449 		}
450 
451 		/* Encode length with ULEB128. */
452 		if (table[i]->len <= 0x7F) {
453 			/* Most symbols use a single byte for the length. */
454 			printf("\t.byte 0x%02x", table[i]->len);
455 			off += table[i]->len + 1;
456 		} else {
457 			/* "Big" symbols use two bytes. */
458 			printf("\t.byte 0x%02x, 0x%02x",
459 				(table[i]->len & 0x7F) | 0x80,
460 				(table[i]->len >> 7) & 0x7F);
461 			off += table[i]->len + 2;
462 		}
463 		for (k = 0; k < table[i]->len; k++)
464 			printf(", 0x%02x", table[i]->sym[k]);
465 		printf("\n");
466 	}
467 	printf("\n");
468 
469 	/*
470 	 * Now that we wrote out the compressed symbol names, restore the
471 	 * original names, which are needed in some of the later steps.
472 	 */
473 	for (i = 0; i < table_cnt; i++) {
474 		expand_symbol(table[i]->sym, table[i]->len, buf);
475 		strcpy((char *)table[i]->sym, buf);
476 	}
477 
478 	output_label("kallsyms_markers");
479 	for (i = 0; i < ((table_cnt + 255) >> 8); i++)
480 		printf("\t.long\t%u\n", markers[i]);
481 	printf("\n");
482 
483 	free(markers);
484 
485 	output_label("kallsyms_token_table");
486 	off = 0;
487 	for (i = 0; i < 256; i++) {
488 		best_idx[i] = off;
489 		expand_symbol(best_table[i], best_table_len[i], buf);
490 		printf("\t.asciz\t\"%s\"\n", buf);
491 		off += strlen(buf) + 1;
492 	}
493 	printf("\n");
494 
495 	output_label("kallsyms_token_index");
496 	for (i = 0; i < 256; i++)
497 		printf("\t.short\t%d\n", best_idx[i]);
498 	printf("\n");
499 
500 	if (!base_relative)
501 		output_label("kallsyms_addresses");
502 	else
503 		output_label("kallsyms_offsets");
504 
505 	for (i = 0; i < table_cnt; i++) {
506 		if (base_relative) {
507 			/*
508 			 * Use the offset relative to the lowest value
509 			 * encountered of all relative symbols, and emit
510 			 * non-relocatable fixed offsets that will be fixed
511 			 * up at runtime.
512 			 */
513 
514 			long long offset;
515 			int overflow;
516 
517 			if (!absolute_percpu) {
518 				offset = table[i]->addr - relative_base;
519 				overflow = (offset < 0 || offset > UINT_MAX);
520 			} else if (symbol_absolute(table[i])) {
521 				offset = table[i]->addr;
522 				overflow = (offset < 0 || offset > INT_MAX);
523 			} else {
524 				offset = relative_base - table[i]->addr - 1;
525 				overflow = (offset < INT_MIN || offset >= 0);
526 			}
527 			if (overflow) {
528 				fprintf(stderr, "kallsyms failure: "
529 					"%s symbol value %#llx out of range in relative mode\n",
530 					symbol_absolute(table[i]) ? "absolute" : "relative",
531 					table[i]->addr);
532 				exit(EXIT_FAILURE);
533 			}
534 			printf("\t.long\t%#x	/* %s */\n", (int)offset, table[i]->sym);
535 		} else if (!symbol_absolute(table[i])) {
536 			output_address(table[i]->addr);
537 		} else {
538 			printf("\tPTR\t%#llx\n", table[i]->addr);
539 		}
540 	}
541 	printf("\n");
542 
543 	if (base_relative) {
544 		output_label("kallsyms_relative_base");
545 		output_address(relative_base);
546 		printf("\n");
547 	}
548 
549 	if (lto_clang)
550 		for (i = 0; i < table_cnt; i++)
551 			cleanup_symbol_name((char *)table[i]->sym);
552 
553 	sort_symbols_by_name();
554 	output_label("kallsyms_seqs_of_names");
555 	for (i = 0; i < table_cnt; i++)
556 		printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
557 			(unsigned char)(table[i]->seq >> 16),
558 			(unsigned char)(table[i]->seq >> 8),
559 			(unsigned char)(table[i]->seq >> 0));
560 	printf("\n");
561 }
562 
563 
564 /* table lookup compression functions */
565 
566 /* count all the possible tokens in a symbol */
567 static void learn_symbol(const unsigned char *symbol, int len)
568 {
569 	int i;
570 
571 	for (i = 0; i < len - 1; i++)
572 		token_profit[ symbol[i] + (symbol[i + 1] << 8) ]++;
573 }
574 
575 /* decrease the count for all the possible tokens in a symbol */
576 static void forget_symbol(const unsigned char *symbol, int len)
577 {
578 	int i;
579 
580 	for (i = 0; i < len - 1; i++)
581 		token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--;
582 }
583 
584 /* do the initial token count */
585 static void build_initial_token_table(void)
586 {
587 	unsigned int i;
588 
589 	for (i = 0; i < table_cnt; i++)
590 		learn_symbol(table[i]->sym, table[i]->len);
591 }
592 
593 static unsigned char *find_token(unsigned char *str, int len,
594 				 const unsigned char *token)
595 {
596 	int i;
597 
598 	for (i = 0; i < len - 1; i++) {
599 		if (str[i] == token[0] && str[i+1] == token[1])
600 			return &str[i];
601 	}
602 	return NULL;
603 }
604 
605 /* replace a given token in all the valid symbols. Use the sampled symbols
606  * to update the counts */
607 static void compress_symbols(const unsigned char *str, int idx)
608 {
609 	unsigned int i, len, size;
610 	unsigned char *p1, *p2;
611 
612 	for (i = 0; i < table_cnt; i++) {
613 
614 		len = table[i]->len;
615 		p1 = table[i]->sym;
616 
617 		/* find the token on the symbol */
618 		p2 = find_token(p1, len, str);
619 		if (!p2) continue;
620 
621 		/* decrease the counts for this symbol's tokens */
622 		forget_symbol(table[i]->sym, len);
623 
624 		size = len;
625 
626 		do {
627 			*p2 = idx;
628 			p2++;
629 			size -= (p2 - p1);
630 			memmove(p2, p2 + 1, size);
631 			p1 = p2;
632 			len--;
633 
634 			if (size < 2) break;
635 
636 			/* find the token on the symbol */
637 			p2 = find_token(p1, size, str);
638 
639 		} while (p2);
640 
641 		table[i]->len = len;
642 
643 		/* increase the counts for this symbol's new tokens */
644 		learn_symbol(table[i]->sym, len);
645 	}
646 }
647 
648 /* search the token with the maximum profit */
649 static int find_best_token(void)
650 {
651 	int i, best, bestprofit;
652 
653 	bestprofit=-10000;
654 	best = 0;
655 
656 	for (i = 0; i < 0x10000; i++) {
657 		if (token_profit[i] > bestprofit) {
658 			best = i;
659 			bestprofit = token_profit[i];
660 		}
661 	}
662 	return best;
663 }
664 
665 /* this is the core of the algorithm: calculate the "best" table */
666 static void optimize_result(void)
667 {
668 	int i, best;
669 
670 	/* using the '\0' symbol last allows compress_symbols to use standard
671 	 * fast string functions */
672 	for (i = 255; i >= 0; i--) {
673 
674 		/* if this table slot is empty (it is not used by an actual
675 		 * original char code */
676 		if (!best_table_len[i]) {
677 
678 			/* find the token with the best profit value */
679 			best = find_best_token();
680 			if (token_profit[best] == 0)
681 				break;
682 
683 			/* place it in the "best" table */
684 			best_table_len[i] = 2;
685 			best_table[i][0] = best & 0xFF;
686 			best_table[i][1] = (best >> 8) & 0xFF;
687 
688 			/* replace this token in all the valid symbols */
689 			compress_symbols(best_table[i], i);
690 		}
691 	}
692 }
693 
694 /* start by placing the symbols that are actually used on the table */
695 static void insert_real_symbols_in_table(void)
696 {
697 	unsigned int i, j, c;
698 
699 	for (i = 0; i < table_cnt; i++) {
700 		for (j = 0; j < table[i]->len; j++) {
701 			c = table[i]->sym[j];
702 			best_table[c][0]=c;
703 			best_table_len[c]=1;
704 		}
705 	}
706 }
707 
708 static void optimize_token_table(void)
709 {
710 	build_initial_token_table();
711 
712 	insert_real_symbols_in_table();
713 
714 	optimize_result();
715 }
716 
717 /* guess for "linker script provide" symbol */
718 static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
719 {
720 	const char *symbol = sym_name(se);
721 	int len = se->len - 1;
722 
723 	if (len < 8)
724 		return 0;
725 
726 	if (symbol[0] != '_' || symbol[1] != '_')
727 		return 0;
728 
729 	/* __start_XXXXX */
730 	if (!memcmp(symbol + 2, "start_", 6))
731 		return 1;
732 
733 	/* __stop_XXXXX */
734 	if (!memcmp(symbol + 2, "stop_", 5))
735 		return 1;
736 
737 	/* __end_XXXXX */
738 	if (!memcmp(symbol + 2, "end_", 4))
739 		return 1;
740 
741 	/* __XXXXX_start */
742 	if (!memcmp(symbol + len - 6, "_start", 6))
743 		return 1;
744 
745 	/* __XXXXX_end */
746 	if (!memcmp(symbol + len - 4, "_end", 4))
747 		return 1;
748 
749 	return 0;
750 }
751 
752 static int compare_symbols(const void *a, const void *b)
753 {
754 	const struct sym_entry *sa = *(const struct sym_entry **)a;
755 	const struct sym_entry *sb = *(const struct sym_entry **)b;
756 	int wa, wb;
757 
758 	/* sort by address first */
759 	if (sa->addr > sb->addr)
760 		return 1;
761 	if (sa->addr < sb->addr)
762 		return -1;
763 
764 	/* sort by "weakness" type */
765 	wa = (sa->sym[0] == 'w') || (sa->sym[0] == 'W');
766 	wb = (sb->sym[0] == 'w') || (sb->sym[0] == 'W');
767 	if (wa != wb)
768 		return wa - wb;
769 
770 	/* sort by "linker script provide" type */
771 	wa = may_be_linker_script_provide_symbol(sa);
772 	wb = may_be_linker_script_provide_symbol(sb);
773 	if (wa != wb)
774 		return wa - wb;
775 
776 	/* sort by the number of prefix underscores */
777 	wa = strspn(sym_name(sa), "_");
778 	wb = strspn(sym_name(sb), "_");
779 	if (wa != wb)
780 		return wa - wb;
781 
782 	/* sort by initial order, so that other symbols are left undisturbed */
783 	return sa->start_pos - sb->start_pos;
784 }
785 
786 static void sort_symbols(void)
787 {
788 	qsort(table, table_cnt, sizeof(table[0]), compare_symbols);
789 }
790 
791 static void make_percpus_absolute(void)
792 {
793 	unsigned int i;
794 
795 	for (i = 0; i < table_cnt; i++)
796 		if (symbol_in_range(table[i], &percpu_range, 1)) {
797 			/*
798 			 * Keep the 'A' override for percpu symbols to
799 			 * ensure consistent behavior compared to older
800 			 * versions of this tool.
801 			 */
802 			table[i]->sym[0] = 'A';
803 			table[i]->percpu_absolute = 1;
804 		}
805 }
806 
807 /* find the minimum non-absolute symbol address */
808 static void record_relative_base(void)
809 {
810 	unsigned int i;
811 
812 	for (i = 0; i < table_cnt; i++)
813 		if (!symbol_absolute(table[i])) {
814 			/*
815 			 * The table is sorted by address.
816 			 * Take the first non-absolute symbol value.
817 			 */
818 			relative_base = table[i]->addr;
819 			return;
820 		}
821 }
822 
823 int main(int argc, char **argv)
824 {
825 	while (1) {
826 		static const struct option long_options[] = {
827 			{"all-symbols",     no_argument, &all_symbols,     1},
828 			{"absolute-percpu", no_argument, &absolute_percpu, 1},
829 			{"base-relative",   no_argument, &base_relative,   1},
830 			{"lto-clang",       no_argument, &lto_clang,       1},
831 			{},
832 		};
833 
834 		int c = getopt_long(argc, argv, "", long_options, NULL);
835 
836 		if (c == -1)
837 			break;
838 		if (c != 0)
839 			usage();
840 	}
841 
842 	if (optind >= argc)
843 		usage();
844 
845 	read_map(argv[optind]);
846 	shrink_table();
847 	if (absolute_percpu)
848 		make_percpus_absolute();
849 	sort_symbols();
850 	if (base_relative)
851 		record_relative_base();
852 	optimize_token_table();
853 	write_src();
854 
855 	return 0;
856 }
857