Commit 17b1f0de79dbdf5cfb2686b63a7fb9ecc440da7c
Committed by
Sam Ravnborg
1 parent
028f042613
Exists in
master
and in
39 other branches
kallsyms: generalize text region handling
Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Showing 1 changed file with 61 additions and 26 deletions Side-by-side Diff
scripts/kallsyms.c
... | ... | @@ -23,6 +23,10 @@ |
23 | 23 | #include <string.h> |
24 | 24 | #include <ctype.h> |
25 | 25 | |
26 | +#ifndef ARRAY_SIZE | |
27 | +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) | |
28 | +#endif | |
29 | + | |
26 | 30 | #define KSYM_NAME_LEN 128 |
27 | 31 | |
28 | 32 | struct sym_entry { |
29 | 33 | |
... | ... | @@ -32,10 +36,23 @@ |
32 | 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 | 54 | static struct sym_entry *table; |
36 | 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 | 56 | static int all_symbols = 0; |
40 | 57 | static char symbol_prefix_char = '\0'; |
41 | 58 | |
... | ... | @@ -62,6 +79,26 @@ |
62 | 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 | 102 | static int read_symbol(FILE *in, struct sym_entry *s) |
66 | 103 | { |
67 | 104 | char str[500]; |
... | ... | @@ -85,22 +122,8 @@ |
85 | 122 | /* Ignore most absolute/undefined (?) symbols. */ |
86 | 123 | if (strcmp(sym, "_text") == 0) |
87 | 124 | _text = s->addr; |
88 | - else if (strcmp(sym, "_stext") == 0) | |
89 | - _stext = s->addr; | |
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; | |
125 | + else if (read_symbol_tr(sym, s->addr) == 0) | |
126 | + /* nothing to do */; | |
104 | 127 | else if (toupper(stype) == 'A') |
105 | 128 | { |
106 | 129 | /* Keep these useful absolute symbols */ |
... | ... | @@ -136,6 +159,21 @@ |
136 | 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 | 177 | static int symbol_valid(struct sym_entry *s) |
140 | 178 | { |
141 | 179 | /* Symbols which vary between passes. Passes 1 and 2 must have |
... | ... | @@ -165,10 +203,7 @@ |
165 | 203 | /* if --all-symbols is not specified, then symbols outside the text |
166 | 204 | * and inittext sections are discarded */ |
167 | 205 | if (!all_symbols) { |
168 | - if ((s->addr < _stext || s->addr > _etext) | |
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)) | |
206 | + if (symbol_valid_tr(s) == 0) | |
172 | 207 | return 0; |
173 | 208 | /* Corner case. Discard any symbols with the same value as |
174 | 209 | * _etext _einittext; they can move between pass 1 and 2 when |
... | ... | @@ -176,10 +211,10 @@ |
176 | 211 | * they may get dropped in pass 2, which breaks the kallsyms |
177 | 212 | * rules. |
178 | 213 | */ |
179 | - if ((s->addr == _etext && | |
180 | - strcmp((char *)s->sym + offset, "_etext")) || | |
181 | - (s->addr == _einittext && | |
182 | - strcmp((char *)s->sym + offset, "_einittext"))) | |
214 | + if ((s->addr == text_range_text->end && | |
215 | + strcmp((char *)s->sym + offset, text_range_text->etext)) || | |
216 | + (s->addr == text_range_inittext->end && | |
217 | + strcmp((char *)s->sym + offset, text_range_inittext->etext))) | |
183 | 218 | return 0; |
184 | 219 | } |
185 | 220 |