Make RGBDS behave identically whether writing a .o

Some errors are only tripped in `out_WriteObject`, which was
basically a stub when `-o` wasn't specified. Now, instead,
errors are checked in a separate function before out_WriteFile
This commit is contained in:
ISSOtm
2019-08-30 22:06:41 +02:00
parent 631910bd67
commit b44f5825a5
3 changed files with 36 additions and 17 deletions

View File

@@ -40,6 +40,7 @@ void out_AbsByteGroup(char *s, int32_t length);
void out_RelByte(struct Expression *expr); void out_RelByte(struct Expression *expr);
void out_RelWord(struct Expression *expr); void out_RelWord(struct Expression *expr);
void out_PCRelByte(struct Expression *expr); void out_PCRelByte(struct Expression *expr);
void out_CheckErrors(void);
void out_WriteObject(void); void out_WriteObject(void);
void out_Skip(int32_t skip); void out_Skip(int32_t skip);
void out_BinaryFile(char *s); void out_BinaryFile(char *s);

View File

@@ -477,6 +477,10 @@ int main(int argc, char *argv[])
printf("(%d lines/minute)\n", printf("(%d lines/minute)\n",
(int)(60 / timespent * nTotalLines)); (int)(60 / timespent * nTotalLines));
} }
out_WriteObject();
out_CheckErrors();
/* If no path specified, don't write file */
if (tzObjectname != NULL)
out_WriteObject();
return 0; return 0;
} }

View File

@@ -265,15 +265,6 @@ static void writesymbol(struct sSymbol *pSym, FILE *f)
int32_t sectid; int32_t sectid;
if (!(pSym->nType & SYMF_DEFINED)) { if (!(pSym->nType & SYMF_DEFINED)) {
if (pSym->nType & SYMF_LOCAL) {
char *name = pSym->tzName;
char *localPtr = strchr(name, '.');
if (localPtr)
name = localPtr;
errx(1, "%s(%u) : '%s' not defined",
pSym->tzFileName, pSym->nFileLine, name);
}
type = SYM_IMPORT; type = SYM_IMPORT;
} else if (pSym->nType & SYMF_EXPORT) { } else if (pSym->nType & SYMF_EXPORT) {
type = SYM_EXPORT; type = SYM_EXPORT;
@@ -536,26 +527,49 @@ static void checksectionoverflow(uint32_t delta_size)
} }
} }
/*
* Check for errors that could happen while writing an object file
* This is important as out_WriteObject is skipped entirely when `-o` is omitted
* Therefore, errors such as memory allocations still should be handled in
* out_WriteObject and not here
*/
void out_CheckErrors(void)
{
/* Local symbols cannot be imported from elsewhere */
struct PatchSymbol *pSym = pPatchSymbols;
while (pSym) {
struct sSymbol *pSymbol = pSym->pSymbol;
if (!(pSymbol->nType & SYMF_DEFINED)
&& pSymbol->nType & SYMF_LOCAL) {
char *name = pSymbol->tzName;
char *localPtr = strchr(name, '.');
if (localPtr)
name = localPtr;
errx(1, "%s(%u) : '%s' not defined",
pSymbol->tzFileName, pSymbol->nFileLine, name);
}
pSym = pSym->pNext;
}
}
/* /*
* Write an objectfile * Write an objectfile
*/ */
void out_WriteObject(void) void out_WriteObject(void)
{ {
FILE *f; FILE *f;
struct PatchSymbol *pSym;
struct Section *pSect;
addexports(); addexports();
/* If no path specified, don't write file */
if (tzObjectname == NULL)
return;
f = fopen(tzObjectname, "wb"); f = fopen(tzObjectname, "wb");
if (f == NULL) if (f == NULL)
fatalerror("Couldn't write file '%s'\n", tzObjectname); fatalerror("Couldn't write file '%s'\n", tzObjectname);
struct PatchSymbol *pSym;
struct Section *pSect;
fwrite(RGBDS_OBJECT_VERSION_STRING, 1, fwrite(RGBDS_OBJECT_VERSION_STRING, 1,
strlen(RGBDS_OBJECT_VERSION_STRING), f); strlen(RGBDS_OBJECT_VERSION_STRING), f);