diff options
| author | Mike Frysinger <vapier@gentoo.org> | 2009-06-08 19:12:13 -0400 |
|---|---|---|
| committer | Sam Ravnborg <sam@ravnborg.org> | 2009-06-14 16:43:46 -0400 |
| commit | 17b1f0de79dbdf5cfb2686b63a7fb9ecc440da7c (patch) | |
| tree | 0bf1a077eb42e61b353463c4c7193af09971e379 /scripts | |
| parent | 028f042613c3c99db20dd7f4e4069fbbcea92dd7 (diff) | |
kallsyms: generalize text region handling
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/kallsyms.c | 87 |
1 files changed, 61 insertions, 26 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index fb82a5b49809..3cb57895c9ea 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
| @@ -23,6 +23,10 @@ | |||
| 23 | #include <string.h> | 23 | #include <string.h> |
| 24 | #include <ctype.h> | 24 | #include <ctype.h> |
| 25 | 25 | ||
| 26 | #ifndef ARRAY_SIZE | ||
| 27 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | ||
| 28 | #endif | ||
| 29 | |||
| 26 | #define KSYM_NAME_LEN 128 | 30 | #define KSYM_NAME_LEN 128 |
| 27 | 31 | ||
| 28 | struct sym_entry { | 32 | struct sym_entry { |
| @@ -32,10 +36,23 @@ struct sym_entry { | |||
| 32 | unsigned char *sym; | 36 | unsigned char *sym; |
| 33 | }; | 37 | }; |
| 34 | 38 | ||
| 39 | struct text_range { | ||
| 40 | const char *stext, *etext; | ||
| 41 | unsigned long long start, end; | ||
| 42 | }; | ||
| 43 | |||
| 44 | static unsigned long long _text; | ||
| 45 | static struct text_range text_ranges[] = { | ||
| 46 | { "_stext", "_etext" }, | ||
| 47 | { "_sinittext", "_einittext" }, | ||
| 48 | { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */ | ||
| 49 | { "_stext_l2", "_etext_l2" }, /* Blackfin on-chip L2 SRAM */ | ||
| 50 | }; | ||
| 51 | #define text_range_text (&text_ranges[0]) | ||
| 52 | #define text_range_inittext (&text_ranges[1]) | ||
| 53 | |||
| 35 | static struct sym_entry *table; | 54 | static struct sym_entry *table; |
| 36 | static unsigned int table_size, table_cnt; | 55 | static unsigned int table_size, table_cnt; |
| 37 | static unsigned long long _text, _stext, _etext, _sinittext, _einittext; | ||
| 38 | static unsigned long long _stext_l1, _etext_l1, _stext_l2, _etext_l2; | ||
| 39 | static int all_symbols = 0; | 56 | static int all_symbols = 0; |
| 40 | static char symbol_prefix_char = '\0'; | 57 | static char symbol_prefix_char = '\0'; |
| 41 | 58 | ||
| @@ -62,6 +79,26 @@ static inline int is_arm_mapping_symbol(const char *str) | |||
| 62 | && (str[2] == '\0' || str[2] == '.'); | 79 | && (str[2] == '\0' || str[2] == '.'); |
| 63 | } | 80 | } |
| 64 | 81 | ||
| 82 | static int read_symbol_tr(const char *sym, unsigned long long addr) | ||
| 83 | { | ||
| 84 | size_t i; | ||
| 85 | struct text_range *tr; | ||
| 86 | |||
| 87 | for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { | ||
| 88 | tr = &text_ranges[i]; | ||
| 89 | |||
| 90 | if (strcmp(sym, tr->stext) == 0) { | ||
| 91 | tr->start = addr; | ||
| 92 | return 0; | ||
| 93 | } else if (strcmp(sym, tr->etext) == 0) { | ||
| 94 | tr->end = addr; | ||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | return 1; | ||
| 100 | } | ||
| 101 | |||
| 65 | static int read_symbol(FILE *in, struct sym_entry *s) | 102 | static int read_symbol(FILE *in, struct sym_entry *s) |
| 66 | { | 103 | { |
| 67 | char str[500]; | 104 | char str[500]; |
| @@ -85,22 +122,8 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
| 85 | /* Ignore most absolute/undefined (?) symbols. */ | 122 | /* Ignore most absolute/undefined (?) symbols. */ |
| 86 | if (strcmp(sym, "_text") == 0) | 123 | if (strcmp(sym, "_text") == 0) |
| 87 | _text = s->addr; | 124 | _text = s->addr; |
| 88 | else if (strcmp(sym, "_stext") == 0) | 125 | else if (read_symbol_tr(sym, s->addr) == 0) |
| 89 | _stext = s->addr; | 126 | /* nothing to do */; |
| 90 | else if (strcmp(sym, "_etext") == 0) | ||
| 91 | _etext = s->addr; | ||
| 92 | else if (strcmp(sym, "_sinittext") == 0) | ||
| 93 | _sinittext = s->addr; | ||
| 94 | else if (strcmp(sym, "_einittext") == 0) | ||
| 95 | _einittext = s->addr; | ||
| 96 | else if (strcmp(sym, "_stext_l1") == 0) | ||
| 97 | _stext_l1 = s->addr; | ||
| 98 | else if (strcmp(sym, "_etext_l1") == 0) | ||
| 99 | _etext_l1 = s->addr; | ||
| 100 | else if (strcmp(sym, "_stext_l2") == 0) | ||
| 101 | _stext_l2 = s->addr; | ||
| 102 | else if (strcmp(sym, "_etext_l2") == 0) | ||
| 103 | _etext_l2 = s->addr; | ||
| 104 | else if (toupper(stype) == 'A') | 127 | else if (toupper(stype) == 'A') |
| 105 | { | 128 | { |
| 106 | /* Keep these useful absolute symbols */ | 129 | /* Keep these useful absolute symbols */ |
| @@ -136,6 +159,21 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
| 136 | return 0; | 159 | return 0; |
| 137 | } | 160 | } |
| 138 | 161 | ||
| 162 | static int symbol_valid_tr(struct sym_entry *s) | ||
| 163 | { | ||
| 164 | size_t i; | ||
| 165 | struct text_range *tr; | ||
| 166 | |||
| 167 | for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { | ||
| 168 | tr = &text_ranges[i]; | ||
| 169 | |||
| 170 | if (s->addr >= tr->start && s->addr < tr->end) | ||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | return 1; | ||
| 175 | } | ||
| 176 | |||
| 139 | static int symbol_valid(struct sym_entry *s) | 177 | static int symbol_valid(struct sym_entry *s) |
| 140 | { | 178 | { |
| 141 | /* Symbols which vary between passes. Passes 1 and 2 must have | 179 | /* Symbols which vary between passes. Passes 1 and 2 must have |
| @@ -165,10 +203,7 @@ static int symbol_valid(struct sym_entry *s) | |||
| 165 | /* if --all-symbols is not specified, then symbols outside the text | 203 | /* if --all-symbols is not specified, then symbols outside the text |
| 166 | * and inittext sections are discarded */ | 204 | * and inittext sections are discarded */ |
| 167 | if (!all_symbols) { | 205 | if (!all_symbols) { |
| 168 | if ((s->addr < _stext || s->addr > _etext) | 206 | if (symbol_valid_tr(s) == 0) |
| 169 | && (s->addr < _sinittext || s->addr > _einittext) | ||
| 170 | && (s->addr < _stext_l1 || s->addr > _etext_l1) | ||
| 171 | && (s->addr < _stext_l2 || s->addr > _etext_l2)) | ||
| 172 | return 0; | 207 | return 0; |
| 173 | /* Corner case. Discard any symbols with the same value as | 208 | /* Corner case. Discard any symbols with the same value as |
| 174 | * _etext _einittext; they can move between pass 1 and 2 when | 209 | * _etext _einittext; they can move between pass 1 and 2 when |
| @@ -176,10 +211,10 @@ static int symbol_valid(struct sym_entry *s) | |||
| 176 | * they may get dropped in pass 2, which breaks the kallsyms | 211 | * they may get dropped in pass 2, which breaks the kallsyms |
| 177 | * rules. | 212 | * rules. |
| 178 | */ | 213 | */ |
| 179 | if ((s->addr == _etext && | 214 | if ((s->addr == text_range_text->end && |
| 180 | strcmp((char *)s->sym + offset, "_etext")) || | 215 | strcmp((char *)s->sym + offset, text_range_text->etext)) || |
| 181 | (s->addr == _einittext && | 216 | (s->addr == text_range_inittext->end && |
| 182 | strcmp((char *)s->sym + offset, "_einittext"))) | 217 | strcmp((char *)s->sym + offset, text_range_inittext->etext))) |
| 183 | return 0; | 218 | return 0; |
| 184 | } | 219 | } |
| 185 | 220 | ||
