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:
Antonio Niño Díaz
2018-01-01 16:28:08 +01:00
parent ec76431c51
commit f41c532400
22 changed files with 758 additions and 715 deletions

View File

@@ -27,8 +27,10 @@ enum eBankDefine {
BANK_SRAM = BANK_HRAM + BANK_COUNT_HRAM BANK_SRAM = BANK_HRAM + BANK_COUNT_HRAM
}; };
#define MAXBANKS (BANK_COUNT_ROM0 + BANK_COUNT_ROMX + BANK_COUNT_WRAM0 + BANK_COUNT_WRAMX \ #define MAXBANKS (BANK_COUNT_ROM0 + BANK_COUNT_ROMX \
+ BANK_COUNT_VRAM + BANK_COUNT_OAM + BANK_COUNT_HRAM + BANK_COUNT_SRAM) + BANK_COUNT_WRAM0 + BANK_COUNT_WRAMX \
+ BANK_COUNT_VRAM + BANK_COUNT_OAM \
+ BANK_COUNT_HRAM + BANK_COUNT_SRAM)
extern int32_t MaxBankUsed; extern int32_t MaxBankUsed;
extern int32_t MaxAvail[MAXBANKS]; extern int32_t MaxAvail[MAXBANKS];
@@ -36,17 +38,11 @@ extern int32_t MaxAvail[MAXBANKS];
int32_t area_Avail(int32_t bank); int32_t area_Avail(int32_t bank);
void AssignSections(void); void AssignSections(void);
void CreateSymbolTable(void); void CreateSymbolTable(void);
int32_t IsSectionNameInUse(const char *name);
void SetLinkerscriptName(char *tzLinkerscriptFile);
int32_t IsSectionSameTypeBankAndFloating(const char *name,
enum eSectionType type, int32_t bank);
uint32_t AssignSectionAddressAndBankByName(const char *name, uint32_t address,
int32_t bank);
int32_t #endif /* RGBDS_LINK_ASSIGN_H */
IsSectionNameInUse(const char *name);
void
SetLinkerscriptName(char *tzLinkerscriptFile);
int32_t
IsSectionSameTypeBankAndFloating(const char *name, enum eSectionType type, int32_t bank);
uint32_t
AssignSectionAddressAndBankByName(const char *name, uint32_t address, int32_t bank);
#endif

View File

@@ -3,4 +3,4 @@
void AddNeededModules(void); void AddNeededModules(void);
#endif #endif /* RGBDS_LINK_LIBRARY_H */

View File

@@ -6,4 +6,4 @@
extern int32_t fillchar; extern int32_t fillchar;
extern char *smartlinkstartsymbol; extern char *smartlinkstartsymbol;
#endif #endif /* RGBDS_LINK_MAIN_H */

View File

@@ -6,8 +6,8 @@
void SetMapfileName(char *name); void SetMapfileName(char *name);
void SetSymfileName(char *name); void SetSymfileName(char *name);
void CloseMapfile(void); void CloseMapfile(void);
void MapfileWriteSection(struct sSection * pSect); void MapfileWriteSection(const struct sSection *pSect);
void MapfileInitBank(int32_t bank); void MapfileInitBank(int32_t bank);
void MapfileCloseBank(int32_t slack); void MapfileCloseBank(int32_t slack);
#endif #endif /* RGBDS_LINK_MAPFILE_H */

View File

