aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/kallsyms.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-03-16 22:48:27 -0400
committerRusty Russell <rusty@rustcorp.com.au>2014-03-17 00:24:50 -0400
commit78eb71594b3265f3cfe871480235be158feebd0f (patch)
tree41e5d7a99e28239d8e04856edc02e34e3d963c96 /scripts/kallsyms.c
parent0283f9a529c81e64bafea80d6d3e056d1c3f656d (diff)
kallsyms: generalize address range checking
This refactors the address range checks to be generalized instead of specific to text range checks, in preparation for other range checks. Also extracts logic for "is the symbol absolute" into a function. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'scripts/kallsyms.c')
-rw-r--r--scripts/kallsyms.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index 10085de886fe..3df15f5e7c55 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -36,13 +36,13 @@ struct sym_entry {
36 unsigned char *sym; 36 unsigned char *sym;
37}; 37};
38 38
39struct text_range { 39struct addr_range {
40 const char *stext, *etext; 40 const char *start_sym, *end_sym;
41 unsigned long long start, end; 41 unsigned long long start, end;
42}; 42};
43 43
44static unsigned long long _text; 44static unsigned long long _text;
45static struct text_range text_ranges[] = { 45static struct addr_range text_ranges[] = {
46 { "_stext", "_etext" }, 46 { "_stext", "_etext" },
47 { "_sinittext", "_einittext" }, 47 { "_sinittext", "_einittext" },
48 { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */ 48 { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */
@@ -83,19 +83,20 @@ static inline int is_arm_mapping_symbol(const char *str)
83 && (str[2] == '\0' || str[2] == '.'); 83 && (str[2] == '\0' || str[2] == '.');
84} 84}
85 85
86static int read_symbol_tr(const char *sym, unsigned long long addr) 86static int check_symbol_range(const char *sym, unsigned long long addr,
87 struct addr_range *ranges, int entries)
87{ 88{
88 size_t i; 89 size_t i;
89 struct text_range *tr; 90 struct addr_range *ar;
90 91
91 for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { 92 for (i = 0; i < entries; ++i) {
92 tr = &text_ranges[i]; 93 ar = &ranges[i];
93 94
94 if (strcmp(sym, tr->stext) == 0) { 95 if (strcmp(sym, ar->start_sym) == 0) {
95 tr->start = addr; 96 ar->start = addr;
96 return 0; 97 return 0;
97 } else if (strcmp(sym, tr->etext) == 0) { 98 } else if (strcmp(sym, ar->end_sym) == 0) {
98 tr->end = addr; 99 ar->end = addr;
99 return 0; 100 return 0;
100 } 101 }
101 } 102 }
@@ -130,7 +131,8 @@ static int read_symbol(FILE *in, struct sym_entry *s)
130 /* Ignore most absolute/undefined (?) symbols. */ 131 /* Ignore most absolute/undefined (?) symbols. */
131 if (strcmp(sym, "_text") == 0) 132 if (strcmp(sym, "_text") == 0)
132 _text = s->addr; 133 _text = s->addr;
133 else if (read_symbol_tr(sym, s->addr) == 0) 134 else if (check_symbol_range(sym, s->addr, text_ranges,
135 ARRAY_SIZE(text_ranges)) == 0)
134 /* nothing to do */; 136 /* nothing to do */;
135 else if (toupper(stype) == 'A') 137 else if (toupper(stype) == 'A')
136 { 138 {
@@ -167,15 +169,16 @@ static int read_symbol(FILE *in, struct sym_entry *s)
167 return 0; 169 return 0;
168} 170}
169 171
170static int symbol_valid_tr(struct sym_entry *s) 172static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges,
173 int entries)
171{ 174{
172 size_t i; 175 size_t i;
173 struct text_range *tr; 176 struct addr_range *ar;
174 177
175 for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { 178 for (i = 0; i < entries; ++i) {
176 tr = &text_ranges[i]; 179 ar = &ranges[i];
177 180
178 if (s->addr >= tr->start && s->addr <= tr->end) 181 if (s->addr >= ar->start && s->addr <= ar->end)
179 return 1; 182 return 1;
180 } 183 }
181 184
@@ -214,7 +217,8 @@ static int symbol_valid(struct sym_entry *s)
214 /* if --all-symbols is not specified, then symbols outside the text 217 /* if --all-symbols is not specified, then symbols outside the text
215 * and inittext sections are discarded */ 218 * and inittext sections are discarded */
216 if (!all_symbols) { 219 if (!all_symbols) {
217 if (symbol_valid_tr(s) == 0) 220 if (symbol_in_range(s, text_ranges,
221 ARRAY_SIZE(text_ranges)) == 0)
218 return 0; 222 return 0;
219 /* Corner case. Discard any symbols with the same value as 223 /* Corner case. Discard any symbols with the same value as
220 * _etext _einittext; they can move between pass 1 and 2 when 224 * _etext _einittext; they can move between pass 1 and 2 when
@@ -223,9 +227,11 @@ static int symbol_valid(struct sym_entry *s)
223 * rules. 227 * rules.
224 */ 228 */
225 if ((s->addr == text_range_text->end && 229 if ((s->addr == text_range_text->end &&
226 strcmp((char *)s->sym + offset, text_range_text->etext)) || 230 strcmp((char *)s->sym + offset,
231 text_range_text->end_sym)) ||
227 (s->addr == text_range_inittext->end && 232 (s->addr == text_range_inittext->end &&
228 strcmp((char *)s->sym + offset, text_range_inittext->etext))) 233 strcmp((char *)s->sym + offset,
234 text_range_inittext->end_sym)))
229 return 0; 235 return 0;
230 } 236 }
231 237
@@ -298,6 +304,11 @@ static int expand_symbol(unsigned char *data, int len, char *result)
298 return total; 304 return total;
299} 305}
300 306
307static int symbol_absolute(struct sym_entry *s)
308{
309 return toupper(s->sym[0]) == 'A';
310}
311
301static void write_src(void) 312static void write_src(void)
302{ 313{
303 unsigned int i, k, off; 314 unsigned int i, k, off;
@@ -325,7 +336,7 @@ static void write_src(void)
325 */ 336 */
326 output_label("kallsyms_addresses"); 337 output_label("kallsyms_addresses");
327 for (i = 0; i < table_cnt; i++) { 338 for (i = 0; i < table_cnt; i++) {
328 if (toupper(table[i].sym[0]) != 'A') { 339 if (!symbol_absolute(&table[i])) {
329 if (_text <= table[i].addr) 340 if (_text <= table[i].addr)
330 printf("\tPTR\t_text + %#llx\n", 341 printf("\tPTR\t_text + %#llx\n",
331 table[i].addr - _text); 342 table[i].addr - _text);