aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/genksyms/lex.l
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-02-03 17:57:09 -0500
committerMichal Marek <mmarek@suse.cz>2011-03-17 10:13:56 -0400
commite37ddb82500393cb417c3ab0fe0726d9a8652372 (patch)
tree6ecc94992cb5affad4fe438d9b586a61b803f928 /scripts/genksyms/lex.l
parent01762c4ec5f6f62c550304b9c70e824293cefdd0 (diff)
genksyms: Track changes to enum constants
Enum constants can be used as array sizes; if the enum itself does not appear in the symbol expansion, a change in the enum constant will go unnoticed. Example patch that changes the ABI but does not change the checksum with current genksyms: | enum e { | E1, | E2, |+ E3, | E_MAX | }; | | struct s { | int a[E_MAX]; | } | | int f(struct s *s) { ... } | EXPORT_SYMBOL(f) Therefore, remember the value of each enum constant and expand each occurence to <constant> <value>. The value is not actually computed, but instead an expression in the form (last explicitly assigned value) + N is used. This avoids having to parse and semantically understand whole of C. Note: The changes won't take effect until the lexer and parser are rebuilt by the next patch. Signed-off-by: Michal Marek <mmarek@suse.cz> Acked-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/genksyms/lex.l')
-rw-r--r--scripts/genksyms/lex.l30
1 files changed, 27 insertions, 3 deletions
diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l
index c125d06fbd36..e4ddd493fec3 100644
--- a/scripts/genksyms/lex.l
+++ b/scripts/genksyms/lex.l
@@ -99,12 +99,23 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
99 99
100/* Macros to append to our phrase collection list. */ 100/* Macros to append to our phrase collection list. */
101 101
102/*
103 * We mark any token, that that equals to a known enumerator, as
104 * SYM_ENUM_CONST. The parser will change this for struct and union tags later,
105 * the only problem is struct and union members:
106 * enum e { a, b }; struct s { int a, b; }
107 * but in this case, the only effect will be, that the ABI checksums become
108 * more volatile, which is acceptable. Also, such collisions are quite rare,
109 * so far it was only observed in include/linux/telephony.h.
110 */
102#define _APP(T,L) do { \ 111#define _APP(T,L) do { \
103 cur_node = next_node; \ 112 cur_node = next_node; \
104 next_node = xmalloc(sizeof(*next_node)); \ 113 next_node = xmalloc(sizeof(*next_node)); \
105 next_node->next = cur_node; \ 114 next_node->next = cur_node; \
106 cur_node->string = memcpy(xmalloc(L+1), T, L+1); \ 115 cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
107 cur_node->tag = SYM_NORMAL; \ 116 cur_node->tag = \
117 find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\
118 SYM_ENUM_CONST : SYM_NORMAL ; \
108 } while (0) 119 } while (0)
109 120
110#define APP _APP(yytext, yyleng) 121#define APP _APP(yytext, yyleng)
@@ -182,8 +193,8 @@ repeat:
182 193
183 case STRUCT_KEYW: 194 case STRUCT_KEYW:
184 case UNION_KEYW: 195 case UNION_KEYW:
185 dont_want_brace_phrase = 3;
186 case ENUM_KEYW: 196 case ENUM_KEYW:
197 dont_want_brace_phrase = 3;
187 suppress_type_lookup = 2; 198 suppress_type_lookup = 2;
188 goto fini; 199 goto fini;
189 200
@@ -312,7 +323,20 @@ repeat:
312 ++count; 323 ++count;
313 APP; 324 APP;
314 goto repeat; 325 goto repeat;
315 case ')': case ']': case '}': 326 case '}':
327 /* is this the last line of an enum declaration? */
328 if (count == 0)
329 {
330 /* Put back the token we just read so's we can find it again
331 after registering the expression. */
332 unput(token);
333
334 lexstate = ST_NORMAL;
335 token = EXPRESSION_PHRASE;
336 break;
337 }
338 /* FALLTHRU */
339 case ')': case ']':
316 --count; 340 --count;
317 APP; 341 APP;
318 goto repeat; 342 goto repeat;