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 | |
parent | 028f042613c3c99db20dd7f4e4069fbbcea92dd7 (diff) |
kallsyms: generalize text region handling
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
-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 | ||