mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 02:32:06 +00:00
Prevent non-reloc symbol from shadowing reloc symbol
This commit is contained in:
@@ -38,6 +38,8 @@ struct sSymbol {
|
|||||||
#define SYMF_SET 0x004
|
#define SYMF_SET 0x004
|
||||||
/* Symbol should be exported */
|
/* Symbol should be exported */
|
||||||
#define SYMF_EXPORT 0x008
|
#define SYMF_EXPORT 0x008
|
||||||
|
/* Symbol referenced in RPN expression */
|
||||||
|
#define SYMF_REF 0x010
|
||||||
/* Symbol is a local symbol */
|
/* Symbol is a local symbol */
|
||||||
#define SYMF_LOCAL 0x020
|
#define SYMF_LOCAL 0x020
|
||||||
/* Symbol has been defined, not only referenced */
|
/* Symbol has been defined, not only referenced */
|
||||||
@@ -74,7 +76,7 @@ void sym_UseCurrentMacroArgs(void);
|
|||||||
void sym_SetMacroArgID(uint32_t nMacroCount);
|
void sym_SetMacroArgID(uint32_t nMacroCount);
|
||||||
uint32_t sym_isString(char *tzSym);
|
uint32_t sym_isString(char *tzSym);
|
||||||
void sym_AddMacro(char *tzSym);
|
void sym_AddMacro(char *tzSym);
|
||||||
void sym_AddForwardRef(char *tzSym);
|
void sym_Ref(char *tzSym);
|
||||||
void sym_ShiftCurrentMacroArgs(void);
|
void sym_ShiftCurrentMacroArgs(void);
|
||||||
void sym_AddString(char *tzSym, char *tzValue);
|
void sym_AddString(char *tzSym, char *tzValue);
|
||||||
uint32_t sym_GetDefinedValue(char *s);
|
uint32_t sym_GetDefinedValue(char *s);
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ void rpn_Symbol(struct Expression *expr, char *tzSym)
|
|||||||
{
|
{
|
||||||
if (!sym_isConstant(tzSym)) {
|
if (!sym_isConstant(tzSym)) {
|
||||||
rpn_Init(expr);
|
rpn_Init(expr);
|
||||||
sym_AddForwardRef(tzSym);
|
sym_Ref(tzSym);
|
||||||
expr->isReloc = 1;
|
expr->isReloc = 1;
|
||||||
pushbyte(expr, RPN_SYM);
|
pushbyte(expr, RPN_SYM);
|
||||||
while (*tzSym)
|
while (*tzSym)
|
||||||
@@ -172,7 +172,7 @@ void rpn_BankSymbol(struct Expression *expr, char *tzSym)
|
|||||||
|
|
||||||
if (!sym_isConstant(tzSym)) {
|
if (!sym_isConstant(tzSym)) {
|
||||||
rpn_Init(expr);
|
rpn_Init(expr);
|
||||||
sym_AddForwardRef(tzSym);
|
sym_Ref(tzSym);
|
||||||
expr->isReloc = 1;
|
expr->isReloc = 1;
|
||||||
pushbyte(expr, RPN_BANK_SYM);
|
pushbyte(expr, RPN_BANK_SYM);
|
||||||
while (*tzSym)
|
while (*tzSym)
|
||||||
|
|||||||
@@ -460,21 +460,36 @@ struct sSymbol *sym_FindMacro(char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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);
|
struct sSymbol *nsym = findsymbol(tzSym, NULL);
|
||||||
|
|
||||||
if (nsym != NULL) {
|
if (nsym != NULL) {
|
||||||
if (nsym->nType & SYMF_DEFINED) {
|
if (nsym->nType & SYMF_DEFINED) {
|
||||||
yyerror("'%s' already defined in %s(%d)", tzSym,
|
yyerror("'%s' already defined at %s(%u)",
|
||||||
nsym->tzFileName, nsym->nFileLine);
|
tzSym, nsym->tzFileName, nsym->nFileLine);
|
||||||
|
} else if (nsym->nType & SYMF_REF) {
|
||||||
|
yyerror("'%s' already referenced at %s(%u)",
|
||||||
|
tzSym, nsym->tzFileName, nsym->nFileLine);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nsym = createsymbol(tzSym);
|
nsym = createsymbol(tzSym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nsym;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an equated symbol
|
||||||
|
*/
|
||||||
|
void sym_AddEqu(char *tzSym, int32_t value)
|
||||||
|
{
|
||||||
|
struct sSymbol *nsym = createNonrelocSymbol(tzSym);
|
||||||
|
|
||||||
if (nsym) {
|
if (nsym) {
|
||||||
nsym->nValue = value;
|
nsym->nValue = value;
|
||||||
nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
|
nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST;
|
||||||
@@ -498,16 +513,7 @@ void sym_AddEqu(char *tzSym, int32_t value)
|
|||||||
*/
|
*/
|
||||||
void sym_AddString(char *tzSym, char *tzValue)
|
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) {
|
if (nsym) {
|
||||||
nsym->pMacro = malloc(strlen(tzValue) + 1);
|
nsym->pMacro = malloc(strlen(tzValue) + 1);
|
||||||
@@ -530,11 +536,7 @@ uint32_t sym_isString(char *tzSym)
|
|||||||
{
|
{
|
||||||
const struct sSymbol *pSym = findsymbol(tzSym, NULL);
|
const struct sSymbol *pSym = findsymbol(tzSym, NULL);
|
||||||
|
|
||||||
if (pSym != NULL) {
|
return (pSym && (pSym->nType & SYMF_STRING));
|
||||||
if (pSym->nType & SYMF_STRING)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -544,8 +546,20 @@ void sym_AddSet(char *tzSym, int32_t value)
|
|||||||
{
|
{
|
||||||
struct sSymbol *nsym = findsymbol(tzSym, NULL);
|
struct sSymbol *nsym = findsymbol(tzSym, NULL);
|
||||||
|
|
||||||
if (nsym == NULL) {
|
if (nsym != NULL) {
|
||||||
/* Symbol hasn been found, create */
|
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);
|
nsym = createsymbol(tzSym);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,19 +711,7 @@ void sym_Export(char *tzSym)
|
|||||||
*/
|
*/
|
||||||
void sym_AddMacro(char *tzSym)
|
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) {
|
if (nsym) {
|
||||||
nsym->nValue = nPC;
|
nsym->nValue = nPC;
|
||||||
@@ -722,11 +724,14 @@ void sym_AddMacro(char *tzSym)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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];
|
char fullname[MAXSYMLEN + 1];
|
||||||
int isLocal = 0;
|
int isLocal = 0;
|
||||||
|
|
||||||
@@ -737,15 +742,18 @@ void sym_AddForwardRef(char *tzSym)
|
|||||||
isLocal = 1;
|
isLocal = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sSymbol *nsym = createsymbol(tzSym);
|
nsym = createsymbol(tzSym);
|
||||||
|
|
||||||
if (nsym && isLocal)
|
if (nsym && isLocal)
|
||||||
nsym->nType |= SYMF_LOCAL;
|
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)
|
void sym_SetExportAll(uint8_t set)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user