diff options
Diffstat (limited to 'scripts/kallsyms.c')
| -rw-r--r-- | scripts/kallsyms.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 1f11d848532a..c912137f80e2 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
| @@ -31,17 +31,16 @@ | |||
| 31 | 31 | ||
| 32 | #define KSYM_NAME_LEN 128 | 32 | #define KSYM_NAME_LEN 128 |
| 33 | 33 | ||
| 34 | |||
| 35 | struct sym_entry { | 34 | struct sym_entry { |
| 36 | unsigned long long addr; | 35 | unsigned long long addr; |
| 37 | unsigned int len; | 36 | unsigned int len; |
| 37 | unsigned int start_pos; | ||
| 38 | unsigned char *sym; | 38 | unsigned char *sym; |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | |||
| 42 | static struct sym_entry *table; | 41 | static struct sym_entry *table; |
| 43 | static unsigned int table_size, table_cnt; | 42 | static unsigned int table_size, table_cnt; |
| 44 | static unsigned long long _text, _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; | 43 | static unsigned long long _text, _stext, _etext, _sinittext, _einittext; |
| 45 | static int all_symbols = 0; | 44 | static int all_symbols = 0; |
| 46 | static char symbol_prefix_char = '\0'; | 45 | static char symbol_prefix_char = '\0'; |
| 47 | 46 | ||
| @@ -99,10 +98,6 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
| 99 | _sinittext = s->addr; | 98 | _sinittext = s->addr; |
| 100 | else if (strcmp(sym, "_einittext") == 0) | 99 | else if (strcmp(sym, "_einittext") == 0) |
| 101 | _einittext = s->addr; | 100 | _einittext = s->addr; |
| 102 | else if (strcmp(sym, "_sextratext") == 0) | ||
| 103 | _sextratext = s->addr; | ||
| 104 | else if (strcmp(sym, "_eextratext") == 0) | ||
| 105 | _eextratext = s->addr; | ||
| 106 | else if (toupper(stype) == 'A') | 101 | else if (toupper(stype) == 'A') |
| 107 | { | 102 | { |
| 108 | /* Keep these useful absolute symbols */ | 103 | /* Keep these useful absolute symbols */ |
| @@ -165,18 +160,18 @@ static int symbol_valid(struct sym_entry *s) | |||
| 165 | * and inittext sections are discarded */ | 160 | * and inittext sections are discarded */ |
| 166 | if (!all_symbols) { | 161 | if (!all_symbols) { |
| 167 | if ((s->addr < _stext || s->addr > _etext) | 162 | if ((s->addr < _stext || s->addr > _etext) |
| 168 | && (s->addr < _sinittext || s->addr > _einittext) | 163 | && (s->addr < _sinittext || s->addr > _einittext)) |
| 169 | && (s->addr < _sextratext || s->addr > _eextratext)) | ||
| 170 | return 0; | 164 | return 0; |
| 171 | /* Corner case. Discard any symbols with the same value as | 165 | /* Corner case. Discard any symbols with the same value as |
| 172 | * _etext _einittext or _eextratext; they can move between pass | 166 | * _etext _einittext; they can move between pass 1 and 2 when |
| 173 | * 1 and 2 when the kallsyms data are added. If these symbols | 167 | * the kallsyms data are added. If these symbols move then |
| 174 | * move then they may get dropped in pass 2, which breaks the | 168 | * they may get dropped in pass 2, which breaks the kallsyms |
| 175 | * kallsyms rules. | 169 | * rules. |
| 176 | */ | 170 | */ |
| 177 | if ((s->addr == _etext && strcmp((char*)s->sym + offset, "_etext")) || | 171 | if ((s->addr == _etext && |
| 178 | (s->addr == _einittext && strcmp((char*)s->sym + offset, "_einittext")) || | 172 | strcmp((char *)s->sym + offset, "_etext")) || |
| 179 | (s->addr == _eextratext && strcmp((char*)s->sym + offset, "_eextratext"))) | 173 | (s->addr == _einittext && |
| 174 | strcmp((char *)s->sym + offset, "_einittext"))) | ||
| 180 | return 0; | 175 | return 0; |
| 181 | } | 176 | } |
| 182 | 177 | ||
| @@ -202,8 +197,10 @@ static void read_map(FILE *in) | |||
| 202 | exit (1); | 197 | exit (1); |
| 203 | } | 198 | } |
| 204 | } | 199 | } |
| 205 | if (read_symbol(in, &table[table_cnt]) == 0) | 200 | if (read_symbol(in, &table[table_cnt]) == 0) { |
| 201 | table[table_cnt].start_pos = table_cnt; | ||
| 206 | table_cnt++; | 202 | table_cnt++; |
| 203 | } | ||
| 207 | } | 204 | } |
| 208 | } | 205 | } |
| 209 | 206 | ||
| @@ -506,6 +503,35 @@ static void optimize_token_table(void) | |||
| 506 | optimize_result(); | 503 | optimize_result(); |
| 507 | } | 504 | } |
| 508 | 505 | ||
| 506 | static int compare_symbols(const void *a, const void *b) | ||
| 507 | { | ||
| 508 | const struct sym_entry *sa; | ||
| 509 | const struct sym_entry *sb; | ||
| 510 | int wa, wb; | ||
| 511 | |||
| 512 | sa = a; | ||
| 513 | sb = b; | ||
| 514 | |||
| 515 | /* sort by address first */ | ||
| 516 | if (sa->addr > sb->addr) | ||
| 517 | return 1; | ||
| 518 | if (sa->addr < sb->addr) | ||
| 519 | return -1; | ||
| 520 | |||
| 521 | /* sort by "weakness" type */ | ||
| 522 | wa = (sa->sym[0] == 'w') || (sa->sym[0] == 'W'); | ||
| 523 | wb = (sb->sym[0] == 'w') || (sb->sym[0] == 'W'); | ||
| 524 | if (wa != wb) | ||
| 525 | return wa - wb; | ||
| 526 | |||
| 527 | /* sort by initial order, so that other symbols are left undisturbed */ | ||
| 528 | return sa->start_pos - sb->start_pos; | ||
| 529 | } | ||
| 530 | |||
| 531 | static void sort_symbols(void) | ||
| 532 | { | ||
| 533 | qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols); | ||
| 534 | } | ||
| 509 | 535 | ||
| 510 | int main(int argc, char **argv) | 536 | int main(int argc, char **argv) |
| 511 | { | 537 | { |
| @@ -527,6 +553,7 @@ int main(int argc, char **argv) | |||
| 527 | usage(); | 553 | usage(); |
| 528 | 554 | ||
| 529 | read_map(stdin); | 555 | read_map(stdin); |
| 556 | sort_symbols(); | ||
| 530 | optimize_token_table(); | 557 | optimize_token_table(); |
| 531 | write_src(); | 558 | write_src(); |
| 532 | 559 | ||
