mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Output error message if diff of labels not defined
When calculating the difference of addresses between two labels, for it to be defined, either: - Both of them must have their absolute address defined. - They belong to the same section, so their relative addresses are compatible. This patch adds a check to make sure that any other case is detected so that the programmer can correct the code. This applies to rgbasm. The difference of labels can be used, for example, as argument of DS. The linker can't resize sections, which means that the final value must be defined when creating the object file. Signed-off-by: AntonioND <antonio_nd@outlook.com>
This commit is contained in:
@@ -71,5 +71,6 @@ ULONG sym_GetDefinedValue(char *s);
|
|||||||
ULONG sym_isDefined(char *tzName);
|
ULONG sym_isDefined(char *tzName);
|
||||||
void sym_Purge(char *tzName);
|
void sym_Purge(char *tzName);
|
||||||
ULONG sym_isConstDefined(char *tzName);
|
ULONG sym_isConstDefined(char *tzName);
|
||||||
|
int sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1040,9 +1040,14 @@ const : T_ID { $$ = sym_GetConstantValue($1); }
|
|||||||
| const T_OP_LOGICNE const { $$ = $1 != $3; }
|
| const T_OP_LOGICNE const { $$ = $1 != $3; }
|
||||||
| const T_OP_ADD const { $$ = $1 + $3; }
|
| const T_OP_ADD const { $$ = $1 + $3; }
|
||||||
| const T_OP_SUB const { $$ = $1 - $3; }
|
| const T_OP_SUB const { $$ = $1 - $3; }
|
||||||
| T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); }
|
| T_ID T_OP_SUB T_ID
|
||||||
|
{
|
||||||
|
if (sym_IsRelocDiffDefined($1, $3) == 0)
|
||||||
|
fatalerror("'%s - %s' not defined.", $1, $3);
|
||||||
|
$$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3);
|
||||||
|
}
|
||||||
| const T_OP_XOR const { $$ = $1 ^ $3; }
|
| const T_OP_XOR const { $$ = $1 ^ $3; }
|
||||||
| const T_OP_OR const { $$ = $1 | $3; }
|
| const T_OP_OR const { $$ = $1 | $3; }
|
||||||
| const T_OP_AND const { $$ = $1 & $3; }
|
| const T_OP_AND const { $$ = $1 & $3; }
|
||||||
| const T_OP_SHL const { $$ = $1 << $3; }
|
| const T_OP_SHL const { $$ = $1 << $3; }
|
||||||
| const T_OP_SHR const { $$ = $1 >> $3; }
|
| const T_OP_SHR const { $$ = $1 >> $3; }
|
||||||
|
|||||||
@@ -619,6 +619,49 @@ sym_AddReloc(char *tzSym)
|
|||||||
pScope = findsymbol(tzSym, NULL);
|
pScope = findsymbol(tzSym, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the subtraction of two symbols is defined. That is, either both
|
||||||
|
* symbols are defined and the result is a constant, or both symbols are
|
||||||
|
* relocatable and belong to the same section.
|
||||||
|
*
|
||||||
|
* It returns 1 if the difference is defined, 0 if not.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2)
|
||||||
|
{
|
||||||
|
/* Do nothing the first pass. */
|
||||||
|
if (nPass != 2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
struct sSymbol *nsym1, *nsym2;
|
||||||
|
|
||||||
|
/* Do the symbols exist? */
|
||||||
|
if ((nsym1 = sym_FindSymbol(tzSym1)) == NULL)
|
||||||
|
fatalerror("Symbol \"%s\" isn't defined.", tzSym1);
|
||||||
|
if ((nsym2 = sym_FindSymbol(tzSym2)) == NULL)
|
||||||
|
fatalerror("Symbol \"%s\" isn't defined.", tzSym2);
|
||||||
|
|
||||||
|
int s1reloc = (nsym1->nType & SYMF_RELOC) != 0;
|
||||||
|
int s2reloc = (nsym2->nType & SYMF_RELOC) != 0;
|
||||||
|
|
||||||
|
/* Both are non-relocatable */
|
||||||
|
if (!s1reloc && !s2reloc) return 1;
|
||||||
|
|
||||||
|
/* One of them relocatable, the other one not. */
|
||||||
|
if (s1reloc ^ s2reloc) return 0;
|
||||||
|
|
||||||
|
/* Both of them are relocatable. Make sure they are defined (internal
|
||||||
|
* coherency with sym_AddReloc and sym_AddLocalReloc). */
|
||||||
|
if (!(nsym1->nType & SYMF_DEFINED))
|
||||||
|
fatalerror("Relocatable symbol \"%s\" isn't defined.", tzSym1);
|
||||||
|
if (!(nsym2->nType & SYMF_DEFINED))
|
||||||
|
fatalerror("Relocatable symbol \"%s\" isn't defined.", tzSym2);
|
||||||
|
|
||||||
|
/* Both of them must be in the same section for the difference to be
|
||||||
|
* defined. */
|
||||||
|
return nsym1->pSection == nsym2->pSection;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export a symbol
|
* Export a symbol
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user