@@ -82,10 +82,12 @@ enum eSymbolType {
struct sSymbol { struct sSymbol {
char *pzName; char *pzName;
enum eSymbolType Type; enum eSymbolType Type;
/* the following 3 items only valid when Type!=SYM_IMPORT */
int32_t nSectionID; /* internal to object.c */ /* The following 3 items only valid when Type!=SYM_IMPORT */
int32_t nSectionID; /* Internal to object.c */
struct sSection *pSection; struct sSection *pSection;
int32_t nOffset; int32_t nOffset;
char *pzObjFileName; /* Object file where the symbol is located. */ char *pzObjFileName; /* Object file where the symbol is located. */
char *pzFileName; /* Source file where the symbol was defined. */ char *pzFileName; /* Source file where the symbol was defined. */
uint32_t nFileLine; /* Line where the symbol was defined. */ uint32_t nFileLine; /* Line where the symbol was defined. */
@@ -111,4 +113,4 @@ struct sPatch {
extern struct sSection *pSections; extern struct sSection *pSections;
extern struct sSection *pLibSections; extern struct sSection *pLibSections;
#endif #endif /* RGBDS_LINK_LINK_H */

View File

@@ -3,4 +3,4 @@
void obj_Readfile(char *tzObjectfile); void obj_Readfile(char *tzObjectfile);
#endif #endif /* RGBDS_LINK_OBJECT_H */

View File

@@ -5,4 +5,4 @@ void out_Setname(char *tzOutputfile);
void out_SetOverlayname(char *tzOverlayfile); void out_SetOverlayname(char *tzOverlayfile);
void Output(void); void Output(void);
#endif #endif /* RGBDS_LINK_OUTPUT_H */

View File

@@ -6,4 +6,4 @@
void Patch(void); void Patch(void);
extern int32_t nPC; extern int32_t nPC;
#endif #endif /* RGBDS_LINK_PATCH_H */

View File

@@ -35,5 +35,4 @@ void script_SetAddress(uint32_t addr);
void script_SetAlignment(uint32_t alignment); void script_SetAlignment(uint32_t alignment);
void script_OutputSection(const char *section_name); void script_OutputSection(const char *section_name);
#endif #endif /* RGBDS_LINK_SCRIPT_H */

View File

@@ -5,8 +5,9 @@
void sym_Init(void); void sym_Init(void);
void sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank, void sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank,
char *tzObjFileName, char *tzFileName, uint32_t nFileLine); char *tzObjFileName, char *tzFileName,
uint32_t nFileLine);
int32_t sym_GetValue(char *tzName); int32_t sym_GetValue(char *tzName);
int32_t sym_GetBank(char *tzName); int32_t sym_GetBank(char *tzName);
#endif #endif /* RGBDS_LINK_SYMBOL_H */

View File

@@ -5,4 +5,4 @@
#define _MAX_PATH 512 #define _MAX_PATH 512
#endif #endif
#endif #endif /* RGBDS_TYPES_H */

View File

@@ -5,6 +5,7 @@
#include <string.h> #include <string.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/assign.h" #include "link/assign.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/main.h" #include "link/main.h"
@@ -19,8 +20,9 @@ struct sFreeArea {
struct sSectionAttributes { struct sSectionAttributes {
const char *name; const char *name;
/* bank + offset = bank originally stored in a section struct */
int32_t bank; int32_t bank;
int32_t offset; // bank + offset = bank originally stored in a section struct int32_t offset;
int32_t minBank; int32_t minBank;
int32_t bankCount; int32_t bankCount;
}; };
@@ -45,27 +47,37 @@ const struct sSectionAttributes SECT_ATTRIBUTES[] = {
{"OAM", BANK_OAM, 0, 0, BANK_COUNT_OAM} {"OAM", BANK_OAM, 0, 0, BANK_COUNT_OAM}
}; };
#define DOMAXBANK(x, y) {switch (x) { \ static void do_max_bank(enum eSectionType Type, int32_t nBank)
case SECT_ROMX: DOMAXRBANK(y); break; \
case SECT_WRAMX: DOMAXWBANK(y); break; \
case SECT_SRAM: DOMAXSBANK(y); break; \
case SECT_VRAM: DOMAXVBANK(y); break; \
default: break; }}
#define DOMAXRBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
#define DOMAXWBANK(x) {if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
#define DOMAXSBANK(x) {if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);}
#define DOMAXVBANK(x) {if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);}
void
ensureSectionTypeIsValid(enum eSectionType type)
{ {
if (type < SECT_MIN || type > SECT_MAX) { switch (Type) {
case SECT_ROMX:
if (nBank > MaxBankUsed)
MaxBankUsed = nBank;
break;
case SECT_WRAMX:
if (nBank > MaxWBankUsed)
MaxWBankUsed = nBank;
break;
case SECT_SRAM:
if (nBank > MaxSBankUsed)
MaxSBankUsed = nBank;
break;
case SECT_VRAM:
if (nBank > MaxVBankUsed)
MaxVBankUsed = nBank;
break;
default:
break;
}
}
void ensureSectionTypeIsValid(enum eSectionType type)
{
if (type < SECT_MIN || type > SECT_MAX)
errx(1, "(INTERNAL) Invalid section type found."); errx(1, "(INTERNAL) Invalid section type found.");
} }
}
int32_t int32_t area_Avail(int32_t bank)
area_Avail(int32_t bank)
{ {
int32_t r; int32_t r;
struct sFreeArea *pArea; struct sFreeArea *pArea;
@@ -78,54 +90,55 @@ area_Avail(int32_t bank)
pArea = pArea->pNext; pArea = pArea->pNext;
} }
return (r); return r;
} }
int32_t int32_t area_doAlloc(struct sFreeArea *pArea, int32_t org, int32_t size)
area_doAlloc(struct sFreeArea *pArea, int32_t org, int32_t size)
{ {
if (org >= pArea->nOrg && (org + size) <= (pArea->nOrg + pArea->nSize)) { if ((org >= pArea->nOrg)
&& ((org + size) <= (pArea->nOrg + pArea->nSize))) {
if (org == pArea->nOrg) { if (org == pArea->nOrg) {
pArea->nOrg += size; pArea->nOrg += size;
pArea->nSize -= size; pArea->nSize -= size;
return org; return org;
} else { }
if ((org + size) == (pArea->nOrg + pArea->nSize)) { if ((org + size) == (pArea->nOrg + pArea->nSize)) {
pArea->nSize -= size; pArea->nSize -= size;
return org; return org;
} else { }
struct sFreeArea *pNewArea; struct sFreeArea *pNewArea;
if ((pNewArea = malloc(sizeof(struct sFreeArea))) != NULL) { pNewArea = malloc(sizeof(struct sFreeArea));
if (pNewArea == NULL)
err(1, NULL);
*pNewArea = *pArea; *pNewArea = *pArea;
pNewArea->pPrev = pArea; pNewArea->pPrev = pArea;
pArea->pNext = pNewArea; pArea->pNext = pNewArea;
pArea->nSize = org - pArea->nOrg; pArea->nSize = org - pArea->nOrg;
pNewArea->nOrg = org + size; pNewArea->nOrg = org + size;
pNewArea->nSize -= size + pArea->nSize; pNewArea->nSize -= size + pArea->nSize;
return org;
} else { return org;
err(1, NULL);
}
}
}
} }
return -1; return -1;
} }
int32_t int32_t area_AllocAbs(struct sFreeArea **ppArea, int32_t org, int32_t size)
area_AllocAbs(struct sFreeArea ** ppArea, int32_t org, int32_t size)
{ {
struct sFreeArea *pArea; struct sFreeArea *pArea;
pArea = *ppArea; pArea = *ppArea;
while (pArea) { while (pArea) {
int32_t result = area_doAlloc(pArea, org, size); int32_t result = area_doAlloc(pArea, org, size);
if (result != -1) {
if (result != -1)
return result; return result;
}
ppArea = &(pArea->pNext); ppArea = &(pArea->pNext);
pArea = *ppArea; pArea = *ppArea;
@@ -134,8 +147,7 @@ area_AllocAbs(struct sFreeArea ** ppArea, int32_t org, int32_t size)
return -1; return -1;
} }
int32_t int32_t area_AllocAbsAnyBank(int32_t org, int32_t size, enum eSectionType type)
area_AllocAbsAnyBank(int32_t org, int32_t size, enum eSectionType type)
{ {
ensureSectionTypeIsValid(type); ensureSectionTypeIsValid(type);
@@ -143,33 +155,33 @@ area_AllocAbsAnyBank(int32_t org, int32_t size, enum eSectionType type)
int32_t bankCount = SECT_ATTRIBUTES[type].bankCount; int32_t bankCount = SECT_ATTRIBUTES[type].bankCount;
for (int32_t i = 0; i < bankCount; i++) { for (int32_t i = 0; i < bankCount; i++) {
if (area_AllocAbs(&BankFree[startBank + i], org, size) != -1) { if (area_AllocAbs(&BankFree[startBank + i], org, size) != -1)
return startBank + i; return startBank + i;
} }
}
return -1; return -1;
} }
int32_t int32_t area_Alloc(struct sFreeArea **ppArea, int32_t size, int32_t alignment)
area_Alloc(struct sFreeArea ** ppArea, int32_t size, int32_t alignment) { {
struct sFreeArea *pArea; struct sFreeArea *pArea;
if (alignment < 1) {
if (alignment < 1)
alignment = 1; alignment = 1;
}
pArea = *ppArea; pArea = *ppArea;
while (pArea) { while (pArea) {
int32_t org = pArea->nOrg; int32_t org = pArea->nOrg;
if (org % alignment) {
if (org % alignment)
org += alignment; org += alignment;
}
org -= org % alignment; org -= org % alignment;
int32_t result = area_doAlloc(pArea, org, size); int32_t result = area_doAlloc(pArea, org, size);
if (result != -1) {
if (result != -1)
return result; return result;
}
ppArea = &(pArea->pNext); ppArea = &(pArea->pNext);
pArea = *ppArea; pArea = *ppArea;
@@ -178,25 +190,25 @@ area_Alloc(struct sFreeArea ** ppArea, int32_t size, int32_t alignment) {
return -1; return -1;
} }
int32_t int32_t area_AllocAnyBank(int32_t size, int32_t alignment,
area_AllocAnyBank(int32_t size, int32_t alignment, enum eSectionType type) { enum eSectionType type)
{
ensureSectionTypeIsValid(type); ensureSectionTypeIsValid(type);
int32_t i, org;
int32_t startBank = SECT_ATTRIBUTES[type].bank; int32_t startBank = SECT_ATTRIBUTES[type].bank;
int32_t bankCount = SECT_ATTRIBUTES[type].bankCount; int32_t bankCount = SECT_ATTRIBUTES[type].bankCount;
for (int32_t i = 0; i < bankCount; i++) { for (i = 0; i < bankCount; i++) {
int32_t org = area_Alloc(&BankFree[startBank + i], size, alignment); org = area_Alloc(&BankFree[startBank + i], size, alignment);
if (org != -1) { if (org != -1)
return ((startBank + i) << 16) | org; return ((startBank + i) << 16) | org;
} }
}
return -1; return -1;
} }
struct sSection * struct sSection *FindLargestSection(enum eSectionType type, bool bankFixed)
FindLargestSection(enum eSectionType type, bool bankFixed)
{ {
struct sSection *pSection, *r = NULL; struct sSection *pSection, *r = NULL;
int32_t nLargest = 0; int32_t nLargest = 0;
@@ -204,8 +216,12 @@ FindLargestSection(enum eSectionType type, bool bankFixed)
pSection = pSections; pSection = pSections;
while (pSection) { while (pSection) {
if (pSection->oAssigned == 0 && pSection->Type == type && (bankFixed ^ (pSection->nBank == -1))) { if (pSection->oAssigned == 0 && pSection->Type == type
if (pSection->nAlign > nLargestAlignment || (pSection->nAlign == nLargestAlignment && pSection->nByteSize > nLargest)) { && (bankFixed ^ (pSection->nBank == -1))) {
if (pSection->nAlign > nLargestAlignment
|| (pSection->nAlign == nLargestAlignment
&& pSection->nByteSize > nLargest)) {
nLargest = pSection->nByteSize; nLargest = pSection->nByteSize;
nLargestAlignment = pSection->nAlign; nLargestAlignment = pSection->nAlign;
r = pSection; r = pSection;
@@ -217,12 +233,10 @@ FindLargestSection(enum eSectionType type, bool bankFixed)
return r; return r;
} }
int32_t int32_t IsSectionNameInUse(const char *name)
IsSectionNameInUse(const char *name)
{ {
struct sSection *pSection; const struct sSection *pSection = pSections;
pSection = pSections;
while (pSection) { while (pSection) {
if (strcmp(pSection->pzName, name) == 0) if (strcmp(pSection->pzName, name) == 0)
return 1; return 1;
@@ -233,100 +247,135 @@ IsSectionNameInUse(const char *name)
return 0; return 0;
} }
int32_t IsSectionSameTypeBankAndFloating(const char *name,
int32_t enum eSectionType type, int32_t bank)
IsSectionSameTypeBankAndFloating(const char *name, enum eSectionType type, int32_t bank)
{ {
struct sSection *pSection; const struct sSection *pSection;
for (pSection = pSections; pSection; pSection = pSection->pNext) {
/* Skip if it has already been assigned */
if (pSection->oAssigned == 1)
continue;
/* Check if it has the same name */
if (strcmp(pSection->pzName, name) != 0)
continue;
/*
* The section has the same name, now check if there is a
* mismatch or not.
*/
pSection = pSections;
while (pSection) {
if (pSection->oAssigned == 0) {
if (strcmp(pSection->pzName, name) == 0) {
/* Section must be floating in source */ /* Section must be floating in source */
if (pSection->nOrg != -1 || pSection->nAlign != 1) if (pSection->nOrg != -1 || pSection->nAlign != 1)
return 0; return 0;
/* It must have the same type in source and linkerscript */ /* It must have the same type in source and linkerscript */
if (pSection->Type != type) if (pSection->Type != type)
return 0; return 0;
/* Bank number must be unassigned in source or equal */ /* Bank number must be unassigned in source or equal */
if (pSection->nBank != -1 && pSection->nBank != bank) if (pSection->nBank != -1 && pSection->nBank != bank)
return 0; return 0;
return 1; return 1;
} }
}
pSection = pSection->pNext;
}
errx(1, "Section \"%s\" not found (or already used).\n", name); errx(1, "Section \"%s\" not found (or already used).\n", name);
} }
uint32_t uint32_t AssignSectionAddressAndBankByName(const char *name, uint32_t address,
AssignSectionAddressAndBankByName(const char *name, uint32_t address, int32_t bank) int32_t bank)
{ {
struct sSection *pSection; struct sSection *pSection;
pSection = pSections; for (pSection = pSections; pSection; pSection = pSection->pNext) {
while (pSection) { /* Skip if it has already been assigned */
if (pSection->oAssigned == 0) { if (pSection->oAssigned == 1)
if (strcmp(pSection->pzName, name) == 0) { continue;
if (pSection->nOrg != -1 || pSection->nAlign != 1)
errx(1, "Section \"%s\" from linkerscript isn't floating.\n", name); /* Check if it has the same name */
if (pSection->nBank != -1 && pSection->nBank != bank) if (strcmp(pSection->pzName, name) != 0)
errx(1, "Section \"%s\" from linkerscript has different bank number than in the source.\n", name); continue;
/* Section has been found. */
/*
* A section can be left as floating in the code if the location
* is assigned in the linkerscript.
*/
if (pSection->nOrg != -1 || pSection->nAlign != 1) {
errx(1, "Section \"%s\" from linkerscript isn't floating.\n",
name);
}
/* The bank can be left as unassigned or be the same */
if (pSection->nBank != -1 && pSection->nBank != bank) {
errx(1, "Section \"%s\" from linkerscript has different bank number than in the source.\n",
name);
}
pSection->nOrg = address; pSection->nOrg = address;
pSection->nBank = bank; pSection->nBank = bank;
pSection->nAlign = -1; pSection->nAlign = -1;
return pSection->nByteSize; return pSection->nByteSize;
} }
}
pSection = pSection->pNext;
}
errx(1, "Section \"%s\" not found (or already used).\n", name); errx(1, "Section \"%s\" not found (or already used).\n", name);
} }
bool bool VerifyAndSetBank(struct sSection *pSection)
VerifyAndSetBank(struct sSection *pSection)
{ {
ensureSectionTypeIsValid(pSection->Type); enum eSectionType Type = pSection->Type;
if (pSection->nBank >= SECT_ATTRIBUTES[pSection->Type].minBank ensureSectionTypeIsValid(Type);
&& pSection->nBank < SECT_ATTRIBUTES[pSection->Type].minBank + SECT_ATTRIBUTES[pSection->Type].bankCount) {
pSection->nBank += SECT_ATTRIBUTES[pSection->Type].bank + SECT_ATTRIBUTES[pSection->Type].offset; if (pSection->nBank >= SECT_ATTRIBUTES[Type].minBank) {
if (pSection->nBank < SECT_ATTRIBUTES[Type].minBank
+ SECT_ATTRIBUTES[Type].bankCount) {
pSection->nBank += SECT_ATTRIBUTES[Type].bank
+ SECT_ATTRIBUTES[Type].offset;
return true; return true;
}
}
} else {
return false; return false;
} }
}
void void AssignFixedBankSections(enum eSectionType type)
AssignFixedBankSections(enum eSectionType type)
{ {
ensureSectionTypeIsValid(type); ensureSectionTypeIsValid(type);
struct sSection *pSection; struct sSection *pSection;
while ((pSection = FindLargestSection(type, true))) { while ((pSection = FindLargestSection(type, true))) {
if (VerifyAndSetBank(pSection) && if (VerifyAndSetBank(pSection)) {
(pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize, pSection->nAlign)) != -1) { pSection->nOrg = area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize,
pSection->nAlign);
if (pSection->nOrg != -1) {
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->Type, pSection->nBank); do_max_bank(pSection->Type, pSection->nBank);
} else { continue;
}
}
if (pSection->nAlign <= 1) { if (pSection->nAlign <= 1) {
errx(1, "Unable to place '%s' (%s section) in bank $%02lX", errx(1, "Unable to place '%s' (%s section) in bank $%02lX",
pSection->pzName, SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank); pSection->pzName,
SECT_ATTRIBUTES[pSection->Type].name,
pSection->nBank);
} else { } else {
errx(1, "Unable to place '%s' (%s section) in bank $%02lX (with $%lX-byte alignment)", errx(1, "Unable to place '%s' (%s section) in bank $%02lX (with $%lX-byte alignment)",
pSection->pzName, SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank, pSection->nAlign); pSection->pzName,
} SECT_ATTRIBUTES[pSection->Type].name,
pSection->nBank, pSection->nAlign);
} }
} }
} }
void void AssignFloatingBankSections(enum eSectionType type)
AssignFloatingBankSections(enum eSectionType type)
{ {
ensureSectionTypeIsValid(type); ensureSectionTypeIsValid(type);
@@ -335,41 +384,45 @@ AssignFloatingBankSections(enum eSectionType type)
while ((pSection = FindLargestSection(type, false))) { while ((pSection = FindLargestSection(type, false))) {
int32_t org; int32_t org;
if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) { org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign,
if (options & OPT_OVERLAY) { type);
if (org != -1) {
if (options & OPT_OVERLAY)
errx(1, "All sections must be fixed when using an overlay file."); errx(1, "All sections must be fixed when using an overlay file.");
}
pSection->nOrg = org & 0xFFFF; pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16; pSection->nBank = org >> 16;
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->Type, pSection->nBank); do_max_bank(pSection->Type, pSection->nBank);
} else { } else {
const char *locality = "anywhere"; const char *locality = "anywhere";
if (SECT_ATTRIBUTES[pSection->Type].bankCount > 1) {
if (SECT_ATTRIBUTES[pSection->Type].bankCount > 1)
locality = "in any bank"; locality = "in any bank";
}
if (pSection->nAlign <= 1) { if (pSection->nAlign <= 1) {
errx(1, "Unable to place '%s' (%s section) %s", errx(1, "Unable to place '%s' (%s section) %s",
pSection->pzName, SECT_ATTRIBUTES[type].name, locality); pSection->pzName,
SECT_ATTRIBUTES[type].name, locality);
} else { } else {
errx(1, "Unable to place '%s' (%s section) %s (with $%lX-byte alignment)", errx(1, "Unable to place '%s' (%s section) %s (with $%lX-byte alignment)",
pSection->pzName, SECT_ATTRIBUTES[type].name, locality, pSection->nAlign); pSection->pzName,
SECT_ATTRIBUTES[type].name, locality,
pSection->nAlign);
} }
} }
} }
} }
char *tzLinkerscriptName = NULL; char *tzLinkerscriptName;
void void SetLinkerscriptName(char *tzLinkerscriptFile)
SetLinkerscriptName(char *tzLinkerscriptFile)
{ {
tzLinkerscriptName = tzLinkerscriptFile; tzLinkerscriptName = tzLinkerscriptFile;
} }
void void AssignSections(void)
AssignSections(void)
{ {
int32_t i; int32_t i;
struct sSection *pSection; struct sSection *pSection;
@@ -378,24 +431,21 @@ AssignSections(void)
/* /*
* Initialize the memory areas * Initialize the memory areas
*
*/ */
for (i = 0; i < MAXBANKS; i += 1) { for (i = 0; i < MAXBANKS; i += 1) {
BankFree[i] = malloc(sizeof *BankFree[i]); BankFree[i] = malloc(sizeof(*BankFree[i]));
if (!BankFree[i]) { if (!BankFree[i])
err(1, NULL); err(1, NULL);
}
if (i == BANK_ROM0) { if (i == BANK_ROM0) {
/* ROM0 bank */ /* ROM0 bank */
BankFree[i]->nOrg = 0x0000; BankFree[i]->nOrg = 0x0000;
if (options & OPT_TINY) { if (options & OPT_TINY)
BankFree[i]->nSize = 0x8000; BankFree[i]->nSize = 0x8000;
} else { else
BankFree[i]->nSize = 0x4000; BankFree[i]->nSize = 0x4000;
}
} else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) { } else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) {
/* Swappable ROM bank */ /* Swappable ROM bank */
BankFree[i]->nOrg = 0x4000; BankFree[i]->nOrg = 0x4000;
@@ -403,11 +453,10 @@ AssignSections(void)
} else if (i == BANK_WRAM0) { } else if (i == BANK_WRAM0) {
/* WRAM */ /* WRAM */
BankFree[i]->nOrg = 0xC000; BankFree[i]->nOrg = 0xC000;
if (options & OPT_CONTWRAM) { if (options & OPT_CONTWRAM)
BankFree[i]->nSize = 0x2000; BankFree[i]->nSize = 0x2000;
} else { else
BankFree[i]->nSize = 0x1000; BankFree[i]->nSize = 0x1000;
}
} else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) { } else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) {
/* Swappable SRAM bank */ /* Swappable SRAM bank */
BankFree[i]->nOrg = 0xA000; BankFree[i]->nOrg = 0xA000;
@@ -419,11 +468,10 @@ AssignSections(void)
} else if (i >= BANK_VRAM && i < BANK_VRAM + BANK_COUNT_VRAM) { } else if (i >= BANK_VRAM && i < BANK_VRAM + BANK_COUNT_VRAM) {
/* Swappable VRAM bank */ /* Swappable VRAM bank */
BankFree[i]->nOrg = 0x8000; BankFree[i]->nOrg = 0x8000;
if (options & OPT_DMG_MODE && i != BANK_VRAM) { if (options & OPT_DMG_MODE && i != BANK_VRAM)
BankFree[i]->nSize = 0; BankFree[i]->nSize = 0;
} else { else
BankFree[i]->nSize = 0x2000; BankFree[i]->nSize = 0x2000;
}
} else if (i == BANK_OAM) { } else if (i == BANK_OAM) {
BankFree[i]->nOrg = 0xFE00; BankFree[i]->nOrg = 0xFE00;
BankFree[i]->nSize = 0x00A0; BankFree[i]->nSize = 0x00A0;
@@ -442,7 +490,6 @@ AssignSections(void)
/* /*
* First, let's parse the linkerscript. * First, let's parse the linkerscript.
*
*/ */
if (tzLinkerscriptName) { if (tzLinkerscriptName) {
@@ -452,13 +499,13 @@ AssignSections(void)
/* /*
* Second, let's assign all the fixed sections... * Second, let's assign all the fixed sections...
*
*/ */
pSection = pSections; for (pSection = pSections ; pSection; pSection = pSection->pNext) {
while (pSection) { if (!((pSection->nOrg != -1 || pSection->nBank != -1)
if ((pSection->nOrg != -1 || pSection->nBank != -1) && pSection->oAssigned == 0))
&& pSection->oAssigned == 0) { continue;
/* User wants to have a say... */ /* User wants to have a say... */
switch (pSection->Type) { switch (pSection->Type) {
@@ -467,10 +514,13 @@ AssignSections(void)
case SECT_ROM0: case SECT_ROM0:
case SECT_OAM: case SECT_OAM:
pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank; pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank;
if (area_AllocAbs(&BankFree[pSection->nBank], pSection->nOrg, if (area_AllocAbs(&BankFree[pSection->nBank],
pSection->nOrg,
pSection->nByteSize) == -1) { pSection->nByteSize) == -1) {
errx(1, "Unable to place '%s' (%s section) at $%lX", errx(1, "Unable to place '%s' (%s section) at $%X",
pSection->pzName, SECT_ATTRIBUTES[pSection->Type].name, pSection->nOrg); pSection->pzName,
SECT_ATTRIBUTES[pSection->Type].name,
pSection->nOrg);
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
break; break;
@@ -479,79 +529,79 @@ AssignSections(void)
case SECT_WRAMX: case SECT_WRAMX:
case SECT_VRAM: case SECT_VRAM:
case SECT_ROMX: case SECT_ROMX:
if (pSection->nBank != -1 && pSection->nOrg != -1) { if (!(pSection->nBank != -1 && pSection->nOrg != -1))
break;
if (VerifyAndSetBank(pSection) && if (VerifyAndSetBank(pSection) &&
area_AllocAbs(&BankFree[pSection->nBank], pSection->nOrg, pSection->nByteSize) != -1) { area_AllocAbs(&BankFree[pSection->nBank],
DOMAXBANK(pSection->Type, pSection->nBank); pSection->nOrg,
pSection->nByteSize) != -1) {
do_max_bank(pSection->Type, pSection->nBank);
pSection->oAssigned = 1; pSection->oAssigned = 1;
} else { } else {
errx(1, "Unable to place '%s' (%s section) at $%lX in bank $%02lX", errx(1, "Unable to place '%s' (%s section) at $%X in bank $%02X",
pSection->pzName, SECT_ATTRIBUTES[pSection->Type].name, pSection->nOrg, pSection->nBank); pSection->pzName,
} SECT_ATTRIBUTES[pSection->Type].name,
pSection->nOrg, pSection->nBank);
} }
break; break;
} }
} }
pSection = pSection->pNext;
}
/* /*
* Next, let's assign all the bankfixed ONLY sections... * Next, let's assign all the bankfixed ONLY sections...
*
*/ */
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) { for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++)
AssignFixedBankSections(i); AssignFixedBankSections(i);
}
/* /*
* Now, let's assign all the floating bank but fixed ROMX sections... * Now, let's assign all the floating bank but fixed ROMX sections...
*
*/ */
pSection = pSections; for (pSection = pSections ; pSection; pSection = pSection->pNext) {
while (pSection) { if (!(pSection->oAssigned == 0
if (pSection->oAssigned == 0 && pSection->nOrg != -1 && pSection->nBank == -1))
&& pSection->nOrg != -1 && pSection->nBank == -1) { continue;
if (options & OPT_OVERLAY) {
if (options & OPT_OVERLAY)
errx(1, "All sections must be fixed when using an overlay file."); errx(1, "All sections must be fixed when using an overlay file.");
}
switch (pSection->Type) { switch (pSection->Type) {
case SECT_ROMX: case SECT_ROMX:
case SECT_VRAM: case SECT_VRAM:
case SECT_SRAM: case SECT_SRAM:
case SECT_WRAMX: case SECT_WRAMX:
if ((pSection->nBank = pSection->nBank =
area_AllocAbsAnyBank(pSection->nOrg, pSection->nByteSize, area_AllocAbsAnyBank(pSection->nOrg,
pSection->Type)) == -1) { pSection->nByteSize,
errx(1, "Unable to place '%s' (%s section) at $%lX in any bank", pSection->Type);
pSection->pzName, SECT_ATTRIBUTES[pSection->Type].name, pSection->nOrg);
if (pSection->nBank == -1) {
errx(1, "Unable to place '%s' (%s section) at $%X in any bank",
pSection->pzName,
SECT_ATTRIBUTES[pSection->Type].name,
pSection->nOrg);
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->Type, pSection->nBank); do_max_bank(pSection->Type, pSection->nBank);
break; break;
default: // Handle other sections later default: /* Handle other sections later */
break; break;
} }
} }
pSection = pSection->pNext;
}
/* /*
* OK, all that nasty stuff is done so let's assign all the other * OK, all that nasty stuff is done so let's assign all the other
* sections * sections
*
*/ */
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) { for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++)
AssignFloatingBankSections(i); AssignFloatingBankSections(i);
} }
}
void void CreateSymbolTable(void)
CreateSymbolTable(void)
{ {
struct sSection *pSect; const struct sSection *pSect;
sym_Init(); sym_Init();
@@ -563,25 +613,27 @@ CreateSymbolTable(void)
i = pSect->nNumberOfSymbols; i = pSect->nNumberOfSymbols;
while (i--) { while (i--) {
if ((pSect->tSymbols[i]->Type == SYM_EXPORT) && const struct sSymbol *tSymbol = pSect->tSymbols[i];
((pSect->tSymbols[i]->pSection == pSect) ||
(pSect->tSymbols[i]->pSection == NULL))) { if ((tSymbol->Type == SYM_EXPORT) &&
if (pSect->tSymbols[i]->pSection == NULL) ((tSymbol->pSection == pSect) ||
(tSymbol->pSection == NULL))) {
if (tSymbol->pSection == NULL)
sym_CreateSymbol( sym_CreateSymbol(
pSect->tSymbols[i]->pzName, tSymbol->pzName,
pSect->tSymbols[i]->nOffset, tSymbol->nOffset,
-1, -1,
pSect->tSymbols[i]->pzObjFileName, tSymbol->pzObjFileName,
pSect->tSymbols[i]->pzFileName, tSymbol->pzFileName,
pSect->tSymbols[i]->nFileLine); tSymbol->nFileLine);
else else
sym_CreateSymbol( sym_CreateSymbol(
pSect->tSymbols[i]->pzName, tSymbol->pzName,
pSect->nOrg + pSect->tSymbols[i]->nOffset, pSect->nOrg + tSymbol->nOffset,
pSect->nBank, pSect->nBank,
pSect->tSymbols[i]->pzObjFileName, tSymbol->pzObjFileName,
pSect->tSymbols[i]->pzFileName, tSymbol->pzFileName,
pSect->tSymbols[i]->nFileLine); tSymbol->nFileLine);
} }
} }
pSect = pSect->pNext; pSect = pSect->pNext;

View File

@@ -37,7 +37,7 @@ extern int yyparse();
#define MAX_INCLUDE_DEPTH 8 #define MAX_INCLUDE_DEPTH 8
static int32_t include_stack_ptr = 0; static int32_t include_stack_ptr;
static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
static char include_path[MAX_INCLUDE_DEPTH][_MAX_PATH + 1]; static char include_path[MAX_INCLUDE_DEPTH][_MAX_PATH + 1];
@@ -49,14 +49,21 @@ static char linkerscript_path[_MAX_PATH + 1]; /* Base file */
%% %%
\"([^\\\"]|\\.)*\" { \"([^\\\"]|\\.)*\" {
if (strlen(yytext) > sizeof(yylval.s) - 1) if (strlen(yytext) > sizeof(yylval.s) - 1) {
script_fatalerror("String is too long: %s\n.", yytext); script_fatalerror("String is too long: %s\n.",
if (strlen(yytext) < 3) /* 2 quotes + 1 character */ yytext);
script_fatalerror("String %s is invalid\n.", yytext); }
yytext++; /* ignore first quote */ if (strlen(yytext) < 3) { /* 2 quotes + 1 character */
script_fatalerror("String %s is invalid\n.",
yytext);
}
/* Ignore first quote */
yytext++;
strcpy(yylval.s, yytext); strcpy(yylval.s, yytext);
yylval.s[strlen(yylval.s)-1] = '\0'; /* remove end quote */ /* Remove end quote */
yylval.s[strlen(yylval.s)-1] = '\0';
return STRING; return STRING;
} }
@@ -112,7 +119,6 @@ void script_Parse(const char * path)
} while (!feof(yyin)); } while (!feof(yyin));
fclose(yyin); fclose(yyin);
} }
void script_IncludeFile(const char * path) void script_IncludeFile(const char * path)

View File

@@ -4,13 +4,13 @@
#include <string.h> #include <string.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/main.h" #include "link/main.h"
static uint8_t static uint8_t symboldefined(char *name)
symboldefined(char *name)
{ {
struct sSection *pSect; const struct sSection *pSect;
pSect = pSections; pSect = pSections;
@@ -18,56 +18,54 @@ symboldefined(char *name)
int32_t i; int32_t i;
for (i = 0; i < pSect->nNumberOfSymbols; i += 1) { for (i = 0; i < pSect->nNumberOfSymbols; i += 1) {
if ((pSect->tSymbols[i]->Type == SYM_EXPORT) const struct sSymbol *tSymbol = pSect->tSymbols[i];
|| ((pSect->tSymbols[i]->Type == SYM_LOCAL)
&& (pSect == pSect->tSymbols[i]->pSection))) { if ((tSymbol->Type == SYM_EXPORT)
if (strcmp(pSect->tSymbols[i]->pzName, name) == || ((tSymbol->Type == SYM_LOCAL)
0) && (pSect == tSymbol->pSection))) {
return (1);
if (strcmp(tSymbol->pzName, name) == 0)
return 1;
} }
} }
pSect = pSect->pNext; pSect = pSect->pNext;
} }
return (0); return 0;
} }
static uint8_t static uint8_t addmodulecontaining(char *name)
addmodulecontaining(char *name)
{ {
struct sSection **ppLSect; struct sSection **ppLSect = &pLibSections;
ppLSect = &pLibSections;
while (*ppLSect) { while (*ppLSect) {
int32_t i; int32_t i;
for (i = 0; i < (*ppLSect)->nNumberOfSymbols; i += 1) { for (i = 0; i < (*ppLSect)->nNumberOfSymbols; i += 1) {
if (((*ppLSect)->tSymbols[i]->Type == SYM_EXPORT) const struct sSymbol *tSymbol = (*ppLSect)->tSymbols[i];
|| (((*ppLSect)->tSymbols[i]->Type == SYM_LOCAL)
&& ((*ppLSect) == if ((tSymbol->Type == SYM_EXPORT)
(*ppLSect)->tSymbols[i]->pSection))) { || ((tSymbol->Type == SYM_LOCAL)
if (strcmp && ((*ppLSect) == tSymbol->pSection))) {
((*ppLSect)->tSymbols[i]->pzName,
name) == 0) { if (strcmp(tSymbol->pzName, name) == 0) {
struct sSection **ppSect; struct sSection **ppSect = &pSections;
ppSect = &pSections;
while (*ppSect) while (*ppSect)
ppSect = &((*ppSect)->pNext); ppSect = &((*ppSect)->pNext);
*ppSect = *ppLSect; *ppSect = *ppLSect;
*ppLSect = (*ppLSect)->pNext; *ppLSect = (*ppLSect)->pNext;
(*ppSect)->pNext = NULL; (*ppSect)->pNext = NULL;
return (1); return 1;
} }
} }
} }
ppLSect = &((*ppLSect)->pNext); ppLSect = &((*ppLSect)->pNext);
} }
return (0); return 0;
} }
void void AddNeededModules(void)
AddNeededModules(void)
{ {
struct sSection *pSect; struct sSection *pSect;
@@ -77,8 +75,8 @@ AddNeededModules(void)
ppLSect = &pLibSections; ppLSect = &pLibSections;
while (*ppLSect) { while (*ppLSect) {
struct sSection **ppSect; struct sSection **ppSect = &pSections;
ppSect = &pSections;
while (*ppSect) while (*ppSect)
ppSect = &((*ppSect)->pNext); ppSect = &((*ppSect)->pNext);
@@ -94,10 +92,11 @@ AddNeededModules(void)
if (!addmodulecontaining(smartlinkstartsymbol)) { if (!addmodulecontaining(smartlinkstartsymbol)) {
errx(1, "Can't find start symbol '%s'", errx(1, "Can't find start symbol '%s'",
smartlinkstartsymbol); smartlinkstartsymbol);
} else } else {
printf("Smart linking with symbol '%s'\n", printf("Smart linking with symbol '%s'\n",
smartlinkstartsymbol); smartlinkstartsymbol);
} }
}
pSect = pSections; pSect = pSections;
while (pSect) { while (pSect) {
@@ -106,10 +105,8 @@ AddNeededModules(void)
for (i = 0; i < pSect->nNumberOfSymbols; i += 1) { for (i = 0; i < pSect->nNumberOfSymbols; i += 1) {
if ((pSect->tSymbols[i]->Type == SYM_IMPORT) if ((pSect->tSymbols[i]->Type == SYM_IMPORT)
|| (pSect->tSymbols[i]->Type == SYM_LOCAL)) { || (pSect->tSymbols[i]->Type == SYM_LOCAL)) {
if (!symboldefined(pSect->tSymbols[i]->pzName)) { if (!symboldefined(pSect->tSymbols[i]->pzName))
addmodulecontaining(pSect->tSymbols[i]-> addmodulecontaining(pSect->tSymbols[i]->pzName);
pzName);
}
} }
} }
pSect = pSect->pNext; pSect = pSect->pNext;

View File

@@ -6,6 +6,7 @@
#include "extern/err.h" #include "extern/err.h"
#include "extern/version.h" #include "extern/version.h"
#include "link/object.h" #include "link/object.h"
#include "link/output.h" #include "link/output.h"
#include "link/assign.h" #include "link/assign.h"
@@ -22,17 +23,15 @@ enum eBlockType {
BLOCK_OUTPUT BLOCK_OUTPUT
}; };
int32_t options = 0; int32_t options;
int32_t fillchar = 0; int32_t fillchar;
char *smartlinkstartsymbol; char *smartlinkstartsymbol;
/* /*
* Print the usagescreen * Print the usagescreen
*
*/ */
static void static void print_usage(void)
usage(void)
{ {
printf( printf(
"usage: rgblink [-dtVw] [-l linkerscript] [-m mapfile] [-n symfile] [-O overlay]\n" "usage: rgblink [-dtVw] [-l linkerscript] [-m mapfile] [-n symfile] [-O overlay]\n"
@@ -42,17 +41,15 @@ usage(void)
/* /*
* The main routine * The main routine
*
*/ */
int int main(int argc, char *argv[])
main(int argc, char *argv[])
{ {
int ch; int ch;
char *ep; char *ep;
if (argc == 1) if (argc == 1)
usage(); print_usage();
while ((ch = getopt(argc, argv, "dl:m:n:O:o:p:s:tVw")) != -1) { while ((ch = getopt(argc, argv, "dl:m:n:O:o:p:s:tVw")) != -1) {
switch (ch) { switch (ch) {
@@ -74,12 +71,10 @@ main(int argc, char *argv[])
break; break;
case 'p': case 'p':
fillchar = strtoul(optarg, &ep, 0); fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') { if (optarg[0] == '\0' || *ep != '\0')
errx(1, "Invalid argument for option 'p'"); errx(1, "Invalid argument for option 'p'");
} if (fillchar < 0 || fillchar > 0xFF)
if (fillchar < 0 || fillchar > 0xFF) {
errx(1, "Argument for option 'p' must be between 0 and 0xFF"); errx(1, "Argument for option 'p' must be between 0 and 0xFF");
}
break; break;
case 's': case 's':
options |= OPT_SMART_C_LINK; options |= OPT_SMART_C_LINK;
@@ -101,17 +96,19 @@ main(int argc, char *argv[])
options |= OPT_DMG_MODE; options |= OPT_DMG_MODE;
/* FALLTHROUGH */ /* FALLTHROUGH */
case 'w': case 'w':
/* Set to set WRAM as a single continuous block as on /*
* Set to set WRAM as a single continuous block as on
* DMG. All WRAM sections must be WRAM0 as bankable WRAM * DMG. All WRAM sections must be WRAM0 as bankable WRAM
* sections do not exist in this mode. A WRAMX section * sections do not exist in this mode. A WRAMX section
* will raise an error. */ * will raise an error.
*/
options |= OPT_CONTWRAM; options |= OPT_CONTWRAM;
break; break;
case 'V': case 'V':
printf("rgblink %s\n", get_package_version_string()); printf("rgblink %s\n", get_package_version_string());
exit(0); exit(0);
default: default:
usage(); print_usage();
/* NOTREACHED */ /* NOTREACHED */
} }
} }
@@ -119,7 +116,7 @@ main(int argc, char *argv[])
argv += optind; argv += optind;
if (argc == 0) if (argc == 0)
usage(); print_usage();
for (int32_t i = 0; i < argc; ++i) for (int32_t i = 0; i < argc; ++i)
obj_Readfile(argv[i]); obj_Readfile(argv[i]);
@@ -131,5 +128,5 @@ main(int argc, char *argv[])
Output(); Output();
CloseMapfile(); CloseMapfile();
return (0); return 0;
} }

View File

@@ -5,39 +5,35 @@
#include <string.h> #include <string.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/main.h" #include "link/main.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/assign.h" #include "link/assign.h"
FILE *mf = NULL; static int32_t currentbank;
FILE *sf = NULL; static int32_t sfbank;
int32_t currentbank = 0; static FILE *mf;
int32_t sfbank; static FILE *sf;
void void SetMapfileName(char *name)
SetMapfileName(char *name)
{ {
mf = fopen(name, "w"); mf = fopen(name, "w");
if (mf == NULL) { if (mf == NULL)
err(1, "Cannot open mapfile '%s'", name); err(1, "Cannot open mapfile '%s'", name);
} }
}
void void SetSymfileName(char *name)
SetSymfileName(char *name)
{ {
sf = fopen(name, "w"); sf = fopen(name, "w");
if (sf == NULL) { if (sf == NULL)
err(1, "Cannot open symfile '%s'", name); err(1, "Cannot open symfile '%s'", name);
}
fprintf(sf, "; File generated by rgblink\n\n"); fprintf(sf, "; File generated by rgblink\n\n");
} }
void void CloseMapfile(void)
CloseMapfile(void)
{ {
if (mf) { if (mf) {
fclose(mf); fclose(mf);
@@ -49,8 +45,7 @@ CloseMapfile(void)
} }
} }
void void MapfileInitBank(int32_t bank)
MapfileInitBank(int32_t bank)
{ {
if (mf) { if (mf) {
currentbank = bank; currentbank = bank;
@@ -91,8 +86,7 @@ MapfileInitBank(int32_t bank)
} }
} }
void void MapfileWriteSection(const struct sSection *pSect)
MapfileWriteSection(struct sSection * pSect)
{ {
int32_t i; int32_t i;
@@ -108,10 +102,9 @@ MapfileWriteSection(struct sSection * pSect)
} }
for (i = 0; i < pSect->nNumberOfSymbols; i += 1) { for (i = 0; i < pSect->nNumberOfSymbols; i += 1) {
struct sSymbol *pSym; const struct sSymbol *pSym = pSect->tSymbols[i];
pSym = pSect->tSymbols[i];
if ((pSym->pSection == pSect) if ((pSym->pSection == pSect) && (pSym->Type != SYM_IMPORT)) {
&& (pSym->Type != SYM_IMPORT)) {
if (mf) { if (mf) {
fprintf(mf, " $%04X = %s\n", fprintf(mf, " $%04X = %s\n",
pSym->nOffset + pSect->nOrg, pSym->nOffset + pSect->nOrg,
@@ -126,8 +119,7 @@ MapfileWriteSection(struct sSection * pSect)
} }
} }
void void MapfileCloseBank(int32_t slack)
MapfileCloseBank(int32_t slack)
{ {
if (!mf) if (!mf)
return; return;

View File

@@ -1,6 +1,5 @@
/* /*
* Here we have the routines that read an objectfile * Here we have the routines that read an objectfile
*
*/ */
#include <ctype.h> #include <ctype.h>
@@ -11,24 +10,23 @@
#include <string.h> #include <string.h>
#include "common.h" #include "common.h"
#include "extern/err.h" #include "extern/err.h"
#include "link/assign.h" #include "link/assign.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/main.h" #include "link/main.h"
struct sSymbol **tSymbols; struct sSymbol **tSymbols;
struct sSection *pSections = NULL; struct sSection *pSections;
struct sSection *pLibSections = NULL; struct sSection *pLibSections;
uint8_t dummymem; uint8_t dummymem;
uint8_t oReadLib = 0; uint8_t oReadLib;
/* /*
* The usual byte order stuff * Read 32-bit values with the correct endianness
*
*/ */
static int32_t readlong(FILE *f)
int32_t
readlong(FILE * f)
{ {
int32_t r; int32_t r;
@@ -37,26 +35,13 @@ readlong(FILE * f)
r |= fgetc(f) << 16; r |= fgetc(f) << 16;
r |= fgetc(f) << 24; r |= fgetc(f) << 24;
return (r); return r;
}
uint16_t
readword(FILE * f)
{
uint16_t r;
r = fgetc(f);
r |= fgetc(f) << 8;
return (r);
} }
/* /*
* Read a NULL terminated string from a file * Read a NULL terminated string from a file
*
*/ */
int32_t int32_t readasciiz(char **dest, FILE *f)
readasciiz(char **dest, FILE *f)
{ {
size_t r = 0; size_t r = 0;
@@ -64,9 +49,8 @@ readasciiz(char **dest, FILE *f)
char *start = malloc(bufferLength); char *start = malloc(bufferLength);
char *s = start; char *s = start;
if (!s) { if (!s)
err(1, NULL); err(1, NULL);
}
while (((*s++) = fgetc(f)) != 0) { while (((*s++) = fgetc(f)) != 0) {
r += 1; r += 1;
@@ -74,9 +58,8 @@ readasciiz(char **dest, FILE *f)
if (r >= bufferLength) { if (r >= bufferLength) {
bufferLength *= 2; bufferLength *= 2;
start = realloc(start, bufferLength); start = realloc(start, bufferLength);
if (!start) { if (!start)
err(1, NULL); err(1, NULL);
}
s = start + r; s = start + r;
} }
} }
@@ -87,11 +70,8 @@ readasciiz(char **dest, FILE *f)
/* /*
* Allocate a new section and link it into the list * Allocate a new section and link it into the list
*
*/ */
struct sSection *AllocSection(void)
struct sSection *
AllocSection(void)
{ {
struct sSection **ppSections; struct sSection **ppSections;
@@ -104,29 +84,26 @@ AllocSection(void)
ppSections = &((*ppSections)->pNext); ppSections = &((*ppSections)->pNext);
*ppSections = malloc(sizeof **ppSections); *ppSections = malloc(sizeof **ppSections);
if (!*ppSections) { if (!*ppSections)
err(1, NULL); err(1, NULL);
}
(*ppSections)->tSymbols = tSymbols; (*ppSections)->tSymbols = tSymbols;
(*ppSections)->pNext = NULL; (*ppSections)->pNext = NULL;
(*ppSections)->pPatches = NULL; (*ppSections)->pPatches = NULL;
(*ppSections)->oAssigned = 0; (*ppSections)->oAssigned = 0;
return *ppSections; return *ppSections;
} }
/* /*
* Read a symbol from a file * 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; struct sSymbol *pSym;
pSym = malloc(sizeof *pSym); pSym = malloc(sizeof(*pSym));
if (!pSym) { if (!pSym)
err(1, NULL); err(1, NULL);
}
readasciiz(&pSym->pzName, f); readasciiz(&pSym->pzName, f);
pSym->Type = (enum eSymbolType)fgetc(f); pSym->Type = (enum eSymbolType)fgetc(f);
@@ -140,19 +117,18 @@ obj_ReadSymbol(FILE * f, char *tzObjectfile)
pSym->nSectionID = readlong(f); pSym->nSectionID = readlong(f);
pSym->nOffset = readlong(f); pSym->nOffset = readlong(f);
} }
return pSym; return pSym;
} }
/* /*
* RGB object reader routines * RGB object reader routines
*
*/ */
struct sSection * struct sSection *obj_ReadRGBSection(FILE *f)
obj_ReadRGBSection(FILE * f)
{ {
struct sSection *pSection; struct sSection *pSection;
char *pzName; char *pzName;
readasciiz(&pzName, f); readasciiz(&pzName, f);
if (IsSectionNameInUse(pzName)) if (IsSectionNameInUse(pzName))
errx(1, "Section name \"%s\" is already in use.", pzName); errx(1, "Section name \"%s\" is already in use.", pzName);
@@ -166,24 +142,22 @@ obj_ReadRGBSection(FILE * f)
pSection->nBank = readlong(f); pSection->nBank = readlong(f);
pSection->nAlign = 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."); 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."); errx(1, "WRAMX sections can't be used with options -w or -d.");
}
if (options & OPT_DMG_MODE) { if (options & OPT_DMG_MODE) {
/* WRAMX sections are checked for OPT_CONTWRAM */ /* 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."); errx(1, "VRAM bank 1 can't be used with option -d.");
} }
}
uint32_t maxsize = 0; uint32_t maxsize = 0;
/* Verify that the section isn't too big */ /* Verify that the section isn't too big */
switch (pSection->Type) switch (pSection->Type) {
{
case SECT_ROM0: case SECT_ROM0:
maxsize = (options & OPT_TINY) ? 0x8000 : 0x4000; maxsize = (options & OPT_TINY) ? 0x8000 : 0x4000;
break; break;
@@ -215,22 +189,29 @@ obj_ReadRGBSection(FILE * f)
pzName, pSection->nByteSize, maxsize); pzName, pSection->nByteSize, maxsize);
} }
if ((pSection->Type == SECT_ROMX) || (pSection->Type == SECT_ROM0)) {
/* /*
* These sectiontypes contain data... * If the section doesn't contain data, it is ready
*
*/ */
if (pSection->nByteSize) { if ((pSection->Type != SECT_ROMX) && (pSection->Type != SECT_ROM0))
pSection->pData = malloc(pSection->nByteSize); return pSection;
if (!pSection->pData) {
err(1, NULL); /* 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; int32_t nNumberOfPatches;
struct sPatch **ppPatch, *pPatch; struct sPatch **ppPatch, *pPatch;
if (fread(pSection->pData, sizeof(uint8_t), if (fread(pSection->pData, sizeof(uint8_t), pSection->nByteSize, f)
pSection->nByteSize, f) != pSection->nByteSize) { != pSection->nByteSize) {
err(1, "Read error."); err(1, "Read error.");
} }
@@ -239,46 +220,40 @@ obj_ReadRGBSection(FILE * f)
/* /*
* And patches... * And patches...
*
*/ */
while (nNumberOfPatches--) { while (nNumberOfPatches--) {
pPatch = malloc(sizeof *pPatch); pPatch = malloc(sizeof(*pPatch));
if (!pPatch) { if (!pPatch)
err(1, NULL); err(1, NULL);
}
*ppPatch = pPatch; *ppPatch = pPatch;
readasciiz(&pPatch->pzFilename, f); readasciiz(&pPatch->pzFilename, f);
pPatch->nLineNo = readlong(f); pPatch->nLineNo = readlong(f);
pPatch->nOffset = readlong(f); pPatch->nOffset = readlong(f);
pPatch->Type = (enum ePatchType)fgetc(f); pPatch->Type = (enum ePatchType)fgetc(f);
if ((pPatch->nRPNSize = readlong(f)) > 0) { pPatch->nRPNSize = readlong(f);
if (pPatch->nRPNSize > 0) {
pPatch->pRPN = malloc(pPatch->nRPNSize); pPatch->pRPN = malloc(pPatch->nRPNSize);
if (!pPatch->pRPN) { if (!pPatch->pRPN)
err(1, NULL); err(1, NULL);
}
if (fread(pPatch->pRPN, sizeof(uint8_t), if (fread(pPatch->pRPN, sizeof(uint8_t),
pPatch->nRPNSize, f) != pPatch->nRPNSize) { pPatch->nRPNSize, f) != pPatch->nRPNSize) {
errx(1, "Read error."); errx(1, "Read error.");
} }
} else } else {
pPatch->pRPN = NULL; pPatch->pRPN = NULL;
}
pPatch->pNext = NULL; pPatch->pNext = NULL;
ppPatch = &(pPatch->pNext); ppPatch = &(pPatch->pNext);
} }
} else {
/* Skip number of patches */
readlong(f);
pSection->pData = &dummymem;
}
}
return pSection; return pSection;
} }
void void obj_ReadRGB(FILE *pObjfile, char *tzObjectfile)
obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
{ {
struct sSection *pFirstSection; struct sSection *pFirstSection;
int32_t nNumberOfSymbols, nNumberOfSections, i; int32_t nNumberOfSymbols, nNumberOfSections, i;
@@ -289,15 +264,15 @@ obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
/* First comes the symbols */ /* First comes the symbols */
if (nNumberOfSymbols) { if (nNumberOfSymbols) {
tSymbols = malloc(nNumberOfSymbols * sizeof *tSymbols); tSymbols = malloc(nNumberOfSymbols * sizeof(*tSymbols));
if (!tSymbols) { if (!tSymbols)
err(1, NULL); err(1, NULL);
}
for (i = 0; i < nNumberOfSymbols; i += 1) for (i = 0; i < nNumberOfSymbols; i += 1)
tSymbols[i] = obj_ReadSymbol(pObjfile, tzObjectfile); tSymbols[i] = obj_ReadSymbol(pObjfile, tzObjectfile);
} else } else {
tSymbols = (struct sSymbol **)&dummymem; tSymbols = (struct sSymbol **)&dummymem;
}
/* Next we have the sections */ /* Next we have the sections */
@@ -314,31 +289,30 @@ obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
/* /*
* Fill in the pSection entry in the symbolstructure. * Fill in the pSection entry in the symbolstructure.
* This REALLY needs some cleaning up... but, hey, it works * This REALLY needs some cleaning up... but, hey, it works
*
*/ */
for (i = 0; i < nNumberOfSymbols; i += 1) { for (i = 0; i < nNumberOfSymbols; i += 1) {
struct sSection *pConvSect = pFirstSection; struct sSection *pConvSect = pFirstSection;
if (tSymbols[i]->Type != SYM_IMPORT if ((tSymbols[i]->Type != SYM_IMPORT) &&
&& tSymbols[i]->nSectionID != -1) { (tSymbols[i]->nSectionID != -1)) {
int32_t j = 0; int32_t j = 0;
while (j != tSymbols[i]->nSectionID) { while (j != tSymbols[i]->nSectionID) {
j += 1; j += 1;
pConvSect = pConvSect->pNext; pConvSect = pConvSect->pNext;
} }
tSymbols[i]->pSection = pConvSect; tSymbols[i]->pSection = pConvSect;
} else } else {
tSymbols[i]->pSection = NULL; tSymbols[i]->pSection = NULL;
} }
} }
}
/* /*
* The main objectfileloadroutine (phew) * 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]; char tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING) + 1];
@@ -353,16 +327,18 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) { strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) {
obj_ReadRGB(pObjfile, tzObjectfile); obj_ReadRGB(pObjfile, tzObjectfile);
} else { } 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])) if (!isprint(tzHeader[i]))
tzHeader[i] = '?'; tzHeader[i] = '?';
errx(1, "%s: Invalid file or object file version [%s]", errx(1, "%s: Invalid file or object file version [%s]",
tzObjectfile, tzHeader); tzObjectfile, tzHeader);
} }
} }
void void obj_Readfile(char *tzObjectfile)
obj_Readfile(char *tzObjectfile)
{ {
FILE *pObjfile; FILE *pObjfile;
@@ -372,17 +348,16 @@ obj_Readfile(char *tzObjectfile)
oReadLib = 0; oReadLib = 0;
pObjfile = fopen(tzObjectfile, "rb"); pObjfile = fopen(tzObjectfile, "rb");
if (pObjfile == NULL) { if (pObjfile == NULL)
err(1, "Unable to open object '%s'", tzObjectfile); err(1, "Unable to open object '%s'", tzObjectfile);
}
obj_ReadOpenFile(pObjfile, tzObjectfile); obj_ReadOpenFile(pObjfile, tzObjectfile);
fclose(pObjfile); fclose(pObjfile);
oReadLib = 0; oReadLib = 0;
} }
int32_t int32_t file_Length(FILE *f)
file_Length(FILE * f)
{ {
uint32_t r, p; uint32_t r, p;
@@ -391,5 +366,5 @@ file_Length(FILE * f)
r = ftell(f); r = ftell(f);
fseek(f, p, SEEK_SET); fseek(f, p, SEEK_SET);
return (r); return r;
} }

View File

@@ -4,20 +4,20 @@
#include <string.h> #include <string.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/mapfile.h" #include "link/mapfile.h"
#include "link/main.h" #include "link/main.h"
#include "link/assign.h" #include "link/assign.h"
char *tzOutname; char *tzOutname;
char *tzOverlayname = NULL; char *tzOverlayname;
int32_t MaxOverlayBank; int32_t MaxOverlayBank;
void void writehome(FILE *f, FILE *f_overlay)
writehome(FILE * f, FILE * f_overlay)
{ {
struct sSection *pSect; const struct sSection *pSect;
uint8_t *mem; uint8_t *mem;
mem = malloc(MaxAvail[BANK_ROM0]); mem = malloc(MaxAvail[BANK_ROM0]);
@@ -51,10 +51,9 @@ writehome(FILE * f, FILE * f_overlay)
free(mem); free(mem);
} }
void void writebank(FILE *f, FILE *f_overlay, int32_t bank)
writebank(FILE * f, FILE * f_overlay, int32_t bank)
{ {
struct sSection *pSect; const struct sSection *pSect;
uint8_t *mem; uint8_t *mem;
mem = malloc(MaxAvail[bank]); mem = malloc(MaxAvail[bank]);
@@ -63,10 +62,8 @@ writebank(FILE * f, FILE * f_overlay, int32_t bank)
if (f_overlay != NULL && bank <= MaxOverlayBank) { if (f_overlay != NULL && bank <= MaxOverlayBank) {
fseek(f_overlay, bank * 0x4000, SEEK_SET); fseek(f_overlay, bank * 0x4000, SEEK_SET);
if (fread(mem, 1, MaxAvail[bank], f_overlay) != if (fread(mem, 1, MaxAvail[bank], f_overlay) != MaxAvail[bank])
MaxAvail[bank]) {
warnx("Failed to read data from overlay file."); warnx("Failed to read data from overlay file.");
}
} else { } else {
memset(mem, fillchar, MaxAvail[bank]); memset(mem, fillchar, MaxAvail[bank]);
} }
@@ -88,44 +85,50 @@ writebank(FILE * f, FILE * f_overlay, int32_t bank)
free(mem); free(mem);
} }
void void out_Setname(char *tzOutputfile)
out_Setname(char *tzOutputfile)
{ {
tzOutname = tzOutputfile; tzOutname = tzOutputfile;
} }
void void out_SetOverlayname(char *tzOverlayfile)
out_SetOverlayname(char *tzOverlayfile)
{ {
tzOverlayname = tzOverlayfile; tzOverlayname = tzOverlayfile;
} }
void Output(void)
void
Output(void)
{ {
int32_t i; int32_t i;
FILE *f; FILE *f;
FILE *f_overlay = NULL; FILE *f_overlay = NULL;
if ((f = fopen(tzOutname, "wb"))) { /*
* Apply overlay
*/
f = fopen(tzOutname, "wb");
if (f != NULL) {
if (tzOverlayname) { if (tzOverlayname) {
f_overlay = fopen(tzOverlayname, "rb"); f_overlay = fopen(tzOverlayname, "rb");
if (!f_overlay) { if (!f_overlay) {
errx(1, "Failed to open overlay file %s\n", tzOverlayname); errx(1, "Failed to open overlay file %s\n",
tzOverlayname);
} }
fseek(f_overlay, 0, SEEK_END); fseek(f_overlay, 0, SEEK_END);
if (ftell(f_overlay) % 0x4000 != 0) {
if (ftell(f_overlay) % 0x4000 != 0)
errx(1, "Overlay file must be aligned to 0x4000 bytes."); errx(1, "Overlay file must be aligned to 0x4000 bytes.");
}
MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1; MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1;
if (MaxOverlayBank < 1) {
if (MaxOverlayBank < 1)
errx(1, "Overlay file must be at least 0x8000 bytes."); errx(1, "Overlay file must be at least 0x8000 bytes.");
}
if (MaxOverlayBank > MaxBankUsed) { if (MaxOverlayBank > MaxBankUsed)
MaxBankUsed = MaxOverlayBank; MaxBankUsed = MaxOverlayBank;
} }
}
writehome(f, f_overlay); writehome(f, f_overlay);
for (i = 1; i <= MaxBankUsed; i += 1) for (i = 1; i <= MaxBankUsed; i += 1)
@@ -133,18 +136,22 @@ Output(void)
fclose(f); fclose(f);
if (tzOverlayname) { if (tzOverlayname)
fclose(f_overlay); fclose(f_overlay);
} }
}
/*
* Add regular sections
*/
for (i = BANK_WRAM0; i < MAXBANKS; i++) { for (i = BANK_WRAM0; i < MAXBANKS; i++) {
struct sSection *pSect; const struct sSection *pSect;
MapfileInitBank(i); MapfileInitBank(i);
pSect = pSections; pSect = pSections;
while (pSect) { while (pSect) {
if (pSect->nBank == i) { if (pSect->nBank == i)
MapfileWriteSection(pSect); MapfileWriteSection(pSect);
}
pSect = pSect->pNext; pSect = pSect->pNext;
} }
MapfileCloseBank(area_Avail(i)); MapfileCloseBank(area_Avail(i));

View File

@@ -19,6 +19,7 @@
#include <stdio.h> #include <stdio.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/script.h" #include "link/script.h"
int yylex(); int yylex();
@@ -27,7 +28,10 @@ void yyerror(char *);
extern int yylineno; extern int yylineno;
%} %}
%union { int32_t i; char s[512]; } %union {
int32_t i;
char s[512];
}
%token<i> INTEGER %token<i> INTEGER
%token<s> STRING %token<s> STRING
@@ -58,41 +62,51 @@ line:
statement: statement:
/* Statements to set the current section */ /* Statements to set the current section */
SECTION_NONBANKED { SECTION_NONBANKED
{
script_SetCurrentSectionType($1, 0); script_SetCurrentSectionType($1, 0);
} }
| SECTION_NONBANKED INTEGER { | SECTION_NONBANKED INTEGER
{
script_fatalerror("Trying to assign a bank to a non-banked section.\n"); script_fatalerror("Trying to assign a bank to a non-banked section.\n");
} }
| SECTION_BANKED { | SECTION_BANKED
{
script_fatalerror("Banked section without assigned bank.\n"); script_fatalerror("Banked section without assigned bank.\n");
} }
| SECTION_BANKED INTEGER { | SECTION_BANKED INTEGER
{
script_SetCurrentSectionType($1, $2); script_SetCurrentSectionType($1, $2);
} }
/* Commands to adjust the address inside the current section */ /* Commands to adjust the address inside the current section */
| COMMAND_ALIGN INTEGER { | COMMAND_ALIGN INTEGER
{
script_SetAlignment($2); script_SetAlignment($2);
} }
| COMMAND_ALIGN { | COMMAND_ALIGN
{
script_fatalerror("ALIGN keyword needs an argument.\n"); script_fatalerror("ALIGN keyword needs an argument.\n");
} }
| COMMAND_ORG INTEGER { | COMMAND_ORG INTEGER
{
script_SetAddress($2); script_SetAddress($2);
} }
| COMMAND_ORG { | COMMAND_ORG
{
script_fatalerror("ORG keyword needs an argument.\n"); script_fatalerror("ORG keyword needs an argument.\n");
} }
/* Section name */ /* Section name */
| STRING { | STRING
{
script_OutputSection($1); script_OutputSection($1);
} }
/* Include file */ /* Include file */
| COMMAND_INCLUDE STRING { | COMMAND_INCLUDE STRING
{
script_IncludeFile($2); script_IncludeFile($2);
} }

View File

@@ -4,87 +4,83 @@
#include <string.h> #include <string.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/assign.h" #include "link/assign.h"
#include "link/main.h"
#include "link/mylink.h" #include "link/mylink.h"
#include "link/symbol.h" #include "link/symbol.h"
#include "link/main.h"
struct sSection *pCurrentSection; static struct sSection *pCurrentSection;
int32_t rpnstack[256]; static int32_t rpnstack[256];
int32_t rpnp; static int32_t rpnp;
int32_t nPC; int32_t nPC;
void static void rpnpush(int32_t i)
rpnpush(int32_t i)
{ {
rpnstack[rpnp++] = i; rpnstack[rpnp] = i;
rpnp++;
} }
int32_t static int32_t rpnpop(void)
rpnpop(void)
{ {
return (rpnstack[--rpnp]); rpnp--;
return rpnstack[rpnp];
} }
int32_t int32_t getsymvalue(int32_t symid)
getsymvalue(int32_t symid)
{ {
switch (pCurrentSection->tSymbols[symid]->Type) { const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
switch (tSymbol->Type) {
case SYM_IMPORT: case SYM_IMPORT:
return (sym_GetValue(pCurrentSection->tSymbols[symid]->pzName)); return sym_GetValue(tSymbol->pzName);
break;
case SYM_EXPORT: case SYM_EXPORT:
case SYM_LOCAL: case SYM_LOCAL:
{ if (strcmp(tSymbol->pzName, "@") == 0)
if (strcmp return nPC;
(pCurrentSection->tSymbols[symid]->pzName,
"@") == 0) { return tSymbol->nOffset + tSymbol->pSection->nOrg;
return (nPC);
} else
return (pCurrentSection->tSymbols[symid]->
nOffset +
pCurrentSection->tSymbols[symid]->
pSection->nOrg);
}
default: default:
break; break;
} }
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
errx(1, "%s: Unknown symbol type", __func__);
} }
int32_t int32_t getsymbank(int32_t symid)
getsymbank(int32_t symid)
{ {
int32_t nBank; int32_t n;
const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
switch (pCurrentSection->tSymbols[symid]->Type) { switch (tSymbol->Type) {
case SYM_IMPORT: case SYM_IMPORT:
nBank = sym_GetBank(pCurrentSection->tSymbols[symid]->pzName); n = sym_GetBank(tSymbol->pzName);
break; break;
case SYM_EXPORT: case SYM_EXPORT:
case SYM_LOCAL: case SYM_LOCAL:
nBank = pCurrentSection->tSymbols[symid]->pSection->nBank; n = tSymbol->pSection->nBank;
break; break;
default: default:
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE"); errx(1, "%s: Unknown symbol type", __func__);
} }
if (nBank == BANK_WRAM0 || nBank == BANK_ROM0 || nBank == BANK_OAM || if ((n == BANK_WRAM0) || (n == BANK_ROM0) || (n == BANK_OAM) ||
nBank == BANK_HRAM) { (n == BANK_HRAM)) {
return 0; return 0;
} else if (nBank >= BANK_WRAMX && nBank < (BANK_WRAMX + BANK_COUNT_WRAMX)) { } else if ((n >= BANK_WRAMX) && (n < (BANK_WRAMX + BANK_COUNT_WRAMX))) {
return nBank - BANK_WRAMX + 1; return n - BANK_WRAMX + 1;
} else if (nBank >= BANK_VRAM && nBank < (BANK_VRAM + BANK_COUNT_VRAM)) { } else if ((n >= BANK_VRAM) && (n < (BANK_VRAM + BANK_COUNT_VRAM))) {
return nBank - BANK_VRAM; return n - BANK_VRAM;
} else if (nBank >= BANK_SRAM && nBank < (BANK_SRAM + BANK_COUNT_SRAM)) { } else if ((n >= BANK_SRAM) && (n < (BANK_SRAM + BANK_COUNT_SRAM))) {
return nBank - BANK_SRAM; return n - BANK_SRAM;
} }
return nBank; return n;
} }
int32_t int32_t calcrpn(struct sPatch *pPatch)
calcrpn(struct sPatch * pPatch)
{ {
int32_t t, size; int32_t t, size;
uint8_t *rpn; uint8_t *rpn;
@@ -209,11 +205,10 @@ calcrpn(struct sPatch * pPatch)
break; break;
} }
} }
return (rpnpop()); return rpnpop();
} }
void void Patch(void)
Patch(void)
{ {
struct sSection *pSect; struct sSection *pSect;

View File

@@ -34,15 +34,15 @@ static int32_t current_real_bank = -1; /* bank as seen by the GB */
void script_InitSections(void) void script_InitSections(void)
{ {
int32_t i; int32_t i;
for (i = 0; i < MAXBANKS; i++) { for (i = 0; i < MAXBANKS; i++) {
if (i == BANK_ROM0) { if (i == BANK_ROM0) {
/* ROM0 bank */ /* ROM0 bank */
bank[i].address = 0x0000; bank[i].address = 0x0000;
if (options & OPT_TINY) { if (options & OPT_TINY)
bank[i].top_address = 0x8000; bank[i].top_address = 0x8000;
} else { else
bank[i].top_address = 0x4000; bank[i].top_address = 0x4000;
}
bank[i].type = SECT_ROM0; bank[i].type = SECT_ROM0;
} else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) { } else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) {
/* Swappable ROM bank */ /* Swappable ROM bank */
@@ -52,11 +52,10 @@ void script_InitSections(void)
} else if (i == BANK_WRAM0) { } else if (i == BANK_WRAM0) {
/* WRAM */ /* WRAM */
bank[i].address = 0xC000; bank[i].address = 0xC000;
if (options & OPT_CONTWRAM) { if (options & OPT_CONTWRAM)
bank[i].top_address = 0xE000; bank[i].top_address = 0xE000;
} else { else
bank[i].top_address = 0xD000; bank[i].top_address = 0xD000;
}
bank[i].type = SECT_WRAM0; bank[i].type = SECT_WRAM0;
} else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) { } else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) {
/* Swappable SRAM bank */ /* Swappable SRAM bank */
@@ -105,14 +104,18 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
} else if (strcmp(type, "ROMX") == 0) { } else if (strcmp(type, "ROMX") == 0) {
if (bank == 0) if (bank == 0)
errx(1, "ROMX index can't be 0.\n"); errx(1, "ROMX index can't be 0.\n");
if (bank > BANK_COUNT_ROMX) if (bank > BANK_COUNT_ROMX) {
errx(1, "ROMX index too big (%d > %d).\n", bank, BANK_COUNT_ROMX); errx(1, "ROMX index too big (%d > %d).\n", bank,
BANK_COUNT_ROMX);
}
current_bank = BANK_ROMX + bank - 1; current_bank = BANK_ROMX + bank - 1;
current_real_bank = bank; current_real_bank = bank;
return; return;
} else if (strcmp(type, "VRAM") == 0) { } else if (strcmp(type, "VRAM") == 0) {
if (bank >= BANK_COUNT_VRAM) if (bank >= BANK_COUNT_VRAM) {
errx(1, "VRAM index too big (%d >= %d).\n", bank, BANK_COUNT_VRAM); errx(1, "VRAM index too big (%d >= %d).\n", bank,
BANK_COUNT_VRAM);
}
current_bank = BANK_VRAM + bank; current_bank = BANK_VRAM + bank;
current_real_bank = bank; current_real_bank = bank;
return; return;
@@ -125,14 +128,18 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
} else if (strcmp(type, "WRAMX") == 0) { } else if (strcmp(type, "WRAMX") == 0) {
if (bank == 0) if (bank == 0)
errx(1, "WRAMX index can't be 0.\n"); errx(1, "WRAMX index can't be 0.\n");
if (bank > BANK_COUNT_WRAMX) if (bank > BANK_COUNT_WRAMX) {
errx(1, "WRAMX index too big (%d > %d).\n", bank, BANK_COUNT_WRAMX); errx(1, "WRAMX index too big (%d > %d).\n", bank,
BANK_COUNT_WRAMX);
}
current_bank = BANK_WRAMX + bank - 1; current_bank = BANK_WRAMX + bank - 1;
current_real_bank = bank - 1; current_real_bank = bank - 1;
return; return;
} else if (strcmp(type, "SRAM") == 0) { } else if (strcmp(type, "SRAM") == 0) {
if (bank >= BANK_COUNT_SRAM) if (bank >= BANK_COUNT_SRAM) {
errx(1, "SRAM index too big (%d >= %d).\n", bank, BANK_COUNT_SRAM); errx(1, "SRAM index too big (%d >= %d).\n", bank,
BANK_COUNT_SRAM);
}
current_bank = BANK_SRAM + bank; current_bank = BANK_SRAM + bank;
current_real_bank = bank; current_real_bank = bank;
return; return;
@@ -155,9 +162,8 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
void script_SetAddress(uint32_t addr) void script_SetAddress(uint32_t addr)
{ {
if (current_bank == -1) { if (current_bank == -1)
errx(1, "Trying to set an address without assigned bank\n"); errx(1, "Trying to set an address without assigned bank\n");
}
/* Make sure that we don't go back. */ /* Make sure that we don't go back. */
if (bank[current_bank].address > addr) { if (bank[current_bank].address > addr) {
@@ -170,19 +176,18 @@ void script_SetAddress(uint32_t addr)
/* Make sure we don't overflow */ /* Make sure we don't overflow */
if (bank[current_bank].address >= bank[current_bank].top_address) { if (bank[current_bank].address >= bank[current_bank].top_address) {
errx(1, "Bank overflowed (0x%04X >= 0x%04X)\n", errx(1, "Bank overflowed (0x%04X >= 0x%04X)\n",
bank[current_bank].address, bank[current_bank].top_address); bank[current_bank].address,
bank[current_bank].top_address);
} }
} }
void script_SetAlignment(uint32_t alignment) void script_SetAlignment(uint32_t alignment)
{ {
if (current_bank == -1) { if (current_bank == -1)
errx(1, "Trying to set an alignment without assigned bank\n"); errx(1, "Trying to set an alignment without assigned bank\n");
}
if (alignment > 15) { if (alignment > 15)
errx(1, "Trying to set an alignment too big: %d\n", alignment); errx(1, "Trying to set an alignment too big: %d\n", alignment);
}
uint32_t size = 1 << alignment; uint32_t size = 1 << alignment;
uint32_t mask = size - 1; uint32_t mask = size - 1;
@@ -195,17 +200,20 @@ void script_SetAlignment(uint32_t alignment)
/* Make sure we don't overflow */ /* Make sure we don't overflow */
if (bank[current_bank].address >= bank[current_bank].top_address) { if (bank[current_bank].address >= bank[current_bank].top_address) {
errx(1, "Bank overflowed (0x%04X >= 0x%04X)\n", errx(1, "Bank overflowed (0x%04X >= 0x%04X)\n",
bank[current_bank].address, bank[current_bank].top_address); bank[current_bank].address,
bank[current_bank].top_address);
} }
} }
void script_OutputSection(const char *section_name) void script_OutputSection(const char *section_name)
{ {
if (current_bank == -1) { if (current_bank == -1) {
errx(1, "Trying to place section \"%s\" without assigned bank\n", section_name); errx(1, "Trying to place section \"%s\" without assigned bank\n",
section_name);
} }
if (!IsSectionSameTypeBankAndFloating(section_name, bank[current_bank].type, if (!IsSectionSameTypeBankAndFloating(section_name,
bank[current_bank].type,
current_real_bank)) { current_real_bank)) {
errx(1, "Different attributes for \"%s\" in source and linkerscript\n", errx(1, "Different attributes for \"%s\" in source and linkerscript\n",
section_name); section_name);
@@ -214,6 +222,7 @@ void script_OutputSection(const char *section_name)
/* Move section to its place. */ /* Move section to its place. */
bank[current_bank].address += bank[current_bank].address +=
AssignSectionAddressAndBankByName(section_name, AssignSectionAddressAndBankByName(section_name,
bank[current_bank].address, current_real_bank); bank[current_bank].address,
current_real_bank);
} }

View File

@@ -16,73 +16,70 @@ struct ISymbol {
char *pzName; char *pzName;
int32_t nValue; int32_t nValue;
int32_t nBank; /* -1 = constant */ int32_t nBank; /* -1 = constant */
char tzObjFileName[_MAX_PATH + 1]; /* Object file where the symbol was defined. */ /* Object file where the symbol was defined. */
char tzFileName[_MAX_PATH + 1]; /* Source file where the symbol was defined. */ char tzObjFileName[_MAX_PATH + 1];
uint32_t nFileLine; /* Line where the symbol was defined. */ /* Source file where the symbol was defined. */
char tzFileName[_MAX_PATH + 1];
/* Line where the symbol was defined. */
uint32_t nFileLine;
struct ISymbol *pNext; struct ISymbol *pNext;
}; };
struct ISymbol *tHash[HASHSIZE]; struct ISymbol *tHash[HASHSIZE];
int32_t int32_t calchash(char *s)
calchash(char *s)
{ {
int32_t r = 0; int32_t r = 0;
while (*s) while (*s)
r += *s++; r += *s++;
return (r % HASHSIZE); return r % HASHSIZE;
} }
void void sym_Init(void)
sym_Init(void)
{ {
int32_t i; int32_t i;
for (i = 0; i < HASHSIZE; i += 1) for (i = 0; i < HASHSIZE; i += 1)
tHash[i] = NULL; tHash[i] = NULL;
} }
int32_t int32_t sym_GetValue(char *tzName)
sym_GetValue(char *tzName)
{ {
if (strcmp(tzName, "@") == 0) { if (strcmp(tzName, "@") == 0)
return (nPC); return nPC;
} else {
struct ISymbol **ppSym; struct ISymbol **ppSym;
ppSym = &(tHash[calchash(tzName)]); ppSym = &(tHash[calchash(tzName)]);
while (*ppSym) { while (*ppSym) {
if (strcmp(tzName, (*ppSym)->pzName)) { if (strcmp(tzName, (*ppSym)->pzName))
ppSym = &((*ppSym)->pNext); ppSym = &((*ppSym)->pNext);
} else { else
return ((*ppSym)->nValue); return ((*ppSym)->nValue);
} }
}
errx(1, "Unknown symbol '%s'", tzName); errx(1, "Unknown symbol '%s'", tzName);
} }
}
int32_t int32_t sym_GetBank(char *tzName)
sym_GetBank(char *tzName)
{ {
struct ISymbol **ppSym; struct ISymbol **ppSym;
ppSym = &(tHash[calchash(tzName)]); ppSym = &(tHash[calchash(tzName)]);
while (*ppSym) { while (*ppSym) {
if (strcmp(tzName, (*ppSym)->pzName)) { if (strcmp(tzName, (*ppSym)->pzName))
ppSym = &((*ppSym)->pNext); ppSym = &((*ppSym)->pNext);
} else { else
return ((*ppSym)->nBank); return ((*ppSym)->nBank);
} }
}
errx(1, "Unknown symbol '%s'", tzName); errx(1, "Unknown symbol '%s'", tzName);
} }
void void sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank,
sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank, char *tzObjFileName, char *tzObjFileName, char *tzFileName, uint32_t nFileLine)
char *tzFileName, uint32_t nFileLine)
{ {
if (strcmp(tzName, "@") == 0) if (strcmp(tzName, "@") == 0)
return; return;
@@ -105,8 +102,12 @@ sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank, char *tzObjFileNam
} }
} }
if ((*ppSym = malloc(sizeof **ppSym))) { *ppSym = malloc(sizeof **ppSym);
if (((*ppSym)->pzName = malloc(strlen(tzName) + 1))) {
if (*ppSym != NULL) {
(*ppSym)->pzName = malloc(strlen(tzName) + 1);
if ((*ppSym)->pzName != NULL) {
strcpy((*ppSym)->pzName, tzName); strcpy((*ppSym)->pzName, tzName);
(*ppSym)->nValue = nValue; (*ppSym)->nValue = nValue;
(*ppSym)->nBank = nBank; (*ppSym)->nBank = nBank;