The usual stuff ...
[linux-2.6/linux-mips.git] / scripts / kallsyms.c
blob43c110fe782914cd6613a915d7a72c3f31aa620b
1 /* Generate assembler source containing symbol information
3 * Copyright 2002 by Kai Germaschewski
5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference.
8 * Usage: nm -n vmlinux | scripts/kallsyms > symbols.S
9 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
15 struct sym_entry {
16 unsigned long long addr;
17 char type;
18 char *sym;
22 static struct sym_entry *table;
23 static int size, cnt;
24 static unsigned long long _stext, _etext, _sinittext, _einittext;
26 static void
27 usage(void)
29 fprintf(stderr, "Usage: kallsyms < in.map > out.S\n");
30 exit(1);
33 static int
34 read_symbol(FILE *in, struct sym_entry *s)
36 char str[500];
37 int rc;
39 rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
40 if (rc != 3) {
41 if (rc != EOF) {
42 /* skip line */
43 fgets(str, 500, in);
45 return -1;
47 s->sym = strdup(str);
48 return 0;
51 static int
52 symbol_valid(struct sym_entry *s)
54 if ((s->addr < _stext || s->addr > _etext)
55 && (s->addr < _sinittext || s->addr > _einittext))
56 return 0;
58 if (strstr(s->sym, "_compiled."))
59 return 0;
61 return 1;
64 static void
65 read_map(FILE *in)
67 int i;
69 while (!feof(in)) {
70 if (cnt >= size) {
71 size += 10000;
72 table = realloc(table, sizeof(*table) * size);
73 if (!table) {
74 fprintf(stderr, "out of memory\n");
75 exit (1);
78 if (read_symbol(in, &table[cnt]) == 0)
79 cnt++;
81 for (i = 0; i < cnt; i++) {
82 if (strcmp(table[i].sym, "_stext") == 0)
83 _stext = table[i].addr;
84 if (strcmp(table[i].sym, "_etext") == 0)
85 _etext = table[i].addr;
86 if (strcmp(table[i].sym, "_sinittext") == 0)
87 _sinittext = table[i].addr;
88 if (strcmp(table[i].sym, "_einittext") == 0)
89 _einittext = table[i].addr;
93 static void
94 write_src(void)
96 unsigned long long last_addr;
97 int i, valid = 0;
98 char *prev;
100 printf("#include <asm/types.h>\n");
101 printf("#if BITS_PER_LONG == 64\n");
102 printf("#define PTR .quad\n");
103 printf("#define ALGN .align 8\n");
104 printf("#else\n");
105 printf("#define PTR .long\n");
106 printf("#define ALGN .align 4\n");
107 printf("#endif\n");
109 printf(".data\n");
111 printf(".globl kallsyms_addresses\n");
112 printf("\tALGN\n");
113 printf("kallsyms_addresses:\n");
114 for (i = 0, last_addr = 0; i < cnt; i++) {
115 if (!symbol_valid(&table[i]))
116 continue;
118 if (table[i].addr == last_addr)
119 continue;
121 printf("\tPTR\t%#llx\n", table[i].addr);
122 valid++;
123 last_addr = table[i].addr;
125 printf("\n");
127 printf(".globl kallsyms_num_syms\n");
128 printf("\tALGN\n");
129 printf("kallsyms_num_syms:\n");
130 printf("\tPTR\t%d\n", valid);
131 printf("\n");
133 printf(".globl kallsyms_names\n");
134 printf("\tALGN\n");
135 printf("kallsyms_names:\n");
136 prev = "";
137 for (i = 0, last_addr = 0; i < cnt; i++) {
138 int k;
140 if (!symbol_valid(&table[i]))
141 continue;
143 if (table[i].addr == last_addr)
144 continue;
146 for (k = 0; table[i].sym[k] && table[i].sym[k] == prev[k]; ++k)
149 printf("\t.byte 0x%02x\n\t.asciz\t\"%s\"\n", k, table[i].sym + k);
150 last_addr = table[i].addr;
151 prev = table[i].sym;
153 printf("\n");
157 main(int argc, char **argv)
159 if (argc != 1)
160 usage();
162 read_map(stdin);
163 write_src();
165 return 0;