X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=scripts%2Fkallsyms.c;h=6654cbed965b932c2cc515243680edac93b00c0b;hb=0e639bdeef26faf287db77a15530f3f295a4ae04;hp=8fb87003d5d3ecb3cf2f46e8a83fec218c7e3535;hpb=a3b81113fb6658629f4ebaabf8dd3067cd341020;p=safe%2Fjmp%2Flinux-2.6 diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 8fb8700..6654cbe 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -7,12 +7,6 @@ * * Usage: nm -n vmlinux | scripts/kallsyms [--all-symbols] > symbols.S * - * ChangeLog: - * - * (25/Aug/2004) Paulo Marques - * Changed the compression method from stem compression to "table lookup" - * compression - * * Table compression uses all the unused char codes on the symbols and * maps these to the most used substrings (tokens). For instance, it might * map char code 0xF7 to represent "write_" and then in every symbol where @@ -31,14 +25,13 @@ #define KSYM_NAME_LEN 128 - struct sym_entry { unsigned long long addr; unsigned int len; + unsigned int start_pos; unsigned char *sym; }; - static struct sym_entry *table; static unsigned int table_size, table_cnt; static unsigned long long _text, _stext, _etext, _sinittext, _einittext; @@ -115,6 +108,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */ else if (str[0] == '$') return -1; + /* exclude debugging symbols */ + else if (stype == 'N') + return -1; /* include the type field in the symbol name, so that it gets * compressed together */ @@ -198,8 +194,10 @@ static void read_map(FILE *in) exit (1); } } - if (read_symbol(in, &table[table_cnt]) == 0) + if (read_symbol(in, &table[table_cnt]) == 0) { + table[table_cnt].start_pos = table_cnt; table_cnt++; + } } } @@ -502,6 +500,92 @@ static void optimize_token_table(void) optimize_result(); } +/* guess for "linker script provide" symbol */ +static int may_be_linker_script_provide_symbol(const struct sym_entry *se) +{ + const char *symbol = (char *)se->sym + 1; + int len = se->len - 1; + + if (len < 8) + return 0; + + if (symbol[0] != '_' || symbol[1] != '_') + return 0; + + /* __start_XXXXX */ + if (!memcmp(symbol + 2, "start_", 6)) + return 1; + + /* __stop_XXXXX */ + if (!memcmp(symbol + 2, "stop_", 5)) + return 1; + + /* __end_XXXXX */ + if (!memcmp(symbol + 2, "end_", 4)) + return 1; + + /* __XXXXX_start */ + if (!memcmp(symbol + len - 6, "_start", 6)) + return 1; + + /* __XXXXX_end */ + if (!memcmp(symbol + len - 4, "_end", 4)) + return 1; + + return 0; +} + +static int prefix_underscores_count(const char *str) +{ + const char *tail = str; + + while (*tail != '_') + tail++; + + return tail - str; +} + +static int compare_symbols(const void *a, const void *b) +{ + const struct sym_entry *sa; + const struct sym_entry *sb; + int wa, wb; + + sa = a; + sb = b; + + /* sort by address first */ + if (sa->addr > sb->addr) + return 1; + if (sa->addr < sb->addr) + return -1; + + /* sort by "weakness" type */ + wa = (sa->sym[0] == 'w') || (sa->sym[0] == 'W'); + wb = (sb->sym[0] == 'w') || (sb->sym[0] == 'W'); + if (wa != wb) + return wa - wb; + + /* sort by "linker script provide" type */ + wa = may_be_linker_script_provide_symbol(sa); + wb = may_be_linker_script_provide_symbol(sb); + if (wa != wb) + return wa - wb; + + /* sort by the number of prefix underscores */ + wa = prefix_underscores_count((const char *)sa->sym + 1); + wb = prefix_underscores_count((const char *)sb->sym + 1); + if (wa != wb) + return wa - wb; + + /* sort by initial order, so that other symbols are left undisturbed */ + return sa->start_pos - sb->start_pos; +} + +static void sort_symbols(void) +{ + qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols); +} int main(int argc, char **argv) { @@ -523,6 +607,7 @@ int main(int argc, char **argv) usage(); read_map(stdin); + sort_symbols(); optimize_token_table(); write_src();