summaryrefslogtreecommitdiff
path: root/ld/ld_script_lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ld_script_lexer.l')
-rw-r--r--ld/ld_script_lexer.l264
1 files changed, 264 insertions, 0 deletions
diff --git a/ld/ld_script_lexer.l b/ld/ld_script_lexer.l
new file mode 100644
index 0000000000000..4a8ff9a2fdf6e
--- /dev/null
+++ b/ld/ld_script_lexer.l
@@ -0,0 +1,264 @@
+%{
+/*-
+ * Copyright (c) 2010-2013 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ld.h"
+#include "y.tab.h"
+
+ELFTC_VCSID("$Id: ld_script_lexer.l 2875 2013-01-09 22:46:03Z kaiwang27 $");
+
+#define YY_NO_UNPUT
+int lineno = 1;
+
+int yylex(void);
+
+static void _calc_num(void);
+static void _get_string(void);
+static void _get_ident(void);
+static void _skip_comment(void);
+
+%}
+
+DEC [0-9]+[kKmMdD]?
+OCT (0[0-7]*+[kKmM]?)|([0-7]+[oO])
+HEX (0[xX][0-9a-fA-F]+[kKmMhH]?)|([0-9a-fA-F]+[hH])
+IDENT [-_A-Za-z/:$.\\~][-_A-Za-z/:$.\\~0-9]*
+WILDCARD [-_A-Za-z/:$.\\~0-9\[\]?*]+
+MATTR \(!?[rRwWxXaAiIlL]+\)
+
+%option noyywrap
+%option never-interactive
+
+%%
+
+ABSOLUTE { return (T_ABSOLUTE); }
+ADDR { return (T_ADDR); }
+ALIGN { return (T_ALIGN); }
+ALIGNOF { return (T_ALIGNOF); }
+ASSERT { return (T_ASSERT); }
+AS_NEEDED { return (T_AS_NEEDED); }
+AT { return (T_AT); }
+BIND { return (T_BIND); }
+BLOCK { return (T_BLOCK); }
+BYTE { return (T_BYTE); }
+COMMONPAGESIZE { _get_ident(); return (T_COMMONPAGESIZE); }
+CONSTANT { return (T_CONSTANT); }
+CONSTRUCTORS { return (T_CONSTRUCTORS); }
+COPY { return (T_COPY); }
+CREATE_OBJECT_SYMBOLS { return (T_CREATE_OBJECT_SYMBOLS); }
+DATA_SEGMENT_ALIGN { return (T_DATA_SEGMENT_ALIGN); }
+DATA_SEGMENT_END { return (T_DATA_SEGMENT_END); }
+DATA_SEGMENT_RELRO_END { return (T_DATA_SEGMENT_RELRO_END); }
+DEFINED { return (T_DEFINED); }
+DSECT { return (T_DSECT); }
+ENTRY { return (T_ENTRY); }
+EXCLUDE_FILE { return (T_EXCLUDE_FILE); }
+EXTERN { return (T_EXTERN); }
+FILEHDR { return (T_FILEHDR); }
+FILL { return (T_FILL); }
+FLAGS { return (T_FLAGS); }
+FLOAT { return (T_FLOAT); }
+FORCE_COMMON_ALLOCATION { return (T_FORCE_COMMON_ALLOCATION); }
+GROUP { return (T_GROUP); }
+HLL { return (T_HLL); }
+INCLUDE { return (T_INCLUDE); }
+INFO { return (T_INFO); }
+INHIBIT_COMMON_ALLOCATION { return (T_INHIBIT_COMMON_ALLOCATION); }
+INPUT { return (T_INPUT); }
+KEEP { return (T_KEEP); }
+LENGTH { return (T_LENGTH); }
+LOADADDR { return (T_LOADADDR); }
+LONG { return (T_LONG); }
+MAP { return (T_MAP); }
+MAX { return (T_MAX); }
+MAXPAGESIZE { _get_ident(); return (T_MAXPAGESIZE); }
+MEMORY { return (T_MEMORY); }
+MIN { return (T_MIN); }
+NEXT { return (T_NEXT); }
+NOCROSSREFS { return (T_NOCROSSREFS); }
+NOFLOAT { return (T_NOFLOAT); }
+NOLOAD { return (T_NOLOAD); }
+ONLY_IF_RO { return (T_ONLY_IF_RO); }
+ONLY_IF_RW { return (T_ONLY_IF_RW); }
+OPTION { return (T_OPTION); }
+ORIGIN { return (T_ORIGIN); }
+OUTPUT { return (T_OUTPUT); }
+OUTPUT_ARCH { return (T_OUTPUT_ARCH); }
+OUTPUT_FORMAT { return (T_OUTPUT_FORMAT); }
+OVERLAY { return (T_OVERLAY); }
+PHDRS { return (T_PHDRS); }
+PROVIDE { return (T_PROVIDE); }
+PROVIDE_HIDDEN { return (T_PROVIDE_HIDDEN); }
+QUAD { return (T_QUAD); }
+REGION_ALIAS { return (T_REGION_ALIAS); }
+SEARCH_DIR { return (T_SEARCH_DIR); }
+SECTIONS { return (T_SECTIONS); }
+SEGMENT_START { return (T_SEGMENT_START); }
+SHORT { return (T_SHORT); }
+SIZEOF { return (T_SIZEOF); }
+SIZEOF_HEADERS { return (T_SIZEOF_HEADERS); }
+SORT { return (T_SORT_BY_NAME); }
+SORT_BY_ALIGNMENT { return (T_SORT_BY_ALIGNMENT); }
+SORT_BY_NAME { return (T_SORT_BY_NAME); }
+SPECIAL { return (T_SPECIAL); }
+SQUAD { return (T_SQUAD); }
+STARTUP { return (T_STARTUP); }
+SUBALIGN { return (T_SUBALIGN); }
+SYSLIB { return (T_SYSLIB); }
+TARGET { return (T_TARGET); }
+TRUNCATE { return (T_TRUNCATE); }
+extern { return (T_VER_EXTERN); }
+global: { return (T_VER_GLOBAL); }
+l { return (T_LENGTH); }
+len { return (T_LENGTH); }
+local: { return (T_VER_LOCAL); }
+o { return (T_ORIGIN); }
+org { return (T_ORIGIN); }
+sizeof_headers { return (T_SIZEOF_HEADERS); }
+"/*" { _skip_comment(); }
+"\""[^\"]+"\"" { _get_string(); return (T_STRING); }
+{DEC}|{OCT}|{HEX} { _calc_num(); return (T_NUM); }
+"<<=" { return (T_LSHIFT_E); }
+">>=" { return (T_RSHIFT_E); }
+"<<" { return (T_LSHIFT); }
+">>" { return (T_RSHIFT); }
+"==" { return (T_EQ); }
+"!=" { return (T_NE); }
+">=" { return (T_GE); }
+"<=" { return (T_LE); }
+"+=" { return (T_ADD_E); }
+"-=" { return (T_SUB_E); }
+"*=" { return (T_MUL_E); }
+"/=" { return (T_DIV_E); }
+"&=" { return (T_AND_E); }
+"|=" { return (T_OR_E); }
+"&&" { return (T_LOGICAL_AND); }
+"||" { return (T_LOGICAL_OR); }
+"!" { return ('!'); }
+"{" { return ('{'); }
+"}" { return ('}'); }
+"[" { return ('['); }
+"]" { return (']'); }
+"(" { return ('('); }
+")" { return (')'); }
+"?" { return ('?'); }
+":" { return (':'); }
+";" { return (';'); }
+"&" { return ('&'); }
+"|" { return ('|'); }
+"~" { return ('~'); }
+"+" { return ('+'); }
+"-" { return ('-'); }
+"*" { return ('*'); }
+"/" { return ('/'); }
+"%" { return ('%'); }
+"=" { return ('='); }
+"<" { return ('<'); }
+">" { return ('>'); }
+"," { return (','); }
+"." { return ('.'); }
+{MATTR} { _get_ident(); return (T_MEMORY_ATTR); }
+{IDENT} { _get_ident(); return (T_IDENT); }
+{WILDCARD} { _get_ident(); return (T_WILDCARD); }
+"\n" { lineno++; }
+[ \t] /* Ignore whitespaces. */
+
+%%
+
+static void
+_calc_num(void)
+{
+ int base, mul;
+
+ base = 0;
+ mul = 1;
+ switch (yytext[yyleng - 1]) {
+ case 'd': case 'D':
+ base = 10;
+ break;
+ case 'o': case 'O':
+ base = 8;
+ break;
+ case 'h': case 'H':
+ base = 16;
+ break;
+ case 'k': case 'K':
+ mul = 1024;
+ break;
+ case 'm': case 'M':
+ mul = 1024 * 1024;
+ break;
+ default:
+ break;
+ }
+
+ if (base || mul > 1)
+ yytext[yyleng - 1] = '\0';
+
+ yylval.num = strtoimax(yytext, NULL, base);
+ yylval.num *= mul;
+}
+
+static void
+_get_ident(void)
+{
+
+ yylval.str = strdup(yytext);
+ if (yylval.str == NULL)
+ err(1, "strdup");
+}
+
+static void
+_get_string(void)
+{
+
+ yytext[yyleng - 1] = '\0';
+ yylval.str = strdup(yytext + 1);
+ if (yylval.str == NULL)
+ err(1, "strdup");
+}
+
+static void
+_skip_comment(void)
+{
+ int c;
+
+ for (;;) {
+ while ((c = input()) != '*' && c != EOF)
+ if (c == '\n')
+ lineno++;
+ if (c == '*') {
+ while ((c = input()) == '*')
+ ;
+ if (c == '\n')
+ lineno++;
+ if (c == '/')
+ break;
+ }
+ if (c == EOF)
+ errx(1, "lexer: EOF in comment");
+ }
+}