1 %{
2 /*-
3  * Copyright (c) 2010-2013 Kai Wang
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include "ld.h"
29 #include "ld_script_parser.h"
30 
31 ELFTC_VCSID("$Id: ld_script_lexer.l 3394 2016-02-07 11:39:17Z jkoshy $");
32 
33 #define	YY_NO_UNPUT
34 int lineno = 1;
35 
36 int	yylex(void);
37 
38 static void	_calc_num(void);
39 static void	_get_string(void);
40 static void	_get_ident(void);
41 static void	_skip_comment(void);
42 
43 %}
44 
45 DEC		[0-9]+[kKmMdD]?
46 OCT		(0[0-7]*+[kKmM]?)|([0-7]+[oO])
47 HEX		(0[xX][0-9a-fA-F]+[kKmMhH]?)|([0-9a-fA-F]+[hH])
48 IDENT		[-_A-Za-z/:$.\\~][-_A-Za-z/:$.\\~0-9]*
49 WILDCARD	[-_A-Za-z/:$.\\~0-9\[\]?*]+
50 MATTR		\(!?[rRwWxXaAiIlL]+\)
51 
52 %option noyywrap
53 %option never-interactive
54 %option nounput
55 
56 %%
57 
58 ABSOLUTE			{ return (T_ABSOLUTE); }
59 ADDR				{ return (T_ADDR); }
60 ALIGN				{ return (T_ALIGN); }
61 ALIGNOF				{ return (T_ALIGNOF); }
62 ASSERT				{ return (T_ASSERT); }
63 AS_NEEDED			{ return (T_AS_NEEDED); }
64 AT				{ return (T_AT); }
65 BIND				{ return (T_BIND); }
66 BLOCK				{ return (T_BLOCK); }
67 BYTE				{ return (T_BYTE); }
68 COMMONPAGESIZE			{ _get_ident(); return (T_COMMONPAGESIZE); }
69 CONSTANT			{ return (T_CONSTANT); }
70 CONSTRUCTORS			{ return (T_CONSTRUCTORS); }
71 COPY				{ return (T_COPY); }
72 CREATE_OBJECT_SYMBOLS		{ return (T_CREATE_OBJECT_SYMBOLS); }
73 DATA_SEGMENT_ALIGN		{ return (T_DATA_SEGMENT_ALIGN); }
74 DATA_SEGMENT_END		{ return (T_DATA_SEGMENT_END); }
75 DATA_SEGMENT_RELRO_END		{ return (T_DATA_SEGMENT_RELRO_END); }
76 DEFINED				{ return (T_DEFINED); }
77 DSECT				{ return (T_DSECT); }
78 ENTRY				{ return (T_ENTRY); }
79 EXCLUDE_FILE			{ return (T_EXCLUDE_FILE); }
80 EXTERN				{ return (T_EXTERN); }
81 FILEHDR				{ return (T_FILEHDR); }
82 FILL				{ return (T_FILL); }
83 FLAGS				{ return (T_FLAGS); }
84 FLOAT				{ return (T_FLOAT); }
85 FORCE_COMMON_ALLOCATION		{ return (T_FORCE_COMMON_ALLOCATION); }
86 GROUP				{ return (T_GROUP); }
87 HLL				{ return (T_HLL); }
88 INCLUDE				{ return (T_INCLUDE); }
89 INFO				{ return (T_INFO); }
90 INHIBIT_COMMON_ALLOCATION	{ return (T_INHIBIT_COMMON_ALLOCATION); }
91 INPUT				{ return (T_INPUT); }
92 KEEP				{ return (T_KEEP); }
93 LENGTH				{ return (T_LENGTH); }
94 LOADADDR			{ return (T_LOADADDR); }
95 LONG				{ return (T_LONG); }
96 MAP				{ return (T_MAP); }
97 MAX				{ return (T_MAX); }
98 MAXPAGESIZE			{ _get_ident(); return (T_MAXPAGESIZE); }
99 MEMORY				{ return (T_MEMORY); }
100 MIN				{ return (T_MIN); }
101 NEXT				{ return (T_NEXT); }
102 NOCROSSREFS			{ return (T_NOCROSSREFS); }
103 NOFLOAT				{ return (T_NOFLOAT); }
104 NOLOAD				{ return (T_NOLOAD); }
105 ONLY_IF_RO			{ return (T_ONLY_IF_RO); }
106 ONLY_IF_RW			{ return (T_ONLY_IF_RW); }
107 OPTION				{ return (T_OPTION); }
108 ORIGIN				{ return (T_ORIGIN); }
109 OUTPUT				{ return (T_OUTPUT); }
110 OUTPUT_ARCH			{ return (T_OUTPUT_ARCH); }
111 OUTPUT_FORMAT			{ return (T_OUTPUT_FORMAT); }
112 OVERLAY				{ return (T_OVERLAY); }
113 PHDRS				{ return (T_PHDRS); }
114 PROVIDE				{ return (T_PROVIDE); }
115 PROVIDE_HIDDEN			{ return (T_PROVIDE_HIDDEN); }
116 QUAD				{ return (T_QUAD); }
117 REGION_ALIAS			{ return (T_REGION_ALIAS); }
118 SEARCH_DIR			{ return (T_SEARCH_DIR); }
119 SECTIONS			{ return (T_SECTIONS); }
120 SEGMENT_START			{ return (T_SEGMENT_START); }
121 SHORT				{ return (T_SHORT); }
122 SIZEOF				{ return (T_SIZEOF); }
123 SIZEOF_HEADERS			{ return (T_SIZEOF_HEADERS); }
124 SORT				{ return (T_SORT_BY_NAME); }
125 SORT_BY_ALIGNMENT		{ return (T_SORT_BY_ALIGNMENT); }
126 SORT_BY_NAME			{ return (T_SORT_BY_NAME); }
127 SPECIAL				{ return (T_SPECIAL); }
128 SQUAD				{ return (T_SQUAD); }
129 STARTUP				{ return (T_STARTUP); }
130 SUBALIGN			{ return (T_SUBALIGN); }
131 SYSLIB				{ return (T_SYSLIB); }
132 TARGET				{ return (T_TARGET); }
133 TRUNCATE			{ return (T_TRUNCATE); }
134 extern				{ return (T_VER_EXTERN); }
135 global:				{ return (T_VER_GLOBAL); }
136 l				{ return (T_LENGTH); }
137 len				{ return (T_LENGTH); }
138 local:				{ return (T_VER_LOCAL); }
139 o				{ return (T_ORIGIN); }
140 org				{ return (T_ORIGIN); }
141 sizeof_headers			{ return (T_SIZEOF_HEADERS); }
142 "/*"				{ _skip_comment(); }
143 "\""[^\"]+"\""			{ _get_string(); return (T_STRING); }
144 {DEC}|{OCT}|{HEX}		{ _calc_num(); return (T_NUM); }
145 "<<="				{ return (T_LSHIFT_E); }
146 ">>="				{ return (T_RSHIFT_E); }
147 "<<"				{ return (T_LSHIFT); }
148 ">>"				{ return (T_RSHIFT); }
149 "=="				{ return (T_EQ); }
150 "!="				{ return (T_NE); }
151 ">="				{ return (T_GE); }
152 "<="				{ return (T_LE); }
153 "+="				{ return (T_ADD_E); }
154 "-="				{ return (T_SUB_E); }
155 "*="				{ return (T_MUL_E); }
156 "/="				{ return (T_DIV_E); }
157 "&="				{ return (T_AND_E); }
158 "|="				{ return (T_OR_E); }
159 "&&"				{ return (T_LOGICAL_AND); }
160 "||"				{ return (T_LOGICAL_OR); }
161 "!"				{ return ('!'); }
162 "{"				{ return ('{'); }
163 "}"				{ return ('}'); }
164 "["				{ return ('['); }
165 "]"				{ return (']'); }
166 "("				{ return ('('); }
167 ")"				{ return (')'); }
168 "?"				{ return ('?'); }
169 ":"				{ return (':'); }
170 ";"				{ return (';'); }
171 "&"				{ return ('&'); }
172 "|"				{ return ('|'); }
173 "~"				{ return ('~'); }
174 "+"				{ return ('+'); }
175 "-"				{ return ('-'); }
176 "*"				{ return ('*'); }
177 "/"				{ return ('/'); }
178 "%"				{ return ('%'); }
179 "="				{ return ('='); }
180 "<"				{ return ('<'); }
181 ">"				{ return ('>'); }
182 ","				{ return (','); }
183 "."				{ return ('.'); }
184 {MATTR}				{ _get_ident(); return (T_MEMORY_ATTR); }
185 {IDENT}				{ _get_ident(); return (T_IDENT); }
186 {WILDCARD}			{ _get_ident(); return (T_WILDCARD); }
187 "\n"				{ lineno++; }
188 [ \t]				/* Ignore whitespaces. */
189 
190 %%
191 
192 static void
193 _calc_num(void)
194 {
195 	int base, mul;
196 
197 	base = 0;
198 	mul = 1;
199 	switch (yytext[yyleng - 1]) {
200 	case 'd': case 'D':
201 		base = 10;
202 		break;
203 	case 'o': case 'O':
204 		base = 8;
205 		break;
206 	case 'h': case 'H':
207 		base = 16;
208 		break;
209 	case 'k': case 'K':
210 		mul = 1024;
211 		break;
212 	case 'm': case 'M':
213 		mul = 1024 * 1024;
214 		break;
215 	default:
216 		break;
217 	}
218 
219 	if (base || mul > 1)
220 		yytext[yyleng - 1] = '\0';
221 
222 	yylval.num = strtoimax(yytext, NULL, base);
223 	yylval.num *= mul;
224 }
225 
226 static void
227 _get_ident(void)
228 {
229 
230 	yylval.str = strdup(yytext);
231 	if (yylval.str == NULL)
232 		err(1, "strdup");
233 }
234 
235 static void
236 _get_string(void)
237 {
238 
239 	yytext[yyleng - 1] = '\0';
240 	yylval.str = strdup(yytext + 1);
241 	if (yylval.str == NULL)
242 		err(1, "strdup");
243 }
244 
245 static void
246 _skip_comment(void)
247 {
248 	int c;
249 
250 	for (;;) {
251 		while ((c = input()) != '*' && c != EOF)
252 			if (c == '\n')
253 				lineno++;
254 		if (c == '*') {
255 			while ((c = input()) == '*')
256 				;
257 			if (c == '\n')
258 				lineno++;
259 			if (c == '/')
260 				break;
261 		}
262 		if (c == EOF)
263 			errx(1, "lexer: EOF in comment");
264 	}
265 }
266