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

aicasm_scan.l (15485B)


      1%{
      2/*
      3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
      4 *
      5 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
      6 * Copyright (c) 2001, 2002 Adaptec Inc.
      7 * All rights reserved.
      8 *
      9 * Redistribution and use in source and binary forms, with or without
     10 * modification, are permitted provided that the following conditions
     11 * are met:
     12 * 1. Redistributions of source code must retain the above copyright
     13 *    notice, this list of conditions, and the following disclaimer,
     14 *    without modification.
     15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     16 *    substantially similar to the "NO WARRANTY" disclaimer below
     17 *    ("Disclaimer") and any redistribution must be conditioned upon
     18 *    including a substantially similar Disclaimer requirement for further
     19 *    binary redistribution.
     20 * 3. Neither the names of the above-listed copyright holders nor the names
     21 *    of any contributors may be used to endorse or promote products derived
     22 *    from this software without specific prior written permission.
     23 *
     24 * Alternatively, this software may be distributed under the terms of the
     25 * GNU General Public License ("GPL") version 2 as published by the Free
     26 * Software Foundation.
     27 *
     28 * NO WARRANTY
     29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     39 * POSSIBILITY OF SUCH DAMAGES.
     40 *
     41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $
     42 *
     43 * $FreeBSD$
     44 */
     45
     46#include <sys/types.h>
     47
     48#include <inttypes.h>
     49#include <limits.h>
     50#include <regex.h>
     51#include <stdio.h>
     52#include <string.h>
     53#include <sysexits.h>
     54#include "../queue.h"
     55
     56#include "aicasm.h"
     57#include "aicasm_symbol.h"
     58#include "aicasm_gram.h"
     59
     60/* This is used for macro body capture too, so err on the large size. */
     61#define MAX_STR_CONST 4096
     62static char string_buf[MAX_STR_CONST];
     63static char *string_buf_ptr;
     64static int  parren_count;
     65static int  quote_count;
     66static char buf[255];
     67%}
     68
     69PATH		([/]*[-A-Za-z0-9_.])+
     70WORD		[A-Za-z_][-A-Za-z_0-9]*
     71SPACE		[ \t]+
     72MCARG		[^(), \t]+
     73MBODY		((\\[^\n])*[^\n\\]*)+
     74
     75%x COMMENT
     76%x CEXPR
     77%x INCLUDE
     78%x STRING
     79%x MACRODEF
     80%x MACROARGLIST
     81%x MACROCALLARGS
     82%x MACROBODY
     83
     84%%
     85\n			{ ++yylineno; }
     86\r			;
     87"/*"			{ BEGIN COMMENT;  /* Enter comment eating state */ }
     88<COMMENT>"/*"		{ fprintf(stderr, "Warning! Comment within comment."); }
     89<COMMENT>\n		{ ++yylineno; }
     90<COMMENT>[^*/\n]*	;
     91<COMMENT>"*"+[^*/\n]*	;
     92<COMMENT>"/"+[^*/\n]*	;
     93<COMMENT>"*"+"/"	{ BEGIN INITIAL; }
     94if[ \t]*\(		{
     95				string_buf_ptr = string_buf;
     96				parren_count = 1;
     97				BEGIN CEXPR;
     98				return T_IF;
     99			}
    100<CEXPR>\(		{	*string_buf_ptr++ = '('; parren_count++; }
    101<CEXPR>\)		{
    102				parren_count--;
    103				if (parren_count == 0) {
    104					/* All done */
    105					BEGIN INITIAL;
    106					*string_buf_ptr = '\0';
    107					yylval.sym = symtable_get(string_buf);
    108					return T_CEXPR;
    109				} else {
    110					*string_buf_ptr++ = ')';
    111				}
    112			}
    113<CEXPR>\n		{ ++yylineno; }
    114<CEXPR>\r		;
    115<CEXPR>[^()\n]+	{
    116				char *yptr;
    117
    118				yptr = yytext;
    119				while (*yptr != '\0') {
    120					/* Remove duplicate spaces */
    121					if (*yptr == '\t')
    122						*yptr = ' ';
    123					if (*yptr == ' '
    124					 && string_buf_ptr != string_buf
    125					 && string_buf_ptr[-1] == ' ')
    126						yptr++;
    127					else 
    128						*string_buf_ptr++ = *yptr++;
    129				}
    130			}
    131else			{ return T_ELSE; }
    132VERSION			{ return T_VERSION; }
    133PREFIX			{ return T_PREFIX; }
    134PATCH_ARG_LIST		{ return T_PATCH_ARG_LIST; }
    135\"			{
    136				string_buf_ptr = string_buf;
    137				BEGIN STRING;
    138			}
    139<STRING>[^"]+		{
    140				char *yptr;
    141
    142				yptr = yytext;
    143				while (*yptr)
    144					*string_buf_ptr++ = *yptr++;
    145			}
    146<STRING>\"		{
    147				/* All done */
    148				BEGIN INITIAL;
    149				*string_buf_ptr = '\0';
    150				yylval.str = string_buf;
    151				return T_STRING;
    152			}
    153{SPACE}			 ;
    154
    155	/* Register/SCB/SRAM definition keywords */
    156export			{ return T_EXPORT; }
    157register		{ return T_REGISTER; }
    158const			{ yylval.value = FALSE; return T_CONST; }
    159download		{ return T_DOWNLOAD; }
    160address			{ return T_ADDRESS; }
    161count			{ return T_COUNT; }
    162access_mode		{ return T_ACCESS_MODE; }
    163dont_generate_debug_code { return T_DONT_GENERATE_DEBUG_CODE; }
    164modes			{ return T_MODES; }
    165RW|RO|WO		{
    166				 if (strcmp(yytext, "RW") == 0)
    167					yylval.value = RW;
    168				 else if (strcmp(yytext, "RO") == 0)
    169					yylval.value = RO;
    170				 else
    171					yylval.value = WO;
    172				 return T_MODE;
    173			}
    174field			{ return T_FIELD; }
    175enum			{ return T_ENUM; }
    176mask			{ return T_MASK; }
    177alias			{ return T_ALIAS; }
    178size			{ return T_SIZE; }
    179scb			{ return T_SCB; }
    180scratch_ram		{ return T_SRAM; }
    181accumulator		{ return T_ACCUM; }
    182mode_pointer		{ return T_MODE_PTR; }
    183allones			{ return T_ALLONES; }
    184allzeros		{ return T_ALLZEROS; }
    185none			{ return T_NONE; }
    186sindex			{ return T_SINDEX; }
    187A			{ return T_A; }
    188
    189	/* Instruction Formatting */
    190PAD_PAGE		{ return T_PAD_PAGE; }
    191BEGIN_CRITICAL		{ return T_BEGIN_CS; }
    192END_CRITICAL		{ return T_END_CS; }
    193SET_SRC_MODE		{ return T_SET_SRC_MODE; }
    194SET_DST_MODE		{ return T_SET_DST_MODE; }
    195
    196	/* Opcodes */
    197shl			{ return T_SHL; }
    198shr			{ return T_SHR; }
    199ror			{ return T_ROR; }
    200rol			{ return T_ROL; }
    201mvi			{ return T_MVI; }
    202mov			{ return T_MOV; }
    203clr			{ return T_CLR; }
    204jmp			{ return T_JMP; }
    205jc			{ return T_JC;	}
    206jnc			{ return T_JNC;	}
    207je			{ return T_JE;	}
    208jne			{ return T_JNE;	}
    209jz			{ return T_JZ;	}
    210jnz			{ return T_JNZ;	}
    211call			{ return T_CALL; }
    212add			{ return T_ADD; }
    213adc			{ return T_ADC; }
    214bmov			{ return T_BMOV; }
    215inc			{ return T_INC; }
    216dec			{ return T_DEC; }
    217stc			{ return T_STC;	}
    218clc			{ return T_CLC; }
    219cmp			{ return T_CMP;	}
    220not			{ return T_NOT;	}
    221xor			{ return T_XOR;	}
    222test			{ return T_TEST;}
    223and			{ return T_AND;	}
    224or			{ return T_OR;	}
    225ret			{ return T_RET; }
    226nop			{ return T_NOP; }
    227
    228	/* ARP2 16bit extensions */
    229	/* or16			{ return T_OR16; } */
    230	/* and16			{ return T_AND16; }*/
    231	/* xor16			{ return T_XOR16; }*/
    232	/* add16			{ return T_ADD16; }*/
    233	/* adc16			{ return T_ADC16; }*/
    234	/* mvi16			{ return T_MVI16; }*/
    235	/* test16			{ return T_TEST16; }*/
    236	/* cmp16			{ return T_CMP16; }*/
    237	/* cmpxchg			{ return T_CMPXCHG; }*/
    238
    239	/* Allowed Symbols */
    240\<\<			{ return T_EXPR_LSHIFT; }
    241\>\>			{ return T_EXPR_RSHIFT; }
    242[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
    243
    244	/* Number processing */
    2450[0-7]*			{
    246				yylval.value = strtol(yytext, NULL, 8);
    247				return T_NUMBER;
    248			}
    249
    2500[xX][0-9a-fA-F]+	{
    251				yylval.value = strtoul(yytext + 2, NULL, 16);
    252				return T_NUMBER;
    253			}
    254
    255[1-9][0-9]*		{
    256				yylval.value = strtol(yytext, NULL, 10);
    257				return T_NUMBER;
    258			}
    259	/* Include Files */
    260#include{SPACE}		{
    261				BEGIN INCLUDE;
    262				quote_count = 0;
    263				return T_INCLUDE;
    264			}
    265<INCLUDE>[<]		{ return yytext[0]; }
    266<INCLUDE>[>]		{ BEGIN INITIAL; return yytext[0]; }
    267<INCLUDE>[\"]		{
    268				if (quote_count != 0)
    269					BEGIN INITIAL;
    270				quote_count++;
    271				return yytext[0];
    272			}
    273<INCLUDE>{PATH}		{
    274				char *yptr;
    275
    276				yptr = yytext;
    277				string_buf_ptr = string_buf;
    278				while (*yptr)
    279					*string_buf_ptr++ = *yptr++;
    280				yylval.str = string_buf;
    281				*string_buf_ptr = '\0';
    282				return T_PATH;
    283			}
    284<INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
    285#define{SPACE}		{
    286				BEGIN MACRODEF;
    287				return T_DEFINE;
    288			}
    289<MACRODEF>{WORD}{SPACE}	{ 
    290				char *yptr;
    291
    292				/* Strip space and return as a normal symbol */
    293				yptr = yytext;
    294				while (*yptr != ' ' && *yptr != '\t')
    295					yptr++;
    296				*yptr = '\0';
    297				yylval.sym = symtable_get(yytext);
    298				string_buf_ptr = string_buf;
    299				BEGIN MACROBODY;
    300				return T_SYMBOL;
    301			}
    302<MACRODEF>{WORD}\(	{
    303				/*
    304				 * We store the symbol with its opening
    305				 * parren so we can differentiate macros
    306				 * that take args from macros with the
    307				 * same name that do not take args as
    308				 * is allowed in C.
    309				 */
    310				BEGIN MACROARGLIST;
    311				yylval.sym = symtable_get(yytext);
    312				unput('(');
    313				return T_SYMBOL;
    314			}
    315<MACROARGLIST>{WORD}	{
    316				yylval.str = yytext;
    317				return T_ARG;
    318			}
    319<MACROARGLIST>{SPACE}   ;
    320<MACROARGLIST>[(,]	{
    321				return yytext[0];
    322			}
    323<MACROARGLIST>[)]	{
    324				string_buf_ptr = string_buf;
    325				BEGIN MACROBODY;
    326				return ')';
    327			}
    328<MACROARGLIST>.		{
    329				snprintf(buf, sizeof(buf), "Invalid character "
    330					 "'%c' in macro argument list",
    331					 yytext[0]);
    332				stop(buf, EX_DATAERR);
    333			}
    334<MACROCALLARGS>{SPACE}  ;
    335<MACROCALLARGS>\(	{
    336				parren_count++;
    337				if (parren_count == 1)
    338					return ('(');
    339				*string_buf_ptr++ = '(';
    340			}
    341<MACROCALLARGS>\)	{
    342				parren_count--;
    343				if (parren_count == 0) {
    344					BEGIN INITIAL;
    345					return (')');
    346				}
    347				*string_buf_ptr++ = ')';
    348			}
    349<MACROCALLARGS>{MCARG}	{
    350				char *yptr;
    351
    352				yptr = yytext;
    353				while (*yptr)
    354					*string_buf_ptr++ = *yptr++;
    355			}
    356<MACROCALLARGS>\,	{
    357				if (string_buf_ptr != string_buf) {
    358					/*
    359					 * Return an argument and
    360					 * rescan this comma so we
    361					 * can return it as well.
    362					 */
    363					*string_buf_ptr = '\0';
    364					yylval.str = string_buf;
    365					string_buf_ptr = string_buf;
    366					unput(',');
    367					return T_ARG;
    368				}
    369				return ',';
    370			}
    371<MACROBODY>\\\n		{
    372				/* Eat escaped newlines. */
    373				++yylineno;
    374			}
    375<MACROBODY>\r		;
    376<MACROBODY>\n		{
    377				/* Macros end on the first unescaped newline. */
    378				BEGIN INITIAL;
    379				*string_buf_ptr = '\0';
    380				yylval.str = string_buf;
    381				++yylineno;
    382				return T_MACROBODY;
    383			}
    384<MACROBODY>{MBODY}	{
    385				char *yptr;
    386				char c;
    387
    388				yptr = yytext;
    389				while (c = *yptr++) {
    390					/*
    391					 * Strip carriage returns.
    392					 */
    393					if (c == '\r')
    394						continue;
    395					*string_buf_ptr++ = c;
    396				}
    397			}
    398{WORD}\(		{
    399				char *yptr;
    400				char *ycopy;
    401
    402				/* May be a symbol or a macro invocation. */
    403				yylval.sym = symtable_get(yytext);
    404				if (yylval.sym->type == MACRO) {
    405					YY_BUFFER_STATE old_state;
    406					YY_BUFFER_STATE temp_state;
    407
    408					ycopy = strdup(yytext);
    409					yptr = ycopy + yyleng;
    410					while (yptr > ycopy)
    411						unput(*--yptr);
    412					old_state = YY_CURRENT_BUFFER;
    413					temp_state =
    414					    yy_create_buffer(stdin,
    415							     YY_BUF_SIZE);
    416					yy_switch_to_buffer(temp_state);
    417					mm_switch_to_buffer(old_state);
    418					mmparse();
    419					mm_switch_to_buffer(temp_state);
    420					yy_switch_to_buffer(old_state);
    421					mm_delete_buffer(temp_state);
    422					expand_macro(yylval.sym);
    423				} else {
    424					if (yylval.sym->type == UNINITIALIZED) {
    425						/* Try without the '(' */
    426						symbol_delete(yylval.sym);
    427						yytext[yyleng-1] = '\0';
    428						yylval.sym =
    429						    symtable_get(yytext);
    430					}
    431					unput('(');
    432					return T_SYMBOL;
    433				}
    434			}
    435{WORD}			{
    436				yylval.sym = symtable_get(yytext);
    437				if (yylval.sym->type == MACRO) {
    438					expand_macro(yylval.sym);
    439				} else {
    440					return T_SYMBOL;
    441				}
    442			}
    443.			{ 
    444				snprintf(buf, sizeof(buf), "Invalid character "
    445					 "'%c'", yytext[0]);
    446				stop(buf, EX_DATAERR);
    447			}
    448%%
    449
    450typedef struct include {
    451        YY_BUFFER_STATE  buffer;
    452        int              lineno;
    453        char            *filename;
    454	SLIST_ENTRY(include) links;
    455}include_t;
    456
    457SLIST_HEAD(, include) include_stack;
    458
    459void
    460include_file(char *file_name, include_type type)
    461{
    462	FILE *newfile;
    463	include_t *include;
    464
    465	newfile = NULL;
    466	/* Try the current directory first */
    467	if (includes_search_curdir != 0 || type == SOURCE_FILE)
    468		newfile = fopen(file_name, "r");
    469
    470	if (newfile == NULL && type != SOURCE_FILE) {
    471                path_entry_t include_dir;
    472                for (include_dir = search_path.slh_first;
    473                     include_dir != NULL;                
    474                     include_dir = include_dir->links.sle_next) {
    475			char fullname[PATH_MAX];
    476
    477			if ((include_dir->quoted_includes_only == TRUE)
    478			 && (type != QUOTED_INCLUDE))
    479				continue;
    480
    481			snprintf(fullname, sizeof(fullname),
    482				 "%s/%s", include_dir->directory, file_name);
    483
    484			if ((newfile = fopen(fullname, "r")) != NULL)
    485				break;
    486                }
    487        }
    488
    489	if (newfile == NULL) {
    490		perror(file_name);
    491		stop("Unable to open input file", EX_SOFTWARE);
    492		/* NOTREACHED */
    493	}
    494
    495	if (type != SOURCE_FILE) {
    496		include = (include_t *)malloc(sizeof(include_t));
    497		if (include == NULL) {
    498			stop("Unable to allocate include stack entry",
    499			     EX_SOFTWARE);
    500			/* NOTREACHED */
    501		}
    502		include->buffer = YY_CURRENT_BUFFER;
    503		include->lineno = yylineno;
    504		include->filename = yyfilename;
    505		SLIST_INSERT_HEAD(&include_stack, include, links);
    506	}
    507	yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
    508	yylineno = 1;
    509	yyfilename = strdup(file_name);
    510}
    511
    512static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
    513			      const char **next_match,
    514			      struct macro_arg **match_marg, regmatch_t *match);
    515
    516void
    517expand_macro(struct symbol *macro_symbol)
    518{
    519	struct macro_arg *marg;
    520	struct macro_arg *match_marg;
    521	const char *body_head;
    522	const char *body_pos;
    523	const char *next_match;
    524
    525	/*
    526	 * Due to the nature of unput, we must work
    527	 * backwards through the macro body performing
    528	 * any expansions.
    529	 */
    530	body_head = macro_symbol->info.macroinfo->body;
    531	body_pos = body_head + strlen(body_head);
    532	while (body_pos > body_head) {
    533		regmatch_t match;
    534
    535		next_match = body_head;
    536		match_marg = NULL;
    537		next_substitution(macro_symbol, body_pos, &next_match,
    538				  &match_marg, &match);
    539
    540		/* Put back everything up until the replacement. */
    541		while (body_pos > next_match)
    542			unput(*--body_pos);
    543
    544		/* Perform the replacement. */
    545		if (match_marg != NULL) {
    546			const char *strp;
    547
    548			next_match = match_marg->replacement_text;
    549			strp = next_match + strlen(next_match);
    550			while (strp > next_match)
    551				unput(*--strp);
    552
    553			/* Skip past the unexpanded macro arg. */
    554			body_pos -= match.rm_eo - match.rm_so;
    555		}
    556	}
    557
    558	/* Cleanup replacement text. */
    559	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
    560		free(marg->replacement_text);
    561	}
    562}
    563
    564/*
    565 * Find the next substitution in the macro working backwards from
    566 * body_pos until the beginning of the macro buffer.  next_match
    567 * should be initialized to the beginning of the macro buffer prior
    568 * to calling this routine.
    569 */
    570static void
    571next_substitution(struct symbol *mac_symbol, const char *body_pos,
    572		  const char **next_match, struct macro_arg **match_marg,
    573		  regmatch_t *match)
    574{
    575	regmatch_t	  matches[2];
    576	struct macro_arg *marg;
    577	const char	 *search_pos;
    578	int		  retval;
    579
    580	do {
    581		search_pos = *next_match;
    582
    583		STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
    584
    585			retval = regexec(&marg->arg_regex, search_pos, 2,
    586					 matches, 0);
    587			if (retval == 0
    588			 && (matches[1].rm_eo + search_pos) <= body_pos
    589			 && (matches[1].rm_eo + search_pos) > *next_match) {
    590				*match = matches[1];
    591				*next_match = match->rm_eo + search_pos;
    592				*match_marg = marg;
    593			}
    594		}
    595	} while (search_pos != *next_match);
    596}
    597
    598int
    599yywrap()
    600{
    601	include_t *include;
    602
    603	yy_delete_buffer(YY_CURRENT_BUFFER);
    604	(void)fclose(yyin);
    605	if (yyfilename != NULL)
    606		free(yyfilename);
    607	yyfilename = NULL;
    608	include = include_stack.slh_first;
    609	if (include != NULL) {
    610		yy_switch_to_buffer(include->buffer);
    611		yylineno = include->lineno;
    612		yyfilename = include->filename;
    613		SLIST_REMOVE_HEAD(&include_stack, links);
    614		free(include);
    615		return (0);
    616	}
    617	return (1);
    618}