shithub: rgbds

Download patch

ref: 249acace08d76c34b19b2340f6210bf2146574a1
parent: 021990b8e0c3c05684b3b46595741a146367c0a4
author: dbrotz <43593771+dbrotz@users.noreply.github.com>
date: Thu May 9 08:48:10 EDT 2019

Prevent non-reloc symbol from shadowing reloc symbol

--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -38,6 +38,8 @@
 #define SYMF_SET	0x004
 /* Symbol should be exported */
 #define SYMF_EXPORT	0x008
+/* Symbol referenced in RPN expression */
+#define SYMF_REF	0x010
 /* Symbol is a local symbol */
 #define SYMF_LOCAL	0x020
 /* Symbol has been defined, not only referenced */
@@ -74,7 +76,7 @@
 void sym_SetMacroArgID(uint32_t nMacroCount);
 uint32_t sym_isString(char *tzSym);
 void sym_AddMacro(char *tzSym);
-void sym_AddForwardRef(char *tzSym);
+void sym_Ref(char *tzSym);
 void sym_ShiftCurrentMacroArgs(void);
 void sym_AddString(char *tzSym, char *tzValue);
 uint32_t sym_GetDefinedValue(char *s);
--- a/src/asm/rpn.c
+++ b/src/asm/rpn.c
@@ -138,7 +138,7 @@
 {
 	if (!sym_isConstant(tzSym)) {
 		rpn_Init(expr);
-		sym_AddForwardRef(tzSym);
+		sym_Ref(tzSym);
 		expr->isReloc = 1;
 		pushbyte(expr, RPN_SYM);
 		while (*tzSym)
@@ -172,7 +172,7 @@
 
 	if (!sym_isConstant(tzSym)) {
 		rpn_Init(expr);
-		sym_AddForwardRef(tzSym);
+		sym_Ref(tzSym);
 		expr->isReloc = 1;
 		pushbyte(expr, RPN_BANK_SYM);
 		while (*tzSym)
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -460,21 +460,36 @@
 }
 
 /*
- * Add an equated symbol
+ * Create a symbol that will be non-relocatable and ensure that it
+ * hasn't already been defined or referenced in a context that would
+ * require that it be relocatable
  */
-void sym_AddEqu(char *tzSym, int32_t value)
+static struct sSymbol *createNonrelocSymbol(char *tzSym)
 {
 	struct sSymbol *nsym = findsymbol(tzSym, NULL);
 
 	if (nsym != NULL) {
 		if (nsym->nType & SYMF_DEFINED) {
-			yyerror("'%s' already defined in %s(%d)", tzSym,
-				nsym->tzFileName, nsym->nFileLine);
+			yyerror("'%s' already defined at %s(%u)",
+				tzSym, nsym->tzFileName, nsym->nFileLine);
+		} else if (nsym->nType & SYMF_REF) {
+			yyerror("'%s' already referenced at %s(%u)",
+				tzSym, nsym->tzFileName, nsym->nFileLine);
 		}
 	} else {
 		nsym = createsymbol(tzSym);
 	}
 
+	return nsym;
+}
+
+/*
+ * Add an equated symbol
+ */
+void sym_AddEqu(char *tzSym, int32_t value)
+{
+	struct sSymbol *nsym = createNonrelocSymbol(tzSym);
+
 	if (nsym) {
 		nsym->nValue = value;
 		nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
@@ -498,17 +513,8 @@
  */
 void sym_AddString(char *tzSym, char *tzValue)
 {
-	struct sSymbol *nsym = findsymbol(tzSym, NULL);
+	struct sSymbol *nsym = createNonrelocSymbol(tzSym);
 
-	if (nsym != NULL) {
-		if (nsym->nType & SYMF_DEFINED) {
-			yyerror("'%s' already defined in %s(%d)",
-				tzSym, nsym->tzFileName, nsym->nFileLine);
-		}
-	} else {
-		nsym = createsymbol(tzSym);
-	}
-
 	if (nsym) {
 		nsym->pMacro = malloc(strlen(tzValue) + 1);
 
@@ -515,7 +521,7 @@
 		if (nsym->pMacro != NULL)
 			strcpy(nsym->pMacro, tzValue);
 		else
-			fatalerror("No memory for stringequate");
+			fatalerror("No memory for string equate");
 
 		nsym->nType |= SYMF_STRING | SYMF_DEFINED;
 		nsym->ulMacroSize = strlen(tzValue);
@@ -530,11 +536,7 @@
 {
 	const struct sSymbol *pSym = findsymbol(tzSym, NULL);
 
-	if (pSym != NULL) {
-		if (pSym->nType & SYMF_STRING)
-			return 1;
-	}
-	return 0;
+	return (pSym && (pSym->nType & SYMF_STRING));
 }
 
 /*
@@ -544,8 +546,20 @@
 {
 	struct sSymbol *nsym = findsymbol(tzSym, NULL);
 
-	if (nsym == NULL) {
-		/* Symbol hasn been found, create */
+	if (nsym != NULL) {
+		if (nsym->nType & SYMF_DEFINED) {
+			if (!(nsym->nType & SYMF_CONST))
+				yyerror("'%s' already defined as non-constant at %s(%u)",
+					tzSym,
+					nsym->tzFileName,
+					nsym->nFileLine);
+		} else if (nsym->nType & SYMF_REF) {
+			yyerror("'%s' already referenced at %s(%u)",
+				tzSym,
+				nsym->tzFileName,
+				nsym->nFileLine);
+		}
+	} else {
 		nsym = createsymbol(tzSym);
 	}
 
@@ -697,20 +711,8 @@
  */
 void sym_AddMacro(char *tzSym)
 {
-	struct sSymbol *nsym;
+	struct sSymbol *nsym = createNonrelocSymbol(tzSym);
 
-	nsym = findsymbol(tzSym, NULL);
-
-	if (nsym != NULL) {
-		if (nsym->nType & SYMF_DEFINED) {
-			yyerror("'%s' already defined in %s(%d)",
-				tzSym, nsym->tzFileName,
-				nsym->nFileLine);
-		}
-	} else {
-		nsym = createsymbol(tzSym);
-	}
-
 	if (nsym) {
 		nsym->nValue = nPC;
 		nsym->nType |= SYMF_MACRO | SYMF_DEFINED;
@@ -722,11 +724,14 @@
 }
 
 /*
- * Add a symbol that is being referenced ahead of its definition
+ * Flag that a symbol is referenced in an RPN expression
+ * and create it if it doesn't exist yet
  */
-void sym_AddForwardRef(char *tzSym)
+void sym_Ref(char *tzSym)
 {
-	if (sym_FindSymbol(tzSym) == NULL) {
+	struct sSymbol *nsym = sym_FindSymbol(tzSym);
+
+	if (nsym == NULL) {
 		char fullname[MAXSYMLEN + 1];
 		int isLocal = 0;
 
@@ -737,15 +742,18 @@
 			isLocal = 1;
 		}
 
-		struct sSymbol *nsym = createsymbol(tzSym);
+		nsym = createsymbol(tzSym);
 
 		if (nsym && isLocal)
 			nsym->nType |= SYMF_LOCAL;
 	}
+
+	if (nsym)
+		nsym->nType |= SYMF_REF;
 }
 
 /*
- * Set whether to export all relocable symbols by default
+ * Set whether to export all relocatable symbols by default
  */
 void sym_SetExportAll(uint8_t set)
 {