123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define symbol_to_write(vaddr, tv, etv) \
- ((vaddr < tv || vaddr > etv) ? 0 : 1)
- struct kernel_symbol_entry_t
- {
- uint64_t vaddr;
- char type;
- char *symbol;
- int symbol_length;
- };
- struct kernel_symbol_entry_t *symbol_table;
- uint64_t table_size = 0;
- uint64_t entry_count = 0;
- uint64_t text_vaddr, etext_vaddr;
- int read_symbol(FILE *filp, struct kernel_symbol_entry_t *entry)
- {
-
- char str[512] = {0};
- int retval = fscanf(filp, "%llx %c %510s\n", &entry->vaddr, &entry->type, str);
-
- if (retval != 3)
- {
- if (retval != EOF)
- {
-
- fgets(str, 512, filp);
- }
- return -1;
- }
-
- entry->symbol = strdup(str);
- entry->symbol_length = strlen(str) + 1;
- return 0;
- }
- void read_map(FILE *filp)
- {
-
- while (!feof(filp))
- {
-
- if (entry_count >= table_size)
- {
- table_size += 100;
-
- symbol_table = (struct kernel_symbol_entry_t *)realloc(symbol_table, sizeof(struct kernel_symbol_entry_t) * table_size);
- }
-
- if (read_symbol(filp, &symbol_table[entry_count]) == 0)
- ++entry_count;
- }
-
- for (uint64_t i = 0; i < entry_count; ++i)
- {
- if (strcmp(symbol_table[i].symbol, "_text")==0)
- text_vaddr = symbol_table[i].vaddr;
- if (strcmp(symbol_table[i].symbol, "_etext")==0)
- etext_vaddr = symbol_table[i].vaddr;
- }
- }
- void generate_result()
- {
- printf(".section .rodata\n\n");
- printf(".global kallsyms_address\n");
- printf(".align 8\n\n");
- printf("kallsyms_address:\n");
- uint64_t last_vaddr = 0;
- uint64_t total_syms_to_write = 0;
-
- for (uint64_t i = 0; i < entry_count; ++i)
- {
-
- if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
- continue;
- if (symbol_table[i].vaddr == last_vaddr)
- continue;
-
- printf("\t.quad\t%#llx\n", symbol_table[i].vaddr);
- ++total_syms_to_write;
- last_vaddr = symbol_table[i].vaddr;
- }
- putchar('\n');
-
- printf(".global kallsyms_num\n");
- printf(".align 8\n");
- printf("kallsyms_num:\n");
- printf("\t.quad\t%lld\n", total_syms_to_write);
- putchar('\n');
-
- printf(".global kallsyms_names_index\n");
- printf(".align 8\n");
- printf("kallsyms_names_index:\n");
- uint64_t position = 0;
- last_vaddr = 0;
- for (uint64_t i = 0; i < entry_count; ++i)
- {
-
- if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
- continue;
- if (symbol_table[i].vaddr == last_vaddr)
- continue;
-
- printf("\t.quad\t%lld\n", position);
- position += symbol_table[i].symbol_length;
- last_vaddr = symbol_table[i].vaddr;
- }
- putchar('\n');
-
- printf(".global kallsyms_names\n");
- printf(".align 8\n");
- printf("kallsyms_names:\n");
- last_vaddr = 0;
- for (uint64_t i = 0; i < entry_count; ++i)
- {
-
- if (!symbol_to_write(symbol_table[i].vaddr, text_vaddr, etext_vaddr))
- continue;
- if (symbol_table[i].vaddr == last_vaddr)
- continue;
-
- printf("\t.asciz\t\"%s\"\n", symbol_table[i].symbol);
-
- last_vaddr = symbol_table[i].vaddr;
- }
- putchar('\n');
-
- }
- int main(int argc, char **argv)
- {
- read_map(stdin);
- generate_result();
- }
|