TokNode* TokRoot; /* Root of token list */
TokNode* TokLast; /* Pointer to last token in list */
unsigned char Style; /* Macro style */
+ unsigned char Incomplete; /* Macro is currently built */
StrBuf Name; /* Macro name, dynamically allocated */
};
unsigned LISlot; /* Slot for additional line infos */
};
+/* Maximum number of nested macro expansions */
+#define MAX_MACEXPANSIONS 256U
+
/* Number of active macro expansions */
static unsigned MacExpansions = 0;
M->TokRoot = 0;
M->TokLast = 0;
M->Style = Style;
+ M->Incomplete = 1;
SB_Init (&M->Name);
SB_Copy (&M->Name, Name);
NextTok ();
}
+ /* Reset the Incomplete flag now that parsing is done */
+ M->Incomplete = 0;
+
Done:
/* Switch out of raw token mode */
LeaveRawTokenMode ();
token_t Term;
- /* Create a structure holding expansion data. This must be done before
+ /* Create a structure holding expansion data. This must be done before
* skipping the macro name, because the call to NextTok may cause a new
* expansion if the next token is actually a .define style macro.
*/
Macro* M = HT_FindEntry (&MacroTab, &CurTok.SVal);
CHECK (M != 0);
+ /* We cannot expand an incomplete macro */
+ if (M->Incomplete) {
+ Error ("Cannot expand an incomplete macro");
+ return;
+ }
+
+ /* Don't allow too many nested macro expansions - otherwise it is possible
+ * to force an endless loop and assembler crash.
+ */
+ if (MacExpansions >= MAX_MACEXPANSIONS) {
+ Error ("Too many nested macro expansions");
+ return;
+ }
+
/* Call the apropriate subroutine */
switch (M->Style) {
case MAC_STYLE_CLASSIC: StartExpClassic (M); break;