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
16 unsigned long long addr
;
22 static struct sym_entry
*table
;
24 static unsigned long long _stext
, _etext
, _sinittext
, _einittext
;
29 fprintf(stderr
, "Usage: kallsyms < in.map > out.S\n");
34 read_symbol(FILE *in
, struct sym_entry
*s
)
39 rc
= fscanf(in
, "%llx %c %499s\n", &s
->addr
, &s
->type
, str
);
52 symbol_valid(struct sym_entry
*s
)
54 if ((s
->addr
< _stext
|| s
->addr
> _etext
)
55 && (s
->addr
< _sinittext
|| s
->addr
> _einittext
))
58 if (strstr(s
->sym
, "_compiled."))
72 table
= realloc(table
, sizeof(*table
) * size
);
74 fprintf(stderr
, "out of memory\n");
78 if (read_symbol(in
, &table
[cnt
]) == 0)
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
;
96 unsigned long long last_addr
;
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");
105 printf("#define PTR .long\n");
106 printf("#define ALGN .align 4\n");
111 printf(".globl kallsyms_addresses\n");
113 printf("kallsyms_addresses:\n");
114 for (i
= 0, last_addr
= 0; i
< cnt
; i
++) {
115 if (!symbol_valid(&table
[i
]))
118 if (table
[i
].addr
== last_addr
)
121 printf("\tPTR\t%#llx\n", table
[i
].addr
);
123 last_addr
= table
[i
].addr
;
127 printf(".globl kallsyms_num_syms\n");
129 printf("kallsyms_num_syms:\n");
130 printf("\tPTR\t%d\n", valid
);
133 printf(".globl kallsyms_names\n");
135 printf("kallsyms_names:\n");
137 for (i
= 0, last_addr
= 0; i
< cnt
; i
++) {
140 if (!symbol_valid(&table
[i
]))
143 if (table
[i
].addr
== last_addr
)
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
;
157 main(int argc
, char **argv
)