--- ./scripts/kallsyms.c.orig 2007-10-30 18:51:28.000000000 +0000 +++ ./scripts/kallsyms.c 2007-10-30 19:07:58.000000000 +0000 @@ -34,7 +34,7 @@ struct sym_entry { unsigned long long addr; - unsigned int len; + unsigned int len, start_pos; unsigned char *sym; }; @@ -202,8 +202,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++; + } } } @@ -507,6 +509,35 @@ static void optimize_token_table(void) } +static int compare_symbols(const void *a, const void *b) +{ + struct sym_entry *sa, *sb; + int wa, wb; + + sa = (struct sym_entry *) a; + sb = (struct sym_entry *) 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 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) { if (argc >= 2) { @@ -527,6 +558,7 @@ int main(int argc, char **argv) usage(); read_map(stdin); + sort_symbols(); optimize_token_table(); write_src();