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:
AntonioND
2017-04-04 21:21:23 +01:00
parent 2abdc9c59d
commit e63e801e9c
3 changed files with 51 additions and 2 deletions

View File

@@ -619,6 +619,49 @@ sym_AddReloc(char *tzSym)
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
*/