mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Cleanup code of rbglink
Follow Linux kernel coding style. Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Here we have the routines that read an objectfile
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -11,24 +10,23 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "extern/err.h"
|
||||
|
||||
#include "link/assign.h"
|
||||
#include "link/mylink.h"
|
||||
#include "link/main.h"
|
||||
|
||||
struct sSymbol **tSymbols;
|
||||
struct sSection *pSections = NULL;
|
||||
struct sSection *pLibSections = NULL;
|
||||
struct sSection *pSections;
|
||||
struct sSection *pLibSections;
|
||||
uint8_t dummymem;
|
||||
uint8_t oReadLib = 0;
|
||||
uint8_t oReadLib;
|
||||
|
||||
/*
|
||||
* The usual byte order stuff
|
||||
*
|
||||
* Read 32-bit values with the correct endianness
|
||||
*/
|
||||
|
||||
int32_t
|
||||
readlong(FILE * f)
|
||||
static int32_t readlong(FILE *f)
|
||||
{
|
||||
int32_t r;
|
||||
|
||||
@@ -37,26 +35,13 @@ readlong(FILE * f)
|
||||
r |= fgetc(f) << 16;
|
||||
r |= fgetc(f) << 24;
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
readword(FILE * f)
|
||||
{
|
||||
uint16_t r;
|
||||
|
||||
r = fgetc(f);
|
||||
r |= fgetc(f) << 8;
|
||||
|
||||
return (r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a NULL terminated string from a file
|
||||
*
|
||||
*/
|
||||
int32_t
|
||||
readasciiz(char **dest, FILE *f)
|
||||
int32_t readasciiz(char **dest, FILE *f)
|
||||
{
|
||||
size_t r = 0;
|
||||
|
||||
@@ -64,9 +49,8 @@ readasciiz(char **dest, FILE *f)
|
||||
char *start = malloc(bufferLength);
|
||||
char *s = start;
|
||||
|
||||
if (!s) {
|
||||
if (!s)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
while (((*s++) = fgetc(f)) != 0) {
|
||||
r += 1;
|
||||
@@ -74,9 +58,8 @@ readasciiz(char **dest, FILE *f)
|
||||
if (r >= bufferLength) {
|
||||
bufferLength *= 2;
|
||||
start = realloc(start, bufferLength);
|
||||
if (!start) {
|
||||
if (!start)
|
||||
err(1, NULL);
|
||||
}
|
||||
s = start + r;
|
||||
}
|
||||
}
|
||||
@@ -87,11 +70,8 @@ readasciiz(char **dest, FILE *f)
|
||||
|
||||
/*
|
||||
* Allocate a new section and link it into the list
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSection *
|
||||
AllocSection(void)
|
||||
struct sSection *AllocSection(void)
|
||||
{
|
||||
struct sSection **ppSections;
|
||||
|
||||
@@ -104,29 +84,26 @@ AllocSection(void)
|
||||
ppSections = &((*ppSections)->pNext);
|
||||
|
||||
*ppSections = malloc(sizeof **ppSections);
|
||||
if (!*ppSections) {
|
||||
if (!*ppSections)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
(*ppSections)->tSymbols = tSymbols;
|
||||
(*ppSections)->pNext = NULL;
|
||||
(*ppSections)->pPatches = NULL;
|
||||
(*ppSections)->oAssigned = 0;
|
||||
return *ppSections;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a symbol from a file
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSymbol *
|
||||
obj_ReadSymbol(FILE * f, char *tzObjectfile)
|
||||
struct sSymbol *obj_ReadSymbol(FILE *f, char *tzObjectfile)
|
||||
{
|
||||
struct sSymbol *pSym;
|
||||
|
||||
pSym = malloc(sizeof *pSym);
|
||||
if (!pSym) {
|
||||
pSym = malloc(sizeof(*pSym));
|
||||
if (!pSym)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
readasciiz(&pSym->pzName, f);
|
||||
pSym->Type = (enum eSymbolType)fgetc(f);
|
||||
@@ -140,19 +117,18 @@ obj_ReadSymbol(FILE * f, char *tzObjectfile)
|
||||
pSym->nSectionID = readlong(f);
|
||||
pSym->nOffset = readlong(f);
|
||||
}
|
||||
|
||||
return pSym;
|
||||
}
|
||||
|
||||
/*
|
||||
* RGB object reader routines
|
||||
*
|
||||
*/
|
||||
struct sSection *
|
||||
obj_ReadRGBSection(FILE * f)
|
||||
struct sSection *obj_ReadRGBSection(FILE *f)
|
||||
{
|
||||
struct sSection *pSection;
|
||||
|
||||
char *pzName;
|
||||
|
||||
readasciiz(&pzName, f);
|
||||
if (IsSectionNameInUse(pzName))
|
||||
errx(1, "Section name \"%s\" is already in use.", pzName);
|
||||
@@ -161,124 +137,123 @@ obj_ReadRGBSection(FILE * f)
|
||||
pSection->pzName = pzName;
|
||||
|
||||
pSection->nByteSize = readlong(f);
|
||||
pSection->Type = (enum eSectionType) fgetc(f);
|
||||
pSection->Type = (enum eSectionType)fgetc(f);
|
||||
pSection->nOrg = readlong(f);
|
||||
pSection->nBank = readlong(f);
|
||||
pSection->nAlign = readlong(f);
|
||||
|
||||
if ((options & OPT_TINY) && (pSection->Type == SECT_ROMX)) {
|
||||
if ((options & OPT_TINY) && (pSection->Type == SECT_ROMX))
|
||||
errx(1, "ROMX sections can't be used with option -t.");
|
||||
}
|
||||
if ((options & OPT_CONTWRAM) && (pSection->Type == SECT_WRAMX)) {
|
||||
|
||||
if ((options & OPT_CONTWRAM) && (pSection->Type == SECT_WRAMX))
|
||||
errx(1, "WRAMX sections can't be used with options -w or -d.");
|
||||
}
|
||||
|
||||
if (options & OPT_DMG_MODE) {
|
||||
/* WRAMX sections are checked for OPT_CONTWRAM */
|
||||
if (pSection->Type == SECT_VRAM && pSection->nBank == 1) {
|
||||
if (pSection->Type == SECT_VRAM && pSection->nBank == 1)
|
||||
errx(1, "VRAM bank 1 can't be used with option -d.");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t maxsize = 0;
|
||||
|
||||
/* Verify that the section isn't too big */
|
||||
switch (pSection->Type)
|
||||
{
|
||||
case SECT_ROM0:
|
||||
maxsize = (options & OPT_TINY) ? 0x8000 : 0x4000;
|
||||
break;
|
||||
case SECT_ROMX:
|
||||
maxsize = 0x4000;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
case SECT_SRAM:
|
||||
maxsize = 0x2000;
|
||||
break;
|
||||
case SECT_WRAM0:
|
||||
maxsize = (options & OPT_CONTWRAM) ? 0x2000 : 0x1000;
|
||||
break;
|
||||
case SECT_WRAMX:
|
||||
maxsize = 0x1000;
|
||||
break;
|
||||
case SECT_OAM:
|
||||
maxsize = 0xA0;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
maxsize = 0x7F;
|
||||
break;
|
||||
default:
|
||||
errx(1, "Section \"%s\" has an invalid section type.", pzName);
|
||||
break;
|
||||
switch (pSection->Type) {
|
||||
case SECT_ROM0:
|
||||
maxsize = (options & OPT_TINY) ? 0x8000 : 0x4000;
|
||||
break;
|
||||
case SECT_ROMX:
|
||||
maxsize = 0x4000;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
case SECT_SRAM:
|
||||
maxsize = 0x2000;
|
||||
break;
|
||||
case SECT_WRAM0:
|
||||
maxsize = (options & OPT_CONTWRAM) ? 0x2000 : 0x1000;
|
||||
break;
|
||||
case SECT_WRAMX:
|
||||
maxsize = 0x1000;
|
||||
break;
|
||||
case SECT_OAM:
|
||||
maxsize = 0xA0;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
maxsize = 0x7F;
|
||||
break;
|
||||
default:
|
||||
errx(1, "Section \"%s\" has an invalid section type.", pzName);
|
||||
break;
|
||||
}
|
||||
if (pSection->nByteSize > maxsize) {
|
||||
errx(1, "Section \"%s\" is bigger than the max size for that type: 0x%X > 0x%X",
|
||||
pzName, pSection->nByteSize, maxsize);
|
||||
pzName, pSection->nByteSize, maxsize);
|
||||
}
|
||||
|
||||
if ((pSection->Type == SECT_ROMX) || (pSection->Type == SECT_ROM0)) {
|
||||
/*
|
||||
* These sectiontypes contain data...
|
||||
*
|
||||
*/
|
||||
if (pSection->nByteSize) {
|
||||
pSection->pData = malloc(pSection->nByteSize);
|
||||
if (!pSection->pData) {
|
||||
/*
|
||||
* If the section doesn't contain data, it is ready
|
||||
*/
|
||||
if ((pSection->Type != SECT_ROMX) && (pSection->Type != SECT_ROM0))
|
||||
return pSection;
|
||||
|
||||
/* If there is no data to read, exit */
|
||||
if (pSection->nByteSize == 0) {
|
||||
/* Skip number of patches */
|
||||
readlong(f);
|
||||
pSection->pData = &dummymem;
|
||||
return pSection;
|
||||
}
|
||||
|
||||
pSection->pData = malloc(pSection->nByteSize);
|
||||
if (!pSection->pData)
|
||||
err(1, NULL);
|
||||
|
||||
int32_t nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
|
||||
if (fread(pSection->pData, sizeof(uint8_t), pSection->nByteSize, f)
|
||||
!= pSection->nByteSize) {
|
||||
err(1, "Read error.");
|
||||
}
|
||||
|
||||
nNumberOfPatches = readlong(f);
|
||||
ppPatch = &pSection->pPatches;
|
||||
|
||||
/*
|
||||
* And patches...
|
||||
*/
|
||||
while (nNumberOfPatches--) {
|
||||
pPatch = malloc(sizeof(*pPatch));
|
||||
if (!pPatch)
|
||||
err(1, NULL);
|
||||
|
||||
*ppPatch = pPatch;
|
||||
readasciiz(&pPatch->pzFilename, f);
|
||||
pPatch->nLineNo = readlong(f);
|
||||
pPatch->nOffset = readlong(f);
|
||||
pPatch->Type = (enum ePatchType)fgetc(f);
|
||||
pPatch->nRPNSize = readlong(f);
|
||||
|
||||
if (pPatch->nRPNSize > 0) {
|
||||
pPatch->pRPN = malloc(pPatch->nRPNSize);
|
||||
if (!pPatch->pRPN)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
int32_t nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
|
||||
if (fread(pSection->pData, sizeof(uint8_t),
|
||||
pSection->nByteSize, f) != pSection->nByteSize) {
|
||||
err(1, "Read error.");
|
||||
}
|
||||
|
||||
nNumberOfPatches = readlong(f);
|
||||
ppPatch = &pSection->pPatches;
|
||||
|
||||
/*
|
||||
* And patches...
|
||||
*
|
||||
*/
|
||||
while (nNumberOfPatches--) {
|
||||
pPatch = malloc(sizeof *pPatch);
|
||||
if (!pPatch) {
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
*ppPatch = pPatch;
|
||||
readasciiz(&pPatch->pzFilename, f);
|
||||
pPatch->nLineNo = readlong(f);
|
||||
pPatch->nOffset = readlong(f);
|
||||
pPatch->Type = (enum ePatchType) fgetc(f);
|
||||
if ((pPatch->nRPNSize = readlong(f)) > 0) {
|
||||
pPatch->pRPN = malloc(pPatch->nRPNSize);
|
||||
if (!pPatch->pRPN) {
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
if (fread(pPatch->pRPN, sizeof(uint8_t),
|
||||
pPatch->nRPNSize, f) != pPatch->nRPNSize) {
|
||||
errx(1, "Read error.");
|
||||
}
|
||||
} else
|
||||
pPatch->pRPN = NULL;
|
||||
|
||||
pPatch->pNext = NULL;
|
||||
ppPatch = &(pPatch->pNext);
|
||||
if (fread(pPatch->pRPN, sizeof(uint8_t),
|
||||
pPatch->nRPNSize, f) != pPatch->nRPNSize) {
|
||||
errx(1, "Read error.");
|
||||
}
|
||||
} else {
|
||||
/* Skip number of patches */
|
||||
readlong(f);
|
||||
pSection->pData = &dummymem;
|
||||
pPatch->pRPN = NULL;
|
||||
}
|
||||
|
||||
pPatch->pNext = NULL;
|
||||
ppPatch = &(pPatch->pNext);
|
||||
}
|
||||
|
||||
return pSection;
|
||||
}
|
||||
|
||||
void
|
||||
obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
|
||||
void obj_ReadRGB(FILE *pObjfile, char *tzObjectfile)
|
||||
{
|
||||
struct sSection *pFirstSection;
|
||||
int32_t nNumberOfSymbols, nNumberOfSections, i;
|
||||
@@ -289,15 +264,15 @@ obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
|
||||
/* First comes the symbols */
|
||||
|
||||
if (nNumberOfSymbols) {
|
||||
tSymbols = malloc(nNumberOfSymbols * sizeof *tSymbols);
|
||||
if (!tSymbols) {
|
||||
tSymbols = malloc(nNumberOfSymbols * sizeof(*tSymbols));
|
||||
if (!tSymbols)
|
||||
err(1, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1)
|
||||
tSymbols[i] = obj_ReadSymbol(pObjfile, tzObjectfile);
|
||||
} else
|
||||
tSymbols = (struct sSymbol **) & dummymem;
|
||||
} else {
|
||||
tSymbols = (struct sSymbol **)&dummymem;
|
||||
}
|
||||
|
||||
/* Next we have the sections */
|
||||
|
||||
@@ -314,55 +289,56 @@ obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
|
||||
/*
|
||||
* Fill in the pSection entry in the symbolstructure.
|
||||
* This REALLY needs some cleaning up... but, hey, it works
|
||||
*
|
||||
*/
|
||||
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1) {
|
||||
struct sSection *pConvSect = pFirstSection;
|
||||
|
||||
if (tSymbols[i]->Type != SYM_IMPORT
|
||||
&& tSymbols[i]->nSectionID != -1) {
|
||||
if ((tSymbols[i]->Type != SYM_IMPORT) &&
|
||||
(tSymbols[i]->nSectionID != -1)) {
|
||||
int32_t j = 0;
|
||||
|
||||
while (j != tSymbols[i]->nSectionID) {
|
||||
j += 1;
|
||||
pConvSect = pConvSect->pNext;
|
||||
}
|
||||
tSymbols[i]->pSection = pConvSect;
|
||||
} else
|
||||
} else {
|
||||
tSymbols[i]->pSection = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The main objectfileloadroutine (phew)
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
|
||||
void obj_ReadOpenFile(FILE *pObjfile, char *tzObjectfile)
|
||||
{
|
||||
char tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING) + 1];
|
||||
|
||||
if (fread(tzHeader, sizeof(char), strlen(RGBDS_OBJECT_VERSION_STRING),
|
||||
pObjfile) != strlen(RGBDS_OBJECT_VERSION_STRING)) {
|
||||
pObjfile) != strlen(RGBDS_OBJECT_VERSION_STRING)) {
|
||||
errx(1, "%s: Read error.", tzObjectfile);
|
||||
}
|
||||
|
||||
tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING)] = 0;
|
||||
|
||||
if (strncmp(tzHeader, RGBDS_OBJECT_VERSION_STRING,
|
||||
strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) {
|
||||
strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) {
|
||||
obj_ReadRGB(pObjfile, tzObjectfile);
|
||||
} else {
|
||||
for (int32_t i = 0; i < strlen(RGBDS_OBJECT_VERSION_STRING); i++)
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < strlen(RGBDS_OBJECT_VERSION_STRING); i++)
|
||||
if (!isprint(tzHeader[i]))
|
||||
tzHeader[i] = '?';
|
||||
|
||||
errx(1, "%s: Invalid file or object file version [%s]",
|
||||
tzObjectfile, tzHeader);
|
||||
tzObjectfile, tzHeader);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
obj_Readfile(char *tzObjectfile)
|
||||
void obj_Readfile(char *tzObjectfile)
|
||||
{
|
||||
FILE *pObjfile;
|
||||
|
||||
@@ -372,17 +348,16 @@ obj_Readfile(char *tzObjectfile)
|
||||
oReadLib = 0;
|
||||
|
||||
pObjfile = fopen(tzObjectfile, "rb");
|
||||
if (pObjfile == NULL) {
|
||||
if (pObjfile == NULL)
|
||||
err(1, "Unable to open object '%s'", tzObjectfile);
|
||||
}
|
||||
|
||||
obj_ReadOpenFile(pObjfile, tzObjectfile);
|
||||
fclose(pObjfile);
|
||||
|
||||
oReadLib = 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
file_Length(FILE * f)
|
||||
int32_t file_Length(FILE *f)
|
||||
{
|
||||
uint32_t r, p;
|
||||
|
||||
@@ -391,5 +366,5 @@ file_Length(FILE * f)
|
||||
r = ftell(f);
|
||||
fseek(f, p, SEEK_SET);
|
||||
|
||||
return (r);
|
||||
return r;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user