14ffa0fb7SMasatake YAMATO /*
24ffa0fb7SMasatake YAMATO * Copyright (c) 2016, Masatake YAMATO
34ffa0fb7SMasatake YAMATO * Copyright (c) 2016, Red Hat, Inc.
44ffa0fb7SMasatake YAMATO *
54ffa0fb7SMasatake YAMATO * This source code is released for free distribution under the terms of the
64ffa0fb7SMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
74ffa0fb7SMasatake YAMATO *
84ffa0fb7SMasatake YAMATO * This module contains functions for generating tags for GNU linker script
94ffa0fb7SMasatake YAMATO * files.
104ffa0fb7SMasatake YAMATO */
114ffa0fb7SMasatake YAMATO
124ffa0fb7SMasatake YAMATO #include "general.h"
134ffa0fb7SMasatake YAMATO #include "tokeninfo.h"
144ffa0fb7SMasatake YAMATO
154ffa0fb7SMasatake YAMATO #include "entry.h"
1687214e15SMasatake YAMATO #include "cpreprocessor.h"
174ffa0fb7SMasatake YAMATO #include "keyword.h"
180d502ef0SMasatake YAMATO #include "parse.h"
19*d69940b7SMasatake YAMATO #include "ptrarray.h"
204ffa0fb7SMasatake YAMATO #include "read.h"
21*d69940b7SMasatake YAMATO #include "trace.h"
224ffa0fb7SMasatake YAMATO #include "xtag.h"
234ffa0fb7SMasatake YAMATO
249a4d7997SMasatake YAMATO #include <string.h>
259a4d7997SMasatake YAMATO
264ffa0fb7SMasatake YAMATO /*
274ffa0fb7SMasatake YAMATO * DATA DEFINITIONS
284ffa0fb7SMasatake YAMATO */
294ffa0fb7SMasatake YAMATO
304ffa0fb7SMasatake YAMATO typedef enum {
314ffa0fb7SMasatake YAMATO LD_SCRIPT_SYMBOL_ENTRYPOINT,
324ffa0fb7SMasatake YAMATO } ldScriptSymbolRole;
334ffa0fb7SMasatake YAMATO
3413457258SMasatake YAMATO static roleDefinition LdScriptSymbolRoles [] = {
354ffa0fb7SMasatake YAMATO { true, "entrypoint", "entry points" },
364ffa0fb7SMasatake YAMATO };
374ffa0fb7SMasatake YAMATO
384ffa0fb7SMasatake YAMATO typedef enum {
39f5b8634aSMasatake YAMATO LD_SCRIPT_INPUT_SECTION_MAPPED,
409a4d7997SMasatake YAMATO LD_SCRIPT_INPUT_SECTION_DISCARDED,
41f5b8634aSMasatake YAMATO } ldScriptInputSectionRole;
42f5b8634aSMasatake YAMATO
4313457258SMasatake YAMATO static roleDefinition LdScriptInputSectionRoles [] = {
44f5b8634aSMasatake YAMATO { true, "mapped", "mapped to output section" },
459a4d7997SMasatake YAMATO { true, "discarded", "discarded when linking" },
46f5b8634aSMasatake YAMATO };
47f5b8634aSMasatake YAMATO
48f5b8634aSMasatake YAMATO typedef enum {
49705ca28dSMasatake YAMATO K_SECTION,
50705ca28dSMasatake YAMATO K_SYMBOL,
51705ca28dSMasatake YAMATO K_VERSION,
52f5b8634aSMasatake YAMATO K_INPUT_SECTION,
534ffa0fb7SMasatake YAMATO } ldScriptKind;
544ffa0fb7SMasatake YAMATO
55e112e8abSMasatake YAMATO static kindDefinition LdScriptKinds [] = {
564ffa0fb7SMasatake YAMATO { true, 'S', "section", "sections" },
574ffa0fb7SMasatake YAMATO { true, 's', "symbol", "symbols",
584ffa0fb7SMasatake YAMATO .referenceOnly = false, ATTACH_ROLES(LdScriptSymbolRoles)},
594ffa0fb7SMasatake YAMATO { true, 'v', "version", "versions" },
60f5b8634aSMasatake YAMATO { true, 'i', "inputSection", "input sections",
61f5b8634aSMasatake YAMATO .referenceOnly = true, ATTACH_ROLES(LdScriptInputSectionRoles)},
624ffa0fb7SMasatake YAMATO };
634ffa0fb7SMasatake YAMATO
644ffa0fb7SMasatake YAMATO enum {
654ffa0fb7SMasatake YAMATO KEYWORD_ENTRY,
664ffa0fb7SMasatake YAMATO KEYWORD_SECTIONS,
674ffa0fb7SMasatake YAMATO KEYWORD_LOC,
684ffa0fb7SMasatake YAMATO KEYWORD_AT,
694ffa0fb7SMasatake YAMATO KEYWORD_VERSION,
704ffa0fb7SMasatake YAMATO KEYWORD_PROVIDE,
714ffa0fb7SMasatake YAMATO KEYWORD_PROVIDE_HIDDEN,
724ffa0fb7SMasatake YAMATO KEYWORD_HIDDEN,
73f5b8634aSMasatake YAMATO KEYWORD_EXCLUDE_FILE,
74f5b8634aSMasatake YAMATO KEYWORD_INPUT_SECTION_FLAGS,
75f5b8634aSMasatake YAMATO KEYWORD_COMMON,
76f5b8634aSMasatake YAMATO KEYWORD_KEEP,
77074f40fdSMasatake YAMATO KEYWORD_DATA,
784ffa0fb7SMasatake YAMATO };
794ffa0fb7SMasatake YAMATO typedef int keywordId; /* to allow KEYWORD_NONE */
804ffa0fb7SMasatake YAMATO
814ffa0fb7SMasatake YAMATO
824ffa0fb7SMasatake YAMATO static const keywordTable LdScriptKeywordTable[] = {
834ffa0fb7SMasatake YAMATO /* keyword keyword ID */
844ffa0fb7SMasatake YAMATO { "ENTRY", KEYWORD_ENTRY },
854ffa0fb7SMasatake YAMATO { "SECTIONS", KEYWORD_SECTIONS },
864ffa0fb7SMasatake YAMATO { ".", KEYWORD_LOC },
874ffa0fb7SMasatake YAMATO { "AT", KEYWORD_AT },
884ffa0fb7SMasatake YAMATO { "VERSION", KEYWORD_VERSION },
894ffa0fb7SMasatake YAMATO { "PROVIDE", KEYWORD_PROVIDE },
904ffa0fb7SMasatake YAMATO { "PROVIDE_HIDDEN", KEYWORD_PROVIDE_HIDDEN },
914ffa0fb7SMasatake YAMATO { "HIDDEN", KEYWORD_HIDDEN },
92f5b8634aSMasatake YAMATO { "EXCLUDE_FILE", KEYWORD_EXCLUDE_FILE },
93f5b8634aSMasatake YAMATO { "INPUT_SECTION_FLAGS", KEYWORD_INPUT_SECTION_FLAGS },
94f5b8634aSMasatake YAMATO { "COMMON", KEYWORD_COMMON },
95f5b8634aSMasatake YAMATO { "KEEP", KEYWORD_KEEP },
96074f40fdSMasatake YAMATO { "BYTE", KEYWORD_DATA },
97074f40fdSMasatake YAMATO { "SHORT", KEYWORD_DATA },
98074f40fdSMasatake YAMATO { "LONG", KEYWORD_DATA },
99074f40fdSMasatake YAMATO { "QUAD", KEYWORD_DATA },
100074f40fdSMasatake YAMATO { "SQUAD", KEYWORD_DATA },
101074f40fdSMasatake YAMATO { "FILL", KEYWORD_DATA },
1024ffa0fb7SMasatake YAMATO };
1034ffa0fb7SMasatake YAMATO
1044ffa0fb7SMasatake YAMATO enum eTokenType {
1054ffa0fb7SMasatake YAMATO /* 0..255 are the byte's value */
1064ffa0fb7SMasatake YAMATO TOKEN_EOF = 256,
1074ffa0fb7SMasatake YAMATO TOKEN_UNDEFINED,
1084ffa0fb7SMasatake YAMATO TOKEN_KEYWORD,
1094ffa0fb7SMasatake YAMATO TOKEN_IDENTIFIER,
1104ffa0fb7SMasatake YAMATO TOKEN_NUMBER,
1114ffa0fb7SMasatake YAMATO TOKEN_ASSIGNMENT_OP,
1124ffa0fb7SMasatake YAMATO TOKEN_OP,
1134ffa0fb7SMasatake YAMATO TOKEN_PHDIR,
1144ffa0fb7SMasatake YAMATO TOKEN_REGION,
1154ffa0fb7SMasatake YAMATO TOKEN_FILLEXP,
1169a4d7997SMasatake YAMATO TOKEN_DISCARD,
1174ffa0fb7SMasatake YAMATO };
1184ffa0fb7SMasatake YAMATO
1194ffa0fb7SMasatake YAMATO static void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED);
1204ffa0fb7SMasatake YAMATO static void clearToken (tokenInfo *token);
1214ffa0fb7SMasatake YAMATO static void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED);
1224ffa0fb7SMasatake YAMATO
123002dd246SMasatake YAMATO typedef struct sLdScriptToken {
124002dd246SMasatake YAMATO tokenInfo base;
1254ffa0fb7SMasatake YAMATO int scopeIndex;
1264ffa0fb7SMasatake YAMATO tokenKeyword assignment;
127*d69940b7SMasatake YAMATO bool whitespacePrefixed;
128002dd246SMasatake YAMATO } ldScriptToken;
129002dd246SMasatake YAMATO
130002dd246SMasatake YAMATO #define LDSCRIPT(TOKEN) ((ldScriptToken *)TOKEN)
1314ffa0fb7SMasatake YAMATO
1321082869bSMasatake YAMATO static struct tokenTypePair ldScriptTypePairs [] = {
1334ffa0fb7SMasatake YAMATO { '{', '}' },
1344ffa0fb7SMasatake YAMATO };
1354ffa0fb7SMasatake YAMATO
1364ffa0fb7SMasatake YAMATO static struct tokenInfoClass ldScriptTokenInfoClass = {
1374ffa0fb7SMasatake YAMATO .nPreAlloc = 4,
1384ffa0fb7SMasatake YAMATO .typeForUndefined = TOKEN_UNDEFINED,
1394ffa0fb7SMasatake YAMATO .keywordNone = KEYWORD_NONE,
1404ffa0fb7SMasatake YAMATO .typeForKeyword = TOKEN_KEYWORD,
1414ffa0fb7SMasatake YAMATO .typeForEOF = TOKEN_EOF,
142002dd246SMasatake YAMATO .extraSpace = sizeof (ldScriptToken) - sizeof (tokenInfo),
1434ffa0fb7SMasatake YAMATO .pairs = ldScriptTypePairs,
1444ffa0fb7SMasatake YAMATO .pairCount = ARRAY_SIZE (ldScriptTypePairs),
1454ffa0fb7SMasatake YAMATO .read = readToken,
1464ffa0fb7SMasatake YAMATO .clear = clearToken,
1474ffa0fb7SMasatake YAMATO .copy = copyToken,
1484ffa0fb7SMasatake YAMATO };
1494ffa0fb7SMasatake YAMATO
1504ffa0fb7SMasatake YAMATO typedef enum {
1514ffa0fb7SMasatake YAMATO F_ASSIGNMENT,
1524ffa0fb7SMasatake YAMATO COUNT_FIELD
1530f6569aeSMasatake YAMATO } ldScriptField;
1544ffa0fb7SMasatake YAMATO
155b56bd065SMasatake YAMATO static fieldDefinition LdScriptFields[COUNT_FIELD] = {
1564ffa0fb7SMasatake YAMATO { .name = "assignment",
1574ffa0fb7SMasatake YAMATO .description = "how a value is assigned to the symbol",
1584ffa0fb7SMasatake YAMATO .enabled = true },
1594ffa0fb7SMasatake YAMATO };
1604ffa0fb7SMasatake YAMATO
1614ffa0fb7SMasatake YAMATO static langType Lang_ldscript;
1624ffa0fb7SMasatake YAMATO
1634ffa0fb7SMasatake YAMATO /*
1644ffa0fb7SMasatake YAMATO * FUNCTION DEFINITIONS
1654ffa0fb7SMasatake YAMATO */
1664ffa0fb7SMasatake YAMATO
newLdScriptToken(void)1674ffa0fb7SMasatake YAMATO static tokenInfo *newLdScriptToken (void)
1684ffa0fb7SMasatake YAMATO {
1694ffa0fb7SMasatake YAMATO return newToken (&ldScriptTokenInfoClass);
1704ffa0fb7SMasatake YAMATO }
1714ffa0fb7SMasatake YAMATO
clearToken(tokenInfo * token)1724ffa0fb7SMasatake YAMATO static void clearToken (tokenInfo *token)
1734ffa0fb7SMasatake YAMATO {
174002dd246SMasatake YAMATO LDSCRIPT(token)->scopeIndex = CORK_NIL;
175002dd246SMasatake YAMATO LDSCRIPT(token)->assignment = KEYWORD_NONE;
1764ffa0fb7SMasatake YAMATO }
1774ffa0fb7SMasatake YAMATO
copyToken(tokenInfo * dest,tokenInfo * src,void * data CTAGS_ATTR_UNUSED)1784ffa0fb7SMasatake YAMATO static void copyToken (tokenInfo *dest, tokenInfo *src, void *data CTAGS_ATTR_UNUSED)
1794ffa0fb7SMasatake YAMATO {
180002dd246SMasatake YAMATO LDSCRIPT (dest)->scopeIndex =
181002dd246SMasatake YAMATO LDSCRIPT (src)->scopeIndex;
182002dd246SMasatake YAMATO LDSCRIPT (dest)->assignment =
183002dd246SMasatake YAMATO LDSCRIPT (src)->assignment;
184*d69940b7SMasatake YAMATO LDSCRIPT (dest)->whitespacePrefixed =
185*d69940b7SMasatake YAMATO LDSCRIPT (src)->whitespacePrefixed;
1864ffa0fb7SMasatake YAMATO }
1874ffa0fb7SMasatake YAMATO
makeLdScriptTagMaybe(tagEntryInfo * const e,tokenInfo * const token,int kind,int role)1884ffa0fb7SMasatake YAMATO static int makeLdScriptTagMaybe (tagEntryInfo *const e, tokenInfo *const token,
1894ffa0fb7SMasatake YAMATO int kind, int role)
1904ffa0fb7SMasatake YAMATO {
19124b256e3SMasatake YAMATO if (role == ROLE_DEFINITION_INDEX)
1924ffa0fb7SMasatake YAMATO {
1934ffa0fb7SMasatake YAMATO if (! LdScriptKinds[kind].enabled)
1944ffa0fb7SMasatake YAMATO return CORK_NIL;
1954ffa0fb7SMasatake YAMATO }
1964ffa0fb7SMasatake YAMATO else if (! (isXtagEnabled (XTAG_REFERENCE_TAGS)
1974ffa0fb7SMasatake YAMATO && LdScriptKinds[kind].roles[role].enabled))
1984ffa0fb7SMasatake YAMATO return CORK_NIL;
1994ffa0fb7SMasatake YAMATO
2002fe47fcaSMasatake YAMATO initRefTagEntry (e, tokenString (token),
20116a2541cSMasatake YAMATO kind,
2024ffa0fb7SMasatake YAMATO role);
2034ffa0fb7SMasatake YAMATO e->lineNumber = token->lineNumber;
2044ffa0fb7SMasatake YAMATO e->filePosition = token->filePosition;
205002dd246SMasatake YAMATO e->extensionFields.scopeIndex = LDSCRIPT (token)->scopeIndex;
2064ffa0fb7SMasatake YAMATO
2074ffa0fb7SMasatake YAMATO /* TODO: implement file: field. */
2084ffa0fb7SMasatake YAMATO if ((kind == K_SYMBOL)
2094ffa0fb7SMasatake YAMATO && LdScriptFields[F_ASSIGNMENT].enabled)
2104ffa0fb7SMasatake YAMATO {
211a7b49da1SColomban Wendling const char *assignment = NULL;
2124ffa0fb7SMasatake YAMATO
213002dd246SMasatake YAMATO switch (LDSCRIPT (token)->assignment)
2144ffa0fb7SMasatake YAMATO {
2154ffa0fb7SMasatake YAMATO case KEYWORD_PROVIDE:
2164ffa0fb7SMasatake YAMATO assignment = "provide";
2174ffa0fb7SMasatake YAMATO break;
2184ffa0fb7SMasatake YAMATO case KEYWORD_PROVIDE_HIDDEN:
2194ffa0fb7SMasatake YAMATO assignment = "provide_hidden";
2204ffa0fb7SMasatake YAMATO break;
2214ffa0fb7SMasatake YAMATO case KEYWORD_HIDDEN:
2224ffa0fb7SMasatake YAMATO assignment = "hidden";
2234ffa0fb7SMasatake YAMATO break;
2244ffa0fb7SMasatake YAMATO }
2254ffa0fb7SMasatake YAMATO
2264ffa0fb7SMasatake YAMATO if (assignment)
227aa4def17SMasatake YAMATO attachParserField (e, false, LdScriptFields[F_ASSIGNMENT].ftype,
2284ffa0fb7SMasatake YAMATO assignment);
2294ffa0fb7SMasatake YAMATO }
2304ffa0fb7SMasatake YAMATO
2314ffa0fb7SMasatake YAMATO return makeTagEntry (e);
2324ffa0fb7SMasatake YAMATO }
2334ffa0fb7SMasatake YAMATO
2344ffa0fb7SMasatake YAMATO #define isIdentifierChar(c) \
23597ab90c3SMasatake YAMATO (cppIsalnum (c) || (c) == '_' || (c) == '.' || (c) == '-' || (c) >= 0x80)
2364ffa0fb7SMasatake YAMATO
readPrefixedToken(tokenInfo * const token,int type)2374ffa0fb7SMasatake YAMATO static int readPrefixedToken (tokenInfo *const token, int type)
2384ffa0fb7SMasatake YAMATO {
2394ffa0fb7SMasatake YAMATO int n = 0;
2404ffa0fb7SMasatake YAMATO int c;
2414ffa0fb7SMasatake YAMATO
2424ffa0fb7SMasatake YAMATO while ((c = cppGetc()) != EOF)
2434ffa0fb7SMasatake YAMATO {
2444ffa0fb7SMasatake YAMATO if (isIdentifierChar (c))
2454ffa0fb7SMasatake YAMATO {
2464ffa0fb7SMasatake YAMATO n++;
2472fe47fcaSMasatake YAMATO tokenPutc (token, c);
2484ffa0fb7SMasatake YAMATO }
2494ffa0fb7SMasatake YAMATO else
2504ffa0fb7SMasatake YAMATO {
2514ffa0fb7SMasatake YAMATO cppUngetc (c);
2524ffa0fb7SMasatake YAMATO break;
2534ffa0fb7SMasatake YAMATO }
2544ffa0fb7SMasatake YAMATO }
2554ffa0fb7SMasatake YAMATO
2564ffa0fb7SMasatake YAMATO if (n)
2574ffa0fb7SMasatake YAMATO token->type = type;
2584ffa0fb7SMasatake YAMATO return n;
2594ffa0fb7SMasatake YAMATO }
2604ffa0fb7SMasatake YAMATO
261*d69940b7SMasatake YAMATO // We stop applying macro replacements if a macro is used so many
262*d69940b7SMasatake YAMATO // times in a recursive macro expansion.
263*d69940b7SMasatake YAMATO #define LD_SCRIPT_PARSER_MAXIMUM_MACRO_USE_COUNT 8
264*d69940b7SMasatake YAMATO
collectMacroArguments(ptrArray * args)265*d69940b7SMasatake YAMATO static bool collectMacroArguments (ptrArray *args)
266*d69940b7SMasatake YAMATO {
267*d69940b7SMasatake YAMATO vString *s = vStringNew ();
268*d69940b7SMasatake YAMATO tokenInfo *const t = newLdScriptToken ();
269*d69940b7SMasatake YAMATO int depth = 1;
270*d69940b7SMasatake YAMATO
271*d69940b7SMasatake YAMATO do
272*d69940b7SMasatake YAMATO {
273*d69940b7SMasatake YAMATO tokenRead (t);
274*d69940b7SMasatake YAMATO
275*d69940b7SMasatake YAMATO if (tokenIsType (t, EOF))
276*d69940b7SMasatake YAMATO break;
277*d69940b7SMasatake YAMATO else if (tokenIsTypeVal (t, ')'))
278*d69940b7SMasatake YAMATO {
279*d69940b7SMasatake YAMATO depth--;
280*d69940b7SMasatake YAMATO if (depth == 0)
281*d69940b7SMasatake YAMATO {
282*d69940b7SMasatake YAMATO char *cstr = vStringDeleteUnwrap (s);
283*d69940b7SMasatake YAMATO ptrArrayAdd (args, cstr);
284*d69940b7SMasatake YAMATO s = NULL;
285*d69940b7SMasatake YAMATO }
286*d69940b7SMasatake YAMATO else
287*d69940b7SMasatake YAMATO vStringCat (s, t->string);
288*d69940b7SMasatake YAMATO }
289*d69940b7SMasatake YAMATO else if (tokenIsTypeVal (t, '('))
290*d69940b7SMasatake YAMATO {
291*d69940b7SMasatake YAMATO depth++;
292*d69940b7SMasatake YAMATO vStringCat (s, t->string);
293*d69940b7SMasatake YAMATO }
294*d69940b7SMasatake YAMATO else if (tokenIsTypeVal (t, ','))
295*d69940b7SMasatake YAMATO {
296*d69940b7SMasatake YAMATO char *cstr = vStringDeleteUnwrap (s);
297*d69940b7SMasatake YAMATO ptrArrayAdd (args, cstr);
298*d69940b7SMasatake YAMATO s = vStringNew ();
299*d69940b7SMasatake YAMATO }
300*d69940b7SMasatake YAMATO else
301*d69940b7SMasatake YAMATO {
302*d69940b7SMasatake YAMATO if (LDSCRIPT(t)->whitespacePrefixed)
303*d69940b7SMasatake YAMATO vStringPut(s, ' ');
304*d69940b7SMasatake YAMATO vStringCat (s, t->string);
305*d69940b7SMasatake YAMATO }
306*d69940b7SMasatake YAMATO }
307*d69940b7SMasatake YAMATO while (depth > 0);
308*d69940b7SMasatake YAMATO
309*d69940b7SMasatake YAMATO vStringDelete (s); /* NULL is acceptable. */
310*d69940b7SMasatake YAMATO
311*d69940b7SMasatake YAMATO tokenDelete (t);
312*d69940b7SMasatake YAMATO
313*d69940b7SMasatake YAMATO if (depth > 0)
314*d69940b7SMasatake YAMATO TRACE_PRINT("unbalanced argument list");
315*d69940b7SMasatake YAMATO
316*d69940b7SMasatake YAMATO return (depth > 0)? false: true;
317*d69940b7SMasatake YAMATO }
318*d69940b7SMasatake YAMATO
expandCppMacro(cppMacroInfo * macroInfo)319*d69940b7SMasatake YAMATO static bool expandCppMacro (cppMacroInfo *macroInfo)
320*d69940b7SMasatake YAMATO {
321*d69940b7SMasatake YAMATO ptrArray *args = NULL;
322*d69940b7SMasatake YAMATO
323*d69940b7SMasatake YAMATO if (macroInfo->hasParameterList)
324*d69940b7SMasatake YAMATO {
325*d69940b7SMasatake YAMATO tokenInfo *const t = newLdScriptToken ();
326*d69940b7SMasatake YAMATO
327*d69940b7SMasatake YAMATO /* Though macro arguments are expected, they are not found. */
328*d69940b7SMasatake YAMATO tokenRead (t);
329*d69940b7SMasatake YAMATO if (!tokenIsTypeVal (t, '('))
330*d69940b7SMasatake YAMATO {
331*d69940b7SMasatake YAMATO tokenUnread (t);
332*d69940b7SMasatake YAMATO tokenDelete (t);
333*d69940b7SMasatake YAMATO TRACE_PRINT("no argument for the %s<%p>", macroInfo->name, macroInfo);
334*d69940b7SMasatake YAMATO return false;
335*d69940b7SMasatake YAMATO }
336*d69940b7SMasatake YAMATO
337*d69940b7SMasatake YAMATO args = ptrArrayNew (eFree);
338*d69940b7SMasatake YAMATO if (!collectMacroArguments (args))
339*d69940b7SMasatake YAMATO {
340*d69940b7SMasatake YAMATO ptrArrayDelete (args);
341*d69940b7SMasatake YAMATO tokenUnread (t);
342*d69940b7SMasatake YAMATO tokenDelete (t);
343*d69940b7SMasatake YAMATO return false;
344*d69940b7SMasatake YAMATO }
345*d69940b7SMasatake YAMATO tokenDelete (t);
346*d69940b7SMasatake YAMATO }
347*d69940b7SMasatake YAMATO
348*d69940b7SMasatake YAMATO #ifdef DO_TRACING
349*d69940b7SMasatake YAMATO for (int i = 0; i < ptrArrayCount(args); i++)
350*d69940b7SMasatake YAMATO TRACE_PRINT("[%d] %s", i, (const char *)ptrArrayItem (args, i));
351*d69940b7SMasatake YAMATO #endif
352*d69940b7SMasatake YAMATO
353*d69940b7SMasatake YAMATO cppBuildMacroReplacementWithPtrArrayAndUngetResult (macroInfo, args);
354*d69940b7SMasatake YAMATO
355*d69940b7SMasatake YAMATO ptrArrayDelete (args); /* NULL is acceptable. */
356*d69940b7SMasatake YAMATO return true;
357*d69940b7SMasatake YAMATO }
358*d69940b7SMasatake YAMATO
readToken(tokenInfo * const token,void * data CTAGS_ATTR_UNUSED)3594ffa0fb7SMasatake YAMATO static void readToken (tokenInfo *const token, void *data CTAGS_ATTR_UNUSED)
3604ffa0fb7SMasatake YAMATO {
3614ffa0fb7SMasatake YAMATO int c, c0, c1;
3624ffa0fb7SMasatake YAMATO
3634ffa0fb7SMasatake YAMATO token->type = TOKEN_UNDEFINED;
3644ffa0fb7SMasatake YAMATO token->keyword = KEYWORD_NONE;
3654ffa0fb7SMasatake YAMATO vStringClear (token->string);
3664ffa0fb7SMasatake YAMATO
367*d69940b7SMasatake YAMATO int prefix_count = -1;
368*d69940b7SMasatake YAMATO LDSCRIPT (token)->whitespacePrefixed = false;
3694ffa0fb7SMasatake YAMATO do {
3704ffa0fb7SMasatake YAMATO c = cppGetc();
371*d69940b7SMasatake YAMATO prefix_count++;
372*d69940b7SMasatake YAMATO if (prefix_count > 0)
373*d69940b7SMasatake YAMATO LDSCRIPT (token)->whitespacePrefixed = true;
3745fb525a6SMasatake YAMATO } while (c == ' ' || c== '\t' || c == '\f' || c == '\r' || c == '\n'
3755fb525a6SMasatake YAMATO || c == STRING_SYMBOL || c == CHAR_SYMBOL);
3764ffa0fb7SMasatake YAMATO
3774ffa0fb7SMasatake YAMATO token->lineNumber = getInputLineNumber ();
3784ffa0fb7SMasatake YAMATO token->filePosition = getInputFilePosition ();
3794ffa0fb7SMasatake YAMATO
3804ffa0fb7SMasatake YAMATO switch (c)
3814ffa0fb7SMasatake YAMATO {
3824ffa0fb7SMasatake YAMATO case EOF:
3834ffa0fb7SMasatake YAMATO token->type = TOKEN_EOF;
3844ffa0fb7SMasatake YAMATO break;
3854ffa0fb7SMasatake YAMATO case ';':
3864ffa0fb7SMasatake YAMATO case '(':
3874ffa0fb7SMasatake YAMATO case ')':
3884ffa0fb7SMasatake YAMATO case '{':
3894ffa0fb7SMasatake YAMATO case '}':
390f5b8634aSMasatake YAMATO case '[':
391f5b8634aSMasatake YAMATO case ']':
392*d69940b7SMasatake YAMATO tokenPutc(token, c);
3934ffa0fb7SMasatake YAMATO token->type = c;
3944ffa0fb7SMasatake YAMATO break;
3954ffa0fb7SMasatake YAMATO case '~':
3964ffa0fb7SMasatake YAMATO case '%':
3974ffa0fb7SMasatake YAMATO case '?':
3982fe47fcaSMasatake YAMATO tokenPutc(token, c);
3994ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4004ffa0fb7SMasatake YAMATO break;
4014ffa0fb7SMasatake YAMATO case '-':
4024ffa0fb7SMasatake YAMATO case '+':
4034ffa0fb7SMasatake YAMATO case '*':
4044ffa0fb7SMasatake YAMATO case '/': /* -,+,*,/,-=,+=,*=,/= */
4052fe47fcaSMasatake YAMATO tokenPutc(token, c);
4064ffa0fb7SMasatake YAMATO c0 = cppGetc ();
4074ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4084ffa0fb7SMasatake YAMATO if (c0 == '=')
4094ffa0fb7SMasatake YAMATO {
4102fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4114ffa0fb7SMasatake YAMATO token->type = TOKEN_ASSIGNMENT_OP;
4124ffa0fb7SMasatake YAMATO }
4139a4d7997SMasatake YAMATO else if (c == '/' && c0 == 'D')
4149a4d7997SMasatake YAMATO {
4159a4d7997SMasatake YAMATO tokenInfo *const discard = newLdScriptToken ();
4169a4d7997SMasatake YAMATO
4179a4d7997SMasatake YAMATO cppUngetc (c0);
4189a4d7997SMasatake YAMATO tokenRead (discard);
4199a4d7997SMasatake YAMATO if (tokenIsType(discard, IDENTIFIER) &&
4209a4d7997SMasatake YAMATO (strcmp(tokenString(discard), "DISCARD")) == 0)
4219a4d7997SMasatake YAMATO {
4229a4d7997SMasatake YAMATO c1 = cppGetc ();
4239a4d7997SMasatake YAMATO if (c1 == '/')
4249a4d7997SMasatake YAMATO token->type = TOKEN_DISCARD;
4259a4d7997SMasatake YAMATO else
4269a4d7997SMasatake YAMATO {
4279a4d7997SMasatake YAMATO cppUngetc (c1);
4289a4d7997SMasatake YAMATO tokenUnread (discard);
4299a4d7997SMasatake YAMATO }
4309a4d7997SMasatake YAMATO }
4319a4d7997SMasatake YAMATO else
4329a4d7997SMasatake YAMATO tokenUnread (discard);
433a203ce0eSMasatake YAMATO tokenDelete (discard);
4349a4d7997SMasatake YAMATO }
4354ffa0fb7SMasatake YAMATO else
4364ffa0fb7SMasatake YAMATO cppUngetc (c0);
4374ffa0fb7SMasatake YAMATO break;
4384ffa0fb7SMasatake YAMATO case '!': /* !, != */
4392fe47fcaSMasatake YAMATO tokenPutc(token, c);
4404ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4414ffa0fb7SMasatake YAMATO c0 = cppGetc ();
4424ffa0fb7SMasatake YAMATO if (c0 == '=')
4432fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4444ffa0fb7SMasatake YAMATO else
4454ffa0fb7SMasatake YAMATO cppUngetc (c0);
4464ffa0fb7SMasatake YAMATO case '<': /* <,<=,<<,<<= */
4472fe47fcaSMasatake YAMATO tokenPutc(token, c);
4484ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4494ffa0fb7SMasatake YAMATO c0 = cppGetc ();
4504ffa0fb7SMasatake YAMATO if (c0 == c || c0 == '=')
4514ffa0fb7SMasatake YAMATO {
4522fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4534ffa0fb7SMasatake YAMATO if (c0 == c)
4544ffa0fb7SMasatake YAMATO {
4554ffa0fb7SMasatake YAMATO c1 = cppGetc ();
4564ffa0fb7SMasatake YAMATO if (c1 == '=')
4574ffa0fb7SMasatake YAMATO {
4582fe47fcaSMasatake YAMATO tokenPutc(token, c1);
4594ffa0fb7SMasatake YAMATO token->type = TOKEN_ASSIGNMENT_OP;
4604ffa0fb7SMasatake YAMATO }
4614ffa0fb7SMasatake YAMATO else
4624ffa0fb7SMasatake YAMATO cppUngetc (c1);
4634ffa0fb7SMasatake YAMATO }
4644ffa0fb7SMasatake YAMATO }
4654ffa0fb7SMasatake YAMATO else
4664ffa0fb7SMasatake YAMATO cppUngetc (c0);
4674ffa0fb7SMasatake YAMATO case '|': /* |,||,|= */
4684ffa0fb7SMasatake YAMATO case '&': /* &,&&,&= */
4692fe47fcaSMasatake YAMATO tokenPutc(token, c);
4704ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4714ffa0fb7SMasatake YAMATO c0 = cppGetc ();
4724ffa0fb7SMasatake YAMATO if (c0 == c)
4732fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4744ffa0fb7SMasatake YAMATO else if (c0 == '=')
4754ffa0fb7SMasatake YAMATO {
4762fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4774ffa0fb7SMasatake YAMATO token->type = TOKEN_ASSIGNMENT_OP;
4784ffa0fb7SMasatake YAMATO }
4794ffa0fb7SMasatake YAMATO else
4804ffa0fb7SMasatake YAMATO cppUngetc (c0);
4814ffa0fb7SMasatake YAMATO break;
4824ffa0fb7SMasatake YAMATO case '=': /* =,== */
4832fe47fcaSMasatake YAMATO tokenPutc(token, c);
4844ffa0fb7SMasatake YAMATO if (!readPrefixedToken (token, TOKEN_FILLEXP))
4854ffa0fb7SMasatake YAMATO {
4864ffa0fb7SMasatake YAMATO c0 = cppGetc ();
4874ffa0fb7SMasatake YAMATO if (c0 == '=')
4884ffa0fb7SMasatake YAMATO {
4892fe47fcaSMasatake YAMATO tokenPutc(token, c0);
4904ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
4914ffa0fb7SMasatake YAMATO }
4924ffa0fb7SMasatake YAMATO else
4934ffa0fb7SMasatake YAMATO {
4944ffa0fb7SMasatake YAMATO cppUngetc (c0);
4954ffa0fb7SMasatake YAMATO token->type = TOKEN_ASSIGNMENT_OP;
4964ffa0fb7SMasatake YAMATO }
4974ffa0fb7SMasatake YAMATO }
4984ffa0fb7SMasatake YAMATO break;
4994ffa0fb7SMasatake YAMATO case '>': /* >,>>,>>= */
5002fe47fcaSMasatake YAMATO tokenPutc(token, c);
5014ffa0fb7SMasatake YAMATO if (!readPrefixedToken (token, TOKEN_REGION))
5024ffa0fb7SMasatake YAMATO {
5034ffa0fb7SMasatake YAMATO token->type = TOKEN_OP;
5044ffa0fb7SMasatake YAMATO c0 = cppGetc ();
5054ffa0fb7SMasatake YAMATO if (c0 == c || c0 == '=')
5064ffa0fb7SMasatake YAMATO {
5072fe47fcaSMasatake YAMATO tokenPutc(token, c0);
5084ffa0fb7SMasatake YAMATO c1 = cppGetc();
5094ffa0fb7SMasatake YAMATO if (c1 == '=')
5104ffa0fb7SMasatake YAMATO {
5112fe47fcaSMasatake YAMATO tokenPutc(token, c1);
5124ffa0fb7SMasatake YAMATO token->type = TOKEN_ASSIGNMENT_OP;
5134ffa0fb7SMasatake YAMATO }
5144ffa0fb7SMasatake YAMATO else
5154ffa0fb7SMasatake YAMATO cppUngetc (c1);
5164ffa0fb7SMasatake YAMATO }
5174ffa0fb7SMasatake YAMATO else
5184ffa0fb7SMasatake YAMATO cppUngetc (c0);
5194ffa0fb7SMasatake YAMATO }
5204ffa0fb7SMasatake YAMATO break;
5214ffa0fb7SMasatake YAMATO case ':':
5222fe47fcaSMasatake YAMATO tokenPutc(token, c);
5234ffa0fb7SMasatake YAMATO if (!readPrefixedToken (token, TOKEN_PHDIR))
5244ffa0fb7SMasatake YAMATO token->type = c;
5254ffa0fb7SMasatake YAMATO break;
5264ffa0fb7SMasatake YAMATO default:
52710c208a6SMasatake YAMATO if (cppIsdigit (c))
5284ffa0fb7SMasatake YAMATO {
52910c208a6SMasatake YAMATO /* Using cppIsdigit here is redundant.
53010c208a6SMasatake YAMATO *
53110c208a6SMasatake YAMATO * `c' never takes STRING_SYMBOL or CHAR_SYMBOL as
53210c208a6SMasatake YAMATO * its value here.
53310c208a6SMasatake YAMATO * However, the practice using cppIs... macros for the value
53410c208a6SMasatake YAMATO * returned from cppGetc() may avoid unexpected programming
53510c208a6SMasatake YAMATO * mistakes I took repeatedly.
53610c208a6SMasatake YAMATO */
5374ffa0fb7SMasatake YAMATO token->type = TOKEN_NUMBER;
5382fe47fcaSMasatake YAMATO tokenPutc(token, c);
5394ffa0fb7SMasatake YAMATO while ((c = cppGetc()))
5404ffa0fb7SMasatake YAMATO {
5414ffa0fb7SMasatake YAMATO if (isIdentifierChar (c))
5422fe47fcaSMasatake YAMATO tokenPutc(token, c);
5434ffa0fb7SMasatake YAMATO else
5444ffa0fb7SMasatake YAMATO {
5454ffa0fb7SMasatake YAMATO cppUngetc (c);
5464ffa0fb7SMasatake YAMATO break;
5474ffa0fb7SMasatake YAMATO }
5484ffa0fb7SMasatake YAMATO }
5494ffa0fb7SMasatake YAMATO }
5504ffa0fb7SMasatake YAMATO else if (isIdentifierChar(c))
5514ffa0fb7SMasatake YAMATO {
5522fe47fcaSMasatake YAMATO tokenPutc(token, c);
5534ffa0fb7SMasatake YAMATO while ((c = cppGetc()))
5544ffa0fb7SMasatake YAMATO {
5554ffa0fb7SMasatake YAMATO if (isIdentifierChar(c))
5562fe47fcaSMasatake YAMATO tokenPutc(token, c);
5574ffa0fb7SMasatake YAMATO else
5584ffa0fb7SMasatake YAMATO {
5594ffa0fb7SMasatake YAMATO cppUngetc (c);
5604ffa0fb7SMasatake YAMATO break;
5614ffa0fb7SMasatake YAMATO }
5624ffa0fb7SMasatake YAMATO }
5634ffa0fb7SMasatake YAMATO token->keyword = lookupKeyword (vStringValue (token->string), Lang_ldscript);
5644ffa0fb7SMasatake YAMATO if (token->keyword == KEYWORD_NONE)
565*d69940b7SMasatake YAMATO {
5664ffa0fb7SMasatake YAMATO token->type = TOKEN_IDENTIFIER;
567*d69940b7SMasatake YAMATO
568*d69940b7SMasatake YAMATO cppMacroInfo *macroInfo = cppFindMacro (vStringValue (token->string));
569*d69940b7SMasatake YAMATO if (macroInfo)
570*d69940b7SMasatake YAMATO {
571*d69940b7SMasatake YAMATO TRACE_PRINT("Macro expansion: %s<%p>%s", vStringValue (token->string),
572*d69940b7SMasatake YAMATO macroInfo, macroInfo->hasParameterList? "(...)": "");
573*d69940b7SMasatake YAMATO if (!(macroInfo->useCount < LD_SCRIPT_PARSER_MAXIMUM_MACRO_USE_COUNT))
574*d69940b7SMasatake YAMATO TRACE_PRINT ("Overly uesd macro %s<%p> useCount: %d (> %d)",
575*d69940b7SMasatake YAMATO vStringValue (token->string), macroInfo, macroInfo->useCount,
576*d69940b7SMasatake YAMATO LD_SCRIPT_PARSER_MAXIMUM_MACRO_USE_COUNT);
577*d69940b7SMasatake YAMATO else if (expandCppMacro (macroInfo))
578*d69940b7SMasatake YAMATO readToken (token, NULL);
579*d69940b7SMasatake YAMATO }
580*d69940b7SMasatake YAMATO }
5814ffa0fb7SMasatake YAMATO else
5824ffa0fb7SMasatake YAMATO token->type = TOKEN_KEYWORD;
5834ffa0fb7SMasatake YAMATO }
5844ffa0fb7SMasatake YAMATO else
585*d69940b7SMasatake YAMATO {
586*d69940b7SMasatake YAMATO tokenPutc(token, c);
5874ffa0fb7SMasatake YAMATO token->type = c;
588*d69940b7SMasatake YAMATO }
5894ffa0fb7SMasatake YAMATO break;
5904ffa0fb7SMasatake YAMATO }
5914ffa0fb7SMasatake YAMATO }
5924ffa0fb7SMasatake YAMATO
parseEntry(tokenInfo * const token)5934ffa0fb7SMasatake YAMATO static void parseEntry (tokenInfo *const token)
5944ffa0fb7SMasatake YAMATO {
5954ffa0fb7SMasatake YAMATO tokenRead (token);
5964ffa0fb7SMasatake YAMATO if (token->type == '(')
5974ffa0fb7SMasatake YAMATO {
5984ffa0fb7SMasatake YAMATO tokenInfo *const name = newLdScriptToken ();
5994ffa0fb7SMasatake YAMATO
6004ffa0fb7SMasatake YAMATO tokenRead (name);
601d9d9244eSMasatake YAMATO if (tokenIsType(name, IDENTIFIER))
6024ffa0fb7SMasatake YAMATO {
6034ffa0fb7SMasatake YAMATO tagEntryInfo e;
6044ffa0fb7SMasatake YAMATO
6054ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, name, K_SYMBOL, LD_SCRIPT_SYMBOL_ENTRYPOINT);
6064ffa0fb7SMasatake YAMATO tokenRead (token);
6074ffa0fb7SMasatake YAMATO tokenSkipToType (token, ')');
6084ffa0fb7SMasatake YAMATO }
609a203ce0eSMasatake YAMATO tokenDelete (name);
6104ffa0fb7SMasatake YAMATO }
6114ffa0fb7SMasatake YAMATO }
6124ffa0fb7SMasatake YAMATO
parseProvide(tokenInfo * token)6134ffa0fb7SMasatake YAMATO static void parseProvide (tokenInfo * token)
6144ffa0fb7SMasatake YAMATO {
6154ffa0fb7SMasatake YAMATO tokenKeyword p = token->keyword;
6164ffa0fb7SMasatake YAMATO
6174ffa0fb7SMasatake YAMATO if (tokenSkipToType (token, '('))
6184ffa0fb7SMasatake YAMATO {
6194ffa0fb7SMasatake YAMATO tagEntryInfo e;
6204ffa0fb7SMasatake YAMATO tokenRead (token);
621d9d9244eSMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
6224ffa0fb7SMasatake YAMATO {
623002dd246SMasatake YAMATO LDSCRIPT (token)->assignment = p;
6244ffa0fb7SMasatake YAMATO
6254ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, token,
62624b256e3SMasatake YAMATO K_SYMBOL, ROLE_DEFINITION_INDEX);
627002dd246SMasatake YAMATO LDSCRIPT (token)->assignment = KEYWORD_NONE;
6284ffa0fb7SMasatake YAMATO }
6294ffa0fb7SMasatake YAMATO tokenSkipToType (token, ')');
6304ffa0fb7SMasatake YAMATO }
6314ffa0fb7SMasatake YAMATO }
6324ffa0fb7SMasatake YAMATO
633f5b8634aSMasatake YAMATO /* An example of input sections:
634f5b8634aSMasatake YAMATO
635f5b8634aSMasatake YAMATO (.text .rdata)
636f5b8634aSMasatake YAMATO
637f5b8634aSMasatake YAMATO .text and .rtada are input sections. */
parseInputSections(tokenInfo * const token)638f5b8634aSMasatake YAMATO static void parseInputSections (tokenInfo *const token)
639f5b8634aSMasatake YAMATO {
640f5b8634aSMasatake YAMATO tagEntryInfo e;
641f5b8634aSMasatake YAMATO do {
642f5b8634aSMasatake YAMATO tokenRead (token);
643f5b8634aSMasatake YAMATO if (token->type == ')')
644f5b8634aSMasatake YAMATO break;
645f5b8634aSMasatake YAMATO else if (tokenIsType (token, IDENTIFIER))
646f5b8634aSMasatake YAMATO makeLdScriptTagMaybe (&e, token,
647f5b8634aSMasatake YAMATO K_INPUT_SECTION,
648002dd246SMasatake YAMATO LDSCRIPT(token)->scopeIndex == CORK_NIL
6499a4d7997SMasatake YAMATO ? LD_SCRIPT_INPUT_SECTION_DISCARDED
6509a4d7997SMasatake YAMATO : LD_SCRIPT_INPUT_SECTION_MAPPED);
651f5b8634aSMasatake YAMATO else if (tokenIsKeyword (token, EXCLUDE_FILE))
652f5b8634aSMasatake YAMATO tokenSkipToType (token, ')');
653f5b8634aSMasatake YAMATO } while (!tokenIsEOF (token));
654f5b8634aSMasatake YAMATO }
655f5b8634aSMasatake YAMATO
656f5b8634aSMasatake YAMATO /* Symbols and input sections are captured here.
657f5b8634aSMasatake YAMATO An example of output sections:
658f5b8634aSMasatake YAMATO
659f5b8634aSMasatake YAMATO __brk_base = .;
660f5b8634aSMasatake YAMATO . += 64 * 1024;
661f5b8634aSMasatake YAMATO *(.brk_reservation)
662f5b8634aSMasatake YAMATO __brk_limit = .;
663f5b8634aSMasatake YAMATO
664f5b8634aSMasatake YAMATO __brk_base and __brk_limit should be recorded as a symbol.
665f5b8634aSMasatake YAMATO .brk_reservationshould be recorded as an input section. */
666f5b8634aSMasatake YAMATO
parseOutputSectionCommands(tokenInfo * const token,int terminator)667f5b8634aSMasatake YAMATO static void parseOutputSectionCommands (tokenInfo *const token, int terminator)
6684ffa0fb7SMasatake YAMATO {
6694ffa0fb7SMasatake YAMATO tokenInfo *const tmp = newLdScriptToken ();
670002dd246SMasatake YAMATO int scope_index = LDSCRIPT (token)->scopeIndex;
6714ffa0fb7SMasatake YAMATO
6724ffa0fb7SMasatake YAMATO do {
6734ffa0fb7SMasatake YAMATO tokenRead (token);
674002dd246SMasatake YAMATO LDSCRIPT (token)->scopeIndex = scope_index;
6754ffa0fb7SMasatake YAMATO
676f5b8634aSMasatake YAMATO if (tokenIsKeyword (token, INPUT_SECTION_FLAGS))
677f5b8634aSMasatake YAMATO {
678f5b8634aSMasatake YAMATO tokenSkipToType (token, '(');
679f5b8634aSMasatake YAMATO tokenSkipToType (token, ')');
680f5b8634aSMasatake YAMATO }
681f5b8634aSMasatake YAMATO else if (tokenIsKeyword (token, KEEP))
682f5b8634aSMasatake YAMATO {
683f5b8634aSMasatake YAMATO tokenSkipToType (token, '(');
684f5b8634aSMasatake YAMATO parseOutputSectionCommands (token, ')');
685f5b8634aSMasatake YAMATO }
686f5b8634aSMasatake YAMATO else if (tokenIsType (token,IDENTIFIER)
687f5b8634aSMasatake YAMATO || tokenIsKeyword (token, LOC))
6884ffa0fb7SMasatake YAMATO {
6894ffa0fb7SMasatake YAMATO tagEntryInfo e;
6904ffa0fb7SMasatake YAMATO
6914ffa0fb7SMasatake YAMATO tokenRead (tmp);
692d9d9244eSMasatake YAMATO if (tokenIsType (tmp, ASSIGNMENT_OP))
6934ffa0fb7SMasatake YAMATO {
694f5b8634aSMasatake YAMATO if (! tokenIsKeyword (token, LOC))
6954ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, token,
69624b256e3SMasatake YAMATO K_SYMBOL, ROLE_DEFINITION_INDEX);
6974ffa0fb7SMasatake YAMATO tokenSkipToType (token, ';');
6984ffa0fb7SMasatake YAMATO }
699f5b8634aSMasatake YAMATO else if (tmp->type == '(')
700f5b8634aSMasatake YAMATO parseInputSections (token);
7014ffa0fb7SMasatake YAMATO else
702f5b8634aSMasatake YAMATO tokenUnread (tmp);
703f5b8634aSMasatake YAMATO }
704f5b8634aSMasatake YAMATO /* `*',`?', `[', `]' can be part of a pattern of input object file names
705f5b8634aSMasatake YAMATO as a meta character.
706f5b8634aSMasatake YAMATO `[' can enumerated here because it cannot be at the end of pattern. */
707f5b8634aSMasatake YAMATO else if ((token->type == TOKEN_OP
708f5b8634aSMasatake YAMATO && ((tokenString(token)[0] == '*')
709f5b8634aSMasatake YAMATO || (tokenString(token)[0] == '?'))
710f5b8634aSMasatake YAMATO && (tokenString(token)[1] == '\0'))
711f5b8634aSMasatake YAMATO || token->type == ']')
712f5b8634aSMasatake YAMATO {
713f5b8634aSMasatake YAMATO tokenRead (tmp);
714f5b8634aSMasatake YAMATO if (tmp->type == '(')
715f5b8634aSMasatake YAMATO parseInputSections (token);
716f5b8634aSMasatake YAMATO else
717f5b8634aSMasatake YAMATO tokenUnread (tmp);
7184ffa0fb7SMasatake YAMATO }
719d9d9244eSMasatake YAMATO else if (tokenIsKeyword (token, PROVIDE)
720d9d9244eSMasatake YAMATO || tokenIsKeyword (token, PROVIDE_HIDDEN)
721d9d9244eSMasatake YAMATO || tokenIsKeyword (token, HIDDEN))
7224ffa0fb7SMasatake YAMATO parseProvide (token);
723f5b8634aSMasatake YAMATO } while (! (tokenIsEOF (token) || token->type == terminator));
7244ffa0fb7SMasatake YAMATO
725a203ce0eSMasatake YAMATO tokenDelete (tmp);
7264ffa0fb7SMasatake YAMATO }
7274ffa0fb7SMasatake YAMATO
parseSection(tokenInfo * name)7284ffa0fb7SMasatake YAMATO static void parseSection (tokenInfo * name)
7294ffa0fb7SMasatake YAMATO {
7304ffa0fb7SMasatake YAMATO tokenInfo *const token = newLdScriptToken ();
7314ffa0fb7SMasatake YAMATO tagEntryInfo e;
7324ffa0fb7SMasatake YAMATO
7334ffa0fb7SMasatake YAMATO tokenRead (token);
7344ffa0fb7SMasatake YAMATO
735d9d9244eSMasatake YAMATO if (tokenIsType (token, ASSIGNMENT_OP))
7364ffa0fb7SMasatake YAMATO {
737d9d9244eSMasatake YAMATO if (!tokenIsKeyword (name, LOC))
7384ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, name,
73924b256e3SMasatake YAMATO K_SYMBOL, ROLE_DEFINITION_INDEX);
7404ffa0fb7SMasatake YAMATO tokenSkipToType (token, ';');
7414ffa0fb7SMasatake YAMATO }
7424ffa0fb7SMasatake YAMATO else
7434ffa0fb7SMasatake YAMATO {
7444ffa0fb7SMasatake YAMATO retry:
745d9d9244eSMasatake YAMATO if (tokenIsType (token, NUMBER))
7464ffa0fb7SMasatake YAMATO tokenSkipToType (token, ':');
747d9d9244eSMasatake YAMATO else if (tokenIsType (token, IDENTIFIER))
7484ffa0fb7SMasatake YAMATO {
7494ffa0fb7SMasatake YAMATO tokenCopy (name, token);
7504ffa0fb7SMasatake YAMATO tokenRead (token);
7514ffa0fb7SMasatake YAMATO goto retry;
7524ffa0fb7SMasatake YAMATO }
7534ffa0fb7SMasatake YAMATO else if (token->type == '(')
7544ffa0fb7SMasatake YAMATO tokenSkipToType (token, ')');
7554ffa0fb7SMasatake YAMATO
7564ffa0fb7SMasatake YAMATO if (token->type == ':')
7574ffa0fb7SMasatake YAMATO {
7584ffa0fb7SMasatake YAMATO int scope_index;
7594ffa0fb7SMasatake YAMATO
7609a4d7997SMasatake YAMATO if (tokenIsType (name, DISCARD))
7619a4d7997SMasatake YAMATO scope_index = CORK_NIL;
7629a4d7997SMasatake YAMATO else
7634ffa0fb7SMasatake YAMATO scope_index = makeLdScriptTagMaybe (&e, name,
76424b256e3SMasatake YAMATO K_SECTION, ROLE_DEFINITION_INDEX);
765f5b8634aSMasatake YAMATO
7664ffa0fb7SMasatake YAMATO if (tokenSkipToType (token, '{'))
7674ffa0fb7SMasatake YAMATO {
768002dd246SMasatake YAMATO LDSCRIPT (token)->scopeIndex = scope_index;
769f5b8634aSMasatake YAMATO parseOutputSectionCommands (token, '}');
7704ffa0fb7SMasatake YAMATO }
7714ffa0fb7SMasatake YAMATO }
7724ffa0fb7SMasatake YAMATO }
773a203ce0eSMasatake YAMATO tokenDelete (token);
7744ffa0fb7SMasatake YAMATO }
7754ffa0fb7SMasatake YAMATO
parseSections(tokenInfo * const token)7764ffa0fb7SMasatake YAMATO static void parseSections (tokenInfo *const token)
7774ffa0fb7SMasatake YAMATO {
7784ffa0fb7SMasatake YAMATO tokenRead (token);
7794ffa0fb7SMasatake YAMATO if (token->type == '{')
7804ffa0fb7SMasatake YAMATO {
7814ffa0fb7SMasatake YAMATO do {
7824ffa0fb7SMasatake YAMATO tokenRead (token);
783d9d9244eSMasatake YAMATO if (tokenIsKeyword (token, ENTRY))
7844ffa0fb7SMasatake YAMATO parseEntry (token);
785d9d9244eSMasatake YAMATO else if (tokenIsType(token, IDENTIFIER)
7869a4d7997SMasatake YAMATO || tokenIsKeyword (token, LOC)
7879a4d7997SMasatake YAMATO || tokenIsType (token, DISCARD))
7884ffa0fb7SMasatake YAMATO parseSection (token);
789d9d9244eSMasatake YAMATO else if (tokenIsKeyword (token, PROVIDE)
790d9d9244eSMasatake YAMATO || tokenIsKeyword (token, PROVIDE_HIDDEN)
791d9d9244eSMasatake YAMATO || tokenIsKeyword (token, HIDDEN))
7924ffa0fb7SMasatake YAMATO parseProvide (token);
793d9d9244eSMasatake YAMATO } while (! (tokenIsEOF (token) || token->type == '}'));
7944ffa0fb7SMasatake YAMATO }
7954ffa0fb7SMasatake YAMATO }
7964ffa0fb7SMasatake YAMATO
parseVersion(tokenInfo * const token)7974ffa0fb7SMasatake YAMATO static void parseVersion (tokenInfo *const token)
7984ffa0fb7SMasatake YAMATO {
7994ffa0fb7SMasatake YAMATO tagEntryInfo e;
8004ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, token,
80124b256e3SMasatake YAMATO K_VERSION, ROLE_DEFINITION_INDEX);
8024ffa0fb7SMasatake YAMATO
8034ffa0fb7SMasatake YAMATO if (tokenSkipToType (token, '{'))
8044ffa0fb7SMasatake YAMATO tokenSkipOverPair (token);
8054ffa0fb7SMasatake YAMATO }
8064ffa0fb7SMasatake YAMATO
parseVersions(tokenInfo * const token)8074ffa0fb7SMasatake YAMATO static void parseVersions (tokenInfo *const token)
8084ffa0fb7SMasatake YAMATO {
8094ffa0fb7SMasatake YAMATO tokenRead (token);
8104ffa0fb7SMasatake YAMATO if (token->type == '{')
8114ffa0fb7SMasatake YAMATO {
8124ffa0fb7SMasatake YAMATO do {
8134ffa0fb7SMasatake YAMATO tokenRead (token);
814d9d9244eSMasatake YAMATO if (tokenIsType(token, IDENTIFIER))
8154ffa0fb7SMasatake YAMATO parseVersion (token);
816d9d9244eSMasatake YAMATO } while (! (tokenIsEOF (token) || token->type == '}'));
8174ffa0fb7SMasatake YAMATO tokenSkipToType (token, ';');
8184ffa0fb7SMasatake YAMATO }
8194ffa0fb7SMasatake YAMATO }
8204ffa0fb7SMasatake YAMATO
findLdScriptTags(void)8214ffa0fb7SMasatake YAMATO static void findLdScriptTags (void)
8224ffa0fb7SMasatake YAMATO {
8234ffa0fb7SMasatake YAMATO tokenInfo *const token = newLdScriptToken ();
8244ffa0fb7SMasatake YAMATO tokenInfo *const tmp = newLdScriptToken ();
8254ffa0fb7SMasatake YAMATO
8264ffa0fb7SMasatake YAMATO cppInit (false, false, false, false,
827d00bddf9SMasatake YAMATO KIND_GHOST_INDEX, 0, 0,
828d00bddf9SMasatake YAMATO KIND_GHOST_INDEX,
829ee4d2ebdSMasatake YAMATO KIND_GHOST_INDEX, 0, 0,
830ee4d2ebdSMasatake YAMATO FIELD_UNKNOWN);
8314ffa0fb7SMasatake YAMATO
8324ffa0fb7SMasatake YAMATO do {
8334ffa0fb7SMasatake YAMATO tokenRead (token);
834d9d9244eSMasatake YAMATO if (tokenIsKeyword (token, ENTRY))
8354ffa0fb7SMasatake YAMATO parseEntry (token);
836d9d9244eSMasatake YAMATO else if (tokenIsKeyword (token, SECTIONS))
8374ffa0fb7SMasatake YAMATO parseSections (token);
838d9d9244eSMasatake YAMATO else if (tokenIsType(token, IDENTIFIER))
8394ffa0fb7SMasatake YAMATO {
8404ffa0fb7SMasatake YAMATO tagEntryInfo e;
8414ffa0fb7SMasatake YAMATO tokenRead (tmp);
842d9d9244eSMasatake YAMATO if (tokenIsType(tmp, ASSIGNMENT_OP))
8434ffa0fb7SMasatake YAMATO {
8444ffa0fb7SMasatake YAMATO makeLdScriptTagMaybe (&e, token,
84524b256e3SMasatake YAMATO K_SYMBOL, ROLE_DEFINITION_INDEX);
8464ffa0fb7SMasatake YAMATO tokenSkipToType (tmp, ';');
8474ffa0fb7SMasatake YAMATO }
8484ffa0fb7SMasatake YAMATO }
849d9d9244eSMasatake YAMATO else if (tokenIsKeyword (token, VERSION))
8504ffa0fb7SMasatake YAMATO parseVersions(token);
851d9d9244eSMasatake YAMATO } while (!tokenIsEOF (token));
8524ffa0fb7SMasatake YAMATO
8534ffa0fb7SMasatake YAMATO cppTerminate ();
8544ffa0fb7SMasatake YAMATO
855a203ce0eSMasatake YAMATO tokenDelete (tmp);
856a203ce0eSMasatake YAMATO tokenDelete (token);
8572438db48SMasatake YAMATO
8582438db48SMasatake YAMATO flashTokenBacklog (&ldScriptTokenInfoClass);
8594ffa0fb7SMasatake YAMATO }
8604ffa0fb7SMasatake YAMATO
initialize(const langType language)8614ffa0fb7SMasatake YAMATO static void initialize (const langType language)
8624ffa0fb7SMasatake YAMATO {
8634ffa0fb7SMasatake YAMATO Lang_ldscript = language;
8644ffa0fb7SMasatake YAMATO }
8654ffa0fb7SMasatake YAMATO
LdScriptParser(void)8664ffa0fb7SMasatake YAMATO extern parserDefinition* LdScriptParser (void)
8674ffa0fb7SMasatake YAMATO {
8684ffa0fb7SMasatake YAMATO parserDefinition* def = parserNew ("LdScript");
8694ffa0fb7SMasatake YAMATO
87056ff609aSMasatake YAMATO /* File name patters are picked from Linux kernel and ecos. */
87156ff609aSMasatake YAMATO static const char *const extensions [] = { "lds", "scr", "ld", "ldi", NULL };
8724ffa0fb7SMasatake YAMATO
87378befd79SMasatake YAMATO /* lds.S must be here because Asm parser registers .S as an extension.
87478befd79SMasatake YAMATO * ld.script is used in linux/arch/mips/boot/compressed/ld.script. */
87578befd79SMasatake YAMATO static const char *const patterns [] = { "*.lds.S", "ld.script", NULL };
8764ffa0fb7SMasatake YAMATO
8774ffa0fb7SMasatake YAMATO /* Emacs's mode */
8784ffa0fb7SMasatake YAMATO static const char *const aliases [] = { "ld-script", NULL };
8794ffa0fb7SMasatake YAMATO
8804ffa0fb7SMasatake YAMATO def->initialize = initialize;
8814ffa0fb7SMasatake YAMATO def->parser = findLdScriptTags;
8824ffa0fb7SMasatake YAMATO
88309ae690fSMasatake YAMATO def->kindTable = LdScriptKinds;
8844ffa0fb7SMasatake YAMATO def->kindCount = ARRAY_SIZE (LdScriptKinds);
8854ffa0fb7SMasatake YAMATO def->extensions = extensions;
8864ffa0fb7SMasatake YAMATO def->patterns = patterns;
8874ffa0fb7SMasatake YAMATO def->aliases = aliases;
8884ffa0fb7SMasatake YAMATO def->keywordTable = LdScriptKeywordTable;
8894ffa0fb7SMasatake YAMATO def->keywordCount = ARRAY_SIZE (LdScriptKeywordTable);
890a739fa5fSMasatake YAMATO def->fieldTable = LdScriptFields;
891a739fa5fSMasatake YAMATO def->fieldCount = ARRAY_SIZE (LdScriptFields);
8924ffa0fb7SMasatake YAMATO
893*d69940b7SMasatake YAMATO def->useCork = CORK_QUEUE|CORK_SYMTAB;
8944ffa0fb7SMasatake YAMATO
8954ffa0fb7SMasatake YAMATO return def;
8964ffa0fb7SMasatake YAMATO }
897