cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

parse.y (10900B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * C global declaration parser for genksyms.
      4 * Copyright 1996, 1997 Linux International.
      5 *
      6 * New implementation contributed by Richard Henderson <rth@tamu.edu>
      7 * Based on original work by Bjorn Ekwall <bj0rn@blox.se>
      8 *
      9 * This file is part of the Linux modutils.
     10 */
     11
     12%{
     13
     14#include <assert.h>
     15#include <stdlib.h>
     16#include <string.h>
     17#include "genksyms.h"
     18
     19static int is_typedef;
     20static int is_extern;
     21static char *current_name;
     22static struct string_list *decl_spec;
     23
     24static void yyerror(const char *);
     25
     26static inline void
     27remove_node(struct string_list **p)
     28{
     29  struct string_list *node = *p;
     30  *p = node->next;
     31  free_node(node);
     32}
     33
     34static inline void
     35remove_list(struct string_list **pb, struct string_list **pe)
     36{
     37  struct string_list *b = *pb, *e = *pe;
     38  *pb = e;
     39  free_list(b, e);
     40}
     41
     42/* Record definition of a struct/union/enum */
     43static void record_compound(struct string_list **keyw,
     44		       struct string_list **ident,
     45		       struct string_list **body,
     46		       enum symbol_type type)
     47{
     48	struct string_list *b = *body, *i = *ident, *r;
     49
     50	if (i->in_source_file) {
     51		remove_node(keyw);
     52		(*ident)->tag = type;
     53		remove_list(body, ident);
     54		return;
     55	}
     56	r = copy_node(i); r->tag = type;
     57	r->next = (*keyw)->next; *body = r; (*keyw)->next = NULL;
     58	add_symbol(i->string, type, b, is_extern);
     59}
     60
     61%}
     62
     63%token ASM_KEYW
     64%token ATTRIBUTE_KEYW
     65%token AUTO_KEYW
     66%token BOOL_KEYW
     67%token BUILTIN_INT_KEYW
     68%token CHAR_KEYW
     69%token CONST_KEYW
     70%token DOUBLE_KEYW
     71%token ENUM_KEYW
     72%token EXTERN_KEYW
     73%token EXTENSION_KEYW
     74%token FLOAT_KEYW
     75%token INLINE_KEYW
     76%token INT_KEYW
     77%token LONG_KEYW
     78%token REGISTER_KEYW
     79%token RESTRICT_KEYW
     80%token SHORT_KEYW
     81%token SIGNED_KEYW
     82%token STATIC_KEYW
     83%token STATIC_ASSERT_KEYW
     84%token STRUCT_KEYW
     85%token TYPEDEF_KEYW
     86%token UNION_KEYW
     87%token UNSIGNED_KEYW
     88%token VOID_KEYW
     89%token VOLATILE_KEYW
     90%token TYPEOF_KEYW
     91%token VA_LIST_KEYW
     92
     93%token EXPORT_SYMBOL_KEYW
     94
     95%token ASM_PHRASE
     96%token ATTRIBUTE_PHRASE
     97%token TYPEOF_PHRASE
     98%token BRACE_PHRASE
     99%token BRACKET_PHRASE
    100%token EXPRESSION_PHRASE
    101%token STATIC_ASSERT_PHRASE
    102
    103%token CHAR
    104%token DOTS
    105%token IDENT
    106%token INT
    107%token REAL
    108%token STRING
    109%token TYPE
    110%token OTHER
    111%token FILENAME
    112
    113%%
    114
    115declaration_seq:
    116	declaration
    117	| declaration_seq declaration
    118	;
    119
    120declaration:
    121	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
    122	declaration1
    123	{ free_list(*$2, NULL); *$2 = NULL; }
    124	;
    125
    126declaration1:
    127	EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
    128		{ $$ = $4; }
    129	| TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
    130		{ $$ = $3; }
    131	| simple_declaration
    132	| function_definition
    133	| asm_definition
    134	| export_definition
    135	| static_assert
    136	| error ';'				{ $$ = $2; }
    137	| error '}'				{ $$ = $2; }
    138	;
    139
    140simple_declaration:
    141	decl_specifier_seq_opt init_declarator_list_opt ';'
    142		{ if (current_name) {
    143		    struct string_list *decl = (*$3)->next;
    144		    (*$3)->next = NULL;
    145		    add_symbol(current_name,
    146			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
    147			       decl, is_extern);
    148		    current_name = NULL;
    149		  }
    150		  $$ = $3;
    151		}
    152	;
    153
    154init_declarator_list_opt:
    155	/* empty */				{ $$ = NULL; }
    156	| init_declarator_list
    157	;
    158
    159init_declarator_list:
    160	init_declarator
    161		{ struct string_list *decl = *$1;
    162		  *$1 = NULL;
    163		  add_symbol(current_name,
    164			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
    165		  current_name = NULL;
    166		  $$ = $1;
    167		}
    168	| init_declarator_list ',' init_declarator
    169		{ struct string_list *decl = *$3;
    170		  *$3 = NULL;
    171		  free_list(*$2, NULL);
    172		  *$2 = decl_spec;
    173		  add_symbol(current_name,
    174			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
    175		  current_name = NULL;
    176		  $$ = $3;
    177		}
    178	;
    179
    180init_declarator:
    181	declarator asm_phrase_opt attribute_opt initializer_opt
    182		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
    183	;
    184
    185/* Hang on to the specifiers so that we can reuse them.  */
    186decl_specifier_seq_opt:
    187	/* empty */				{ decl_spec = NULL; }
    188	| decl_specifier_seq
    189	;
    190
    191decl_specifier_seq:
    192	decl_specifier				{ decl_spec = *$1; }
    193	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
    194	;
    195
    196decl_specifier:
    197	storage_class_specifier
    198		{ /* Version 2 checksumming ignores storage class, as that
    199		     is really irrelevant to the linkage.  */
    200		  remove_node($1);
    201		  $$ = $1;
    202		}
    203	| type_specifier
    204	;
    205
    206storage_class_specifier:
    207	AUTO_KEYW
    208	| REGISTER_KEYW
    209	| STATIC_KEYW
    210	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
    211	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
    212	;
    213
    214type_specifier:
    215	simple_type_specifier
    216	| cvar_qualifier
    217	| TYPEOF_KEYW '(' parameter_declaration ')'
    218	| TYPEOF_PHRASE
    219
    220	/* References to s/u/e's defined elsewhere.  Rearrange things
    221	   so that it is easier to expand the definition fully later.  */
    222	| STRUCT_KEYW IDENT
    223		{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
    224	| UNION_KEYW IDENT
    225		{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
    226	| ENUM_KEYW IDENT
    227		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
    228
    229	/* Full definitions of an s/u/e.  Record it.  */
    230	| STRUCT_KEYW IDENT class_body
    231		{ record_compound($1, $2, $3, SYM_STRUCT); $$ = $3; }
    232	| UNION_KEYW IDENT class_body
    233		{ record_compound($1, $2, $3, SYM_UNION); $$ = $3; }
    234	| ENUM_KEYW IDENT enum_body
    235		{ record_compound($1, $2, $3, SYM_ENUM); $$ = $3; }
    236	/*
    237	 * Anonymous enum definition. Tell add_symbol() to restart its counter.
    238	 */
    239	| ENUM_KEYW enum_body
    240		{ add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; }
    241	/* Anonymous s/u definitions.  Nothing needs doing.  */
    242	| STRUCT_KEYW class_body			{ $$ = $2; }
    243	| UNION_KEYW class_body				{ $$ = $2; }
    244	;
    245
    246simple_type_specifier:
    247	CHAR_KEYW
    248	| SHORT_KEYW
    249	| INT_KEYW
    250	| LONG_KEYW
    251	| SIGNED_KEYW
    252	| UNSIGNED_KEYW
    253	| FLOAT_KEYW
    254	| DOUBLE_KEYW
    255	| VOID_KEYW
    256	| BOOL_KEYW
    257	| VA_LIST_KEYW
    258	| BUILTIN_INT_KEYW
    259	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
    260	;
    261
    262ptr_operator:
    263	'*' cvar_qualifier_seq_opt
    264		{ $$ = $2 ? $2 : $1; }
    265	;
    266
    267cvar_qualifier_seq_opt:
    268	/* empty */					{ $$ = NULL; }
    269	| cvar_qualifier_seq
    270	;
    271
    272cvar_qualifier_seq:
    273	cvar_qualifier
    274	| cvar_qualifier_seq cvar_qualifier		{ $$ = $2; }
    275	;
    276
    277cvar_qualifier:
    278	CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
    279	| RESTRICT_KEYW
    280		{ /* restrict has no effect in prototypes so ignore it */
    281		  remove_node($1);
    282		  $$ = $1;
    283		}
    284	;
    285
    286declarator:
    287	ptr_operator declarator			{ $$ = $2; }
    288	| direct_declarator
    289	;
    290
    291direct_declarator:
    292	IDENT
    293		{ if (current_name != NULL) {
    294		    error_with_pos("unexpected second declaration name");
    295		    YYERROR;
    296		  } else {
    297		    current_name = (*$1)->string;
    298		    $$ = $1;
    299		  }
    300		}
    301	| TYPE
    302		{ if (current_name != NULL) {
    303		    error_with_pos("unexpected second declaration name");
    304		    YYERROR;
    305		  } else {
    306		    current_name = (*$1)->string;
    307		    $$ = $1;
    308		  }
    309		}
    310	| direct_declarator '(' parameter_declaration_clause ')'
    311		{ $$ = $4; }
    312	| direct_declarator '(' error ')'
    313		{ $$ = $4; }
    314	| direct_declarator BRACKET_PHRASE
    315		{ $$ = $2; }
    316	| '(' declarator ')'
    317		{ $$ = $3; }
    318	;
    319
    320/* Nested declarators differ from regular declarators in that they do
    321   not record the symbols they find in the global symbol table.  */
    322nested_declarator:
    323	ptr_operator nested_declarator		{ $$ = $2; }
    324	| direct_nested_declarator
    325	;
    326
    327direct_nested_declarator:
    328	IDENT
    329	| TYPE
    330	| direct_nested_declarator '(' parameter_declaration_clause ')'
    331		{ $$ = $4; }
    332	| direct_nested_declarator '(' error ')'
    333		{ $$ = $4; }
    334	| direct_nested_declarator BRACKET_PHRASE
    335		{ $$ = $2; }
    336	| '(' nested_declarator ')'
    337		{ $$ = $3; }
    338	| '(' error ')'
    339		{ $$ = $3; }
    340	;
    341
    342parameter_declaration_clause:
    343	parameter_declaration_list_opt DOTS		{ $$ = $2; }
    344	| parameter_declaration_list_opt
    345	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
    346	;
    347
    348parameter_declaration_list_opt:
    349	/* empty */					{ $$ = NULL; }
    350	| parameter_declaration_list
    351	;
    352
    353parameter_declaration_list:
    354	parameter_declaration
    355	| parameter_declaration_list ',' parameter_declaration
    356		{ $$ = $3; }
    357	;
    358
    359parameter_declaration:
    360	decl_specifier_seq m_abstract_declarator
    361		{ $$ = $2 ? $2 : $1; }
    362	;
    363
    364m_abstract_declarator:
    365	ptr_operator m_abstract_declarator
    366		{ $$ = $2 ? $2 : $1; }
    367	| direct_m_abstract_declarator
    368	;
    369
    370direct_m_abstract_declarator:
    371	/* empty */					{ $$ = NULL; }
    372	| IDENT
    373		{ /* For version 2 checksums, we don't want to remember
    374		     private parameter names.  */
    375		  remove_node($1);
    376		  $$ = $1;
    377		}
    378	/* This wasn't really a typedef name but an identifier that
    379	   shadows one.  */
    380	| TYPE
    381		{ remove_node($1);
    382		  $$ = $1;
    383		}
    384	| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
    385		{ $$ = $4; }
    386	| direct_m_abstract_declarator '(' error ')'
    387		{ $$ = $4; }
    388	| direct_m_abstract_declarator BRACKET_PHRASE
    389		{ $$ = $2; }
    390	| '(' m_abstract_declarator ')'
    391		{ $$ = $3; }
    392	| '(' error ')'
    393		{ $$ = $3; }
    394	;
    395
    396function_definition:
    397	decl_specifier_seq_opt declarator BRACE_PHRASE
    398		{ struct string_list *decl = *$2;
    399		  *$2 = NULL;
    400		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
    401		  $$ = $3;
    402		}
    403	;
    404
    405initializer_opt:
    406	/* empty */					{ $$ = NULL; }
    407	| initializer
    408	;
    409
    410/* We never care about the contents of an initializer.  */
    411initializer:
    412	'=' EXPRESSION_PHRASE
    413		{ remove_list($2, &(*$1)->next); $$ = $2; }
    414	;
    415
    416class_body:
    417	'{' member_specification_opt '}'		{ $$ = $3; }
    418	| '{' error '}'					{ $$ = $3; }
    419	;
    420
    421member_specification_opt:
    422	/* empty */					{ $$ = NULL; }
    423	| member_specification
    424	;
    425
    426member_specification:
    427	member_declaration
    428	| member_specification member_declaration	{ $$ = $2; }
    429	;
    430
    431member_declaration:
    432	decl_specifier_seq_opt member_declarator_list_opt ';'
    433		{ $$ = $3; }
    434	| error ';'
    435		{ $$ = $2; }
    436	;
    437
    438member_declarator_list_opt:
    439	/* empty */					{ $$ = NULL; }
    440	| member_declarator_list
    441	;
    442
    443member_declarator_list:
    444	member_declarator
    445	| member_declarator_list ',' member_declarator	{ $$ = $3; }
    446	;
    447
    448member_declarator:
    449	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
    450	| IDENT member_bitfield_declarator		{ $$ = $2; }
    451	| member_bitfield_declarator
    452	;
    453
    454member_bitfield_declarator:
    455	':' EXPRESSION_PHRASE				{ $$ = $2; }
    456	;
    457
    458attribute_opt:
    459	/* empty */					{ $$ = NULL; }
    460	| attribute_opt ATTRIBUTE_PHRASE
    461	;
    462
    463enum_body:
    464	'{' enumerator_list '}'				{ $$ = $3; }
    465	| '{' enumerator_list ',' '}'			{ $$ = $4; }
    466	 ;
    467
    468enumerator_list:
    469	enumerator
    470	| enumerator_list ',' enumerator
    471
    472enumerator:
    473	IDENT
    474		{
    475			const char *name = strdup((*$1)->string);
    476			add_symbol(name, SYM_ENUM_CONST, NULL, 0);
    477		}
    478	| IDENT '=' EXPRESSION_PHRASE
    479		{
    480			const char *name = strdup((*$1)->string);
    481			struct string_list *expr = copy_list_range(*$3, *$2);
    482			add_symbol(name, SYM_ENUM_CONST, expr, 0);
    483		}
    484
    485asm_definition:
    486	ASM_PHRASE ';'					{ $$ = $2; }
    487	;
    488
    489asm_phrase_opt:
    490	/* empty */					{ $$ = NULL; }
    491	| ASM_PHRASE
    492	;
    493
    494export_definition:
    495	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
    496		{ export_symbol((*$3)->string); $$ = $5; }
    497	;
    498
    499/* Ignore any module scoped _Static_assert(...) */
    500static_assert:
    501	STATIC_ASSERT_PHRASE ';'			{ $$ = $2; }
    502	;
    503
    504%%
    505
    506static void
    507yyerror(const char *e)
    508{
    509  error_with_pos("%s", e);
    510}