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
};
#define MAXBANKS (BANK_COUNT_ROM0 + BANK_COUNT_ROMX + BANK_COUNT_WRAM0 + BANK_COUNT_WRAMX \
+ BANK_COUNT_VRAM + BANK_COUNT_OAM + BANK_COUNT_HRAM + BANK_COUNT_SRAM)
#define MAXBANKS (BANK_COUNT_ROM0 + BANK_COUNT_ROMX \
+ 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 MaxAvail[MAXBANKS];
@@ -36,17 +38,11 @@ extern int32_t MaxAvail[MAXBANKS];
int32_t area_Avail(int32_t bank);
void AssignSections(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
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
#endif /* RGBDS_LINK_ASSIGN_H */

View File

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

View File

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

View File

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

View File

@@ -82,10 +82,12 @@ enum eSymbolType {
struct sSymbol {
char *pzName;
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;
int32_t nOffset;
char *pzObjFileName; /* Object file where the symbol is located. */
char *pzFileName; /* Source file 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 *pLibSections;
#endif
#endif /* RGBDS_LINK_LINK_H */

View File

@@ -3,4 +3,4 @@
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 Output(void);
#endif
#endif /* RGBDS_LINK_OUTPUT_H */

View File

@@ -6,4 +6,4 @@
void Patch(void);
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_OutputSection(const char *section_name);
#endif
#endif /* RGBDS_LINK_SCRIPT_H */

View File

@@ -5,8 +5,9 @@
void sym_Init(void);
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_GetBank(char *tzName);
#endif
#endif /* RGBDS_LINK_SYMBOL_H */

View File

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

View File

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

View File

@@ -35,9 +35,9 @@ extern int yyparse();
/* File include stack. */
#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 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)
script_fatalerror("String is too long: %s\n.", yytext);
if (strlen(yytext) < 3) /* 2 quotes + 1 character */
script_fatalerror("String %s is invalid\n.", yytext);
if (strlen(yytext) > sizeof(yylval.s) - 1) {
script_fatalerror("String is too long: %s\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);
yylval.s[strlen(yylval.s)-1] = '\0'; /* remove end quote */
/* Remove end quote */
yylval.s[strlen(yylval.s)-1] = '\0';
return STRING;
}
@@ -112,12 +119,11 @@ void script_Parse(const char * path)
} while (!feof(yyin));
fclose(yyin);
}
void script_IncludeFile(const char * path)
{
if (include_stack_ptr == (MAX_INCLUDE_DEPTH-1))
if (include_stack_ptr == (MAX_INCLUDE_DEPTH - 1))
script_fatalerror("Includes nested too deeply.");
include_line[include_stack_ptr] = yylineno;
@@ -125,13 +131,13 @@ void script_IncludeFile(const char * path)
include_stack_ptr++;
yyin = fopen(path, "r" );
yyin = fopen(path, "r");
if (!yyin)
script_fatalerror("Couldn't open file \"%s\"", path);
strncpy(include_path[include_stack_ptr], path, sizeof(include_path[0]));
include_path[include_stack_ptr][sizeof(include_path[0])-1] = '\0';
include_path[include_stack_ptr][sizeof(include_path[0]) - 1] = '\0';
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
yylineno = 1;

View File

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

View File

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

View File

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

View File

@@ -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;
}

View File

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

View File

@@ -19,6 +19,7 @@
#include <stdio.h>
#include "extern/err.h"
#include "link/script.h"
int yylex();
@@ -27,7 +28,10 @@ void yyerror(char *);
extern int yylineno;
%}
%union { int32_t i; char s[512]; }
%union {
int32_t i;
char s[512];
}
%token<i> INTEGER
%token<s> STRING
@@ -49,55 +53,65 @@ extern int yylineno;
lines:
/* empty */
| lines line NEWLINE
;
;
line:
/* empty */
| statement
;
;
statement:
/* Statements to set the current section */
SECTION_NONBANKED {
SECTION_NONBANKED
{
script_SetCurrentSectionType($1, 0);
}
| SECTION_NONBANKED INTEGER {
| SECTION_NONBANKED INTEGER
{
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");
}
| SECTION_BANKED INTEGER {
| SECTION_BANKED INTEGER
{
script_SetCurrentSectionType($1, $2);
}
/* Commands to adjust the address inside the current section */
| COMMAND_ALIGN INTEGER {
| COMMAND_ALIGN INTEGER
{
script_SetAlignment($2);
}
| COMMAND_ALIGN {
| COMMAND_ALIGN
{
script_fatalerror("ALIGN keyword needs an argument.\n");
}
| COMMAND_ORG INTEGER {
| COMMAND_ORG INTEGER
{
script_SetAddress($2);
}
| COMMAND_ORG {
| COMMAND_ORG
{
script_fatalerror("ORG keyword needs an argument.\n");
}
/* Section name */
| STRING {
| STRING
{
script_OutputSection($1);
}
/* Include file */
| COMMAND_INCLUDE STRING {
| COMMAND_INCLUDE STRING
{
script_IncludeFile($2);
}
/* End */
;
;
%%

View File

@@ -4,87 +4,83 @@
#include <string.h>
#include "extern/err.h"
#include "link/assign.h"
#include "link/main.h"
#include "link/mylink.h"
#include "link/symbol.h"
#include "link/main.h"
struct sSection *pCurrentSection;
int32_t rpnstack[256];
int32_t rpnp;
static struct sSection *pCurrentSection;
static int32_t rpnstack[256];
static int32_t rpnp;
int32_t nPC;
void
rpnpush(int32_t i)
static void rpnpush(int32_t i)
{
rpnstack[rpnp++] = i;
rpnstack[rpnp] = i;
rpnp++;
}
int32_t
rpnpop(void)
static int32_t rpnpop(void)
{
return (rpnstack[--rpnp]);
rpnp--;
return rpnstack[rpnp];
}
int32_t
getsymvalue(int32_t symid)
int32_t getsymvalue(int32_t symid)
{
switch (pCurrentSection->tSymbols[symid]->Type) {
case SYM_IMPORT:
return (sym_GetValue(pCurrentSection->tSymbols[symid]->pzName));
break;
case SYM_EXPORT:
case SYM_LOCAL:
{
if (strcmp
(pCurrentSection->tSymbols[symid]->pzName,
"@") == 0) {
return (nPC);
} else
return (pCurrentSection->tSymbols[symid]->
nOffset +
pCurrentSection->tSymbols[symid]->
pSection->nOrg);
}
default:
break;
}
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
int32_t
getsymbank(int32_t symid)
{
int32_t nBank;
switch (pCurrentSection->tSymbols[symid]->Type) {
switch (tSymbol->Type) {
case SYM_IMPORT:
nBank = sym_GetBank(pCurrentSection->tSymbols[symid]->pzName);
return sym_GetValue(tSymbol->pzName);
case SYM_EXPORT:
case SYM_LOCAL:
if (strcmp(tSymbol->pzName, "@") == 0)
return nPC;
return tSymbol->nOffset + tSymbol->pSection->nOrg;
default:
break;
}
errx(1, "%s: Unknown symbol type", __func__);
}
int32_t getsymbank(int32_t symid)
{
int32_t n;
const struct sSymbol *tSymbol = pCurrentSection->tSymbols[symid];
switch (tSymbol->Type) {
case SYM_IMPORT:
n = sym_GetBank(tSymbol->pzName);
break;
case SYM_EXPORT:
case SYM_LOCAL:
nBank = pCurrentSection->tSymbols[symid]->pSection->nBank;
n = tSymbol->pSection->nBank;
break;
default:
errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
errx(1, "%s: Unknown symbol type", __func__);
}
if (nBank == BANK_WRAM0 || nBank == BANK_ROM0 || nBank == BANK_OAM ||
nBank == BANK_HRAM) {
if ((n == BANK_WRAM0) || (n == BANK_ROM0) || (n == BANK_OAM) ||
(n == BANK_HRAM)) {
return 0;
} else if (nBank >= BANK_WRAMX && nBank < (BANK_WRAMX + BANK_COUNT_WRAMX)) {
return nBank - BANK_WRAMX + 1;
} else if (nBank >= BANK_VRAM && nBank < (BANK_VRAM + BANK_COUNT_VRAM)) {
return nBank - BANK_VRAM;
} else if (nBank >= BANK_SRAM && nBank < (BANK_SRAM + BANK_COUNT_SRAM)) {
return nBank - BANK_SRAM;
} else if ((n >= BANK_WRAMX) && (n < (BANK_WRAMX + BANK_COUNT_WRAMX))) {
return n - BANK_WRAMX + 1;
} else if ((n >= BANK_VRAM) && (n < (BANK_VRAM + BANK_COUNT_VRAM))) {
return n - BANK_VRAM;
} else if ((n >= BANK_SRAM) && (n < (BANK_SRAM + BANK_COUNT_SRAM))) {
return n - BANK_SRAM;
}
return nBank;
return n;
}
int32_t
calcrpn(struct sPatch * pPatch)
int32_t calcrpn(struct sPatch *pPatch)
{
int32_t t, size;
uint8_t *rpn;
@@ -175,8 +171,8 @@ calcrpn(struct sPatch * pPatch)
rpnpush(t & 0xFF);
if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) {
errx(1,
"%s(%ld) : Value must be in the HRAM area",
pPatch->pzFilename, pPatch->nLineNo);
"%s(%ld) : Value must be in the HRAM area",
pPatch->pzFilename, pPatch->nLineNo);
}
break;
case RPN_CONST:
@@ -209,11 +205,10 @@ calcrpn(struct sPatch * pPatch)
break;
}
}
return (rpnpop());
return rpnpop();
}
void
Patch(void)
void Patch(void)
{
struct sSection *pSect;
@@ -233,12 +228,12 @@ Patch(void)
if (t >= -128 && t <= 255) {
t &= 0xFF;
pSect->pData[pPatch->nOffset] =
(uint8_t) t;
(uint8_t)t;
} else {
errx(1,
"%s(%ld) : Value must be 8-bit",
pPatch->pzFilename,
pPatch->nLineNo);
"%s(%ld) : Value must be 8-bit",
pPatch->pzFilename,
pPatch->nLineNo);
}
break;
case PATCH_WORD_L:
@@ -250,19 +245,19 @@ Patch(void)
(t >> 8) & 0xFF;
} else {
errx(1,
"%s(%ld) : Value must be 16-bit",
pPatch->pzFilename,
pPatch->nLineNo);
"%s(%ld) : Value must be 16-bit",
pPatch->pzFilename,
pPatch->nLineNo);
}
break;
case PATCH_LONG_L:
pSect->pData[pPatch->nOffset + 0] = t & 0xFF;
pSect->pData[pPatch->nOffset + 1] =
(t >> 8) & 0xFF;
(t >> 8) & 0xFF;
pSect->pData[pPatch->nOffset + 2] =
(t >> 16) & 0xFF;
(t >> 16) & 0xFF;
pSect->pData[pPatch->nOffset + 3] =
(t >> 24) & 0xFF;
(t >> 24) & 0xFF;
break;
}

View File

@@ -34,15 +34,15 @@ static int32_t current_real_bank = -1; /* bank as seen by the GB */
void script_InitSections(void)
{
int32_t i;
for (i = 0; i < MAXBANKS; i++) {
if (i == BANK_ROM0) {
/* ROM0 bank */
bank[i].address = 0x0000;
if (options & OPT_TINY) {
if (options & OPT_TINY)
bank[i].top_address = 0x8000;
} else {
else
bank[i].top_address = 0x4000;
}
bank[i].type = SECT_ROM0;
} else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) {
/* Swappable ROM bank */
@@ -52,11 +52,10 @@ void script_InitSections(void)
} else if (i == BANK_WRAM0) {
/* WRAM */
bank[i].address = 0xC000;
if (options & OPT_CONTWRAM) {
if (options & OPT_CONTWRAM)
bank[i].top_address = 0xE000;
} else {
else
bank[i].top_address = 0xD000;
}
bank[i].type = SECT_WRAM0;
} else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) {
/* Swappable SRAM bank */
@@ -105,14 +104,18 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
} else if (strcmp(type, "ROMX") == 0) {
if (bank == 0)
errx(1, "ROMX index can't be 0.\n");
if (bank > BANK_COUNT_ROMX)
errx(1, "ROMX index too big (%d > %d).\n", bank, BANK_COUNT_ROMX);
if (bank > BANK_COUNT_ROMX) {
errx(1, "ROMX index too big (%d > %d).\n", bank,
BANK_COUNT_ROMX);
}
current_bank = BANK_ROMX + bank - 1;
current_real_bank = bank;
return;
} else if (strcmp(type, "VRAM") == 0) {
if (bank >= BANK_COUNT_VRAM)
errx(1, "VRAM index too big (%d >= %d).\n", bank, BANK_COUNT_VRAM);
if (bank >= BANK_COUNT_VRAM) {
errx(1, "VRAM index too big (%d >= %d).\n", bank,
BANK_COUNT_VRAM);
}
current_bank = BANK_VRAM + bank;
current_real_bank = bank;
return;
@@ -125,14 +128,18 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
} else if (strcmp(type, "WRAMX") == 0) {
if (bank == 0)
errx(1, "WRAMX index can't be 0.\n");
if (bank > BANK_COUNT_WRAMX)
errx(1, "WRAMX index too big (%d > %d).\n", bank, BANK_COUNT_WRAMX);
if (bank > BANK_COUNT_WRAMX) {
errx(1, "WRAMX index too big (%d > %d).\n", bank,
BANK_COUNT_WRAMX);
}
current_bank = BANK_WRAMX + bank - 1;
current_real_bank = bank - 1;
return;
} else if (strcmp(type, "SRAM") == 0) {
if (bank >= BANK_COUNT_SRAM)
errx(1, "SRAM index too big (%d >= %d).\n", bank, BANK_COUNT_SRAM);
if (bank >= BANK_COUNT_SRAM) {
errx(1, "SRAM index too big (%d >= %d).\n", bank,
BANK_COUNT_SRAM);
}
current_bank = BANK_SRAM + bank;
current_real_bank = bank;
return;
@@ -155,14 +162,13 @@ void script_SetCurrentSectionType(const char *type, uint32_t bank)
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");
}
/* Make sure that we don't go back. */
if (bank[current_bank].address > addr) {
errx(1, "Trying to go to a previous address (0x%04X to 0x%04X)\n",
bank[current_bank].address, addr);
bank[current_bank].address, addr);
}
bank[current_bank].address = addr;
@@ -170,19 +176,18 @@ void script_SetAddress(uint32_t addr)
/* Make sure we don't overflow */
if (bank[current_bank].address >= bank[current_bank].top_address) {
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)
{
if (current_bank == -1) {
if (current_bank == -1)
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);
}
uint32_t size = 1 << alignment;
uint32_t mask = size - 1;
@@ -195,25 +200,29 @@ void script_SetAlignment(uint32_t alignment)
/* Make sure we don't overflow */
if (bank[current_bank].address >= bank[current_bank].top_address) {
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)
{
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,
current_real_bank)) {
if (!IsSectionSameTypeBankAndFloating(section_name,
bank[current_bank].type,
current_real_bank)) {
errx(1, "Different attributes for \"%s\" in source and linkerscript\n",
section_name);
section_name);
}
/* Move section to its place. */
bank[current_bank].address +=
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;
int32_t nValue;
int32_t nBank; /* -1 = constant */
char tzObjFileName[_MAX_PATH + 1]; /* Object file where the symbol was defined. */
char tzFileName[_MAX_PATH + 1]; /* Source file where the symbol was defined. */
uint32_t nFileLine; /* Line where the symbol was defined. */
/* Object file where the symbol was defined. */
char tzObjFileName[_MAX_PATH + 1];
/* 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 *tHash[HASHSIZE];
int32_t
calchash(char *s)
int32_t calchash(char *s)
{
int32_t r = 0;
while (*s)
r += *s++;
return (r % HASHSIZE);
return r % HASHSIZE;
}
void
sym_Init(void)
void sym_Init(void)
{
int32_t i;
for (i = 0; i < HASHSIZE; i += 1)
tHash[i] = NULL;
}
int32_t
sym_GetValue(char *tzName)
int32_t sym_GetValue(char *tzName)
{
if (strcmp(tzName, "@") == 0) {
return (nPC);
} else {
struct ISymbol **ppSym;
if (strcmp(tzName, "@") == 0)
return nPC;
ppSym = &(tHash[calchash(tzName)]);
while (*ppSym) {
if (strcmp(tzName, (*ppSym)->pzName)) {
ppSym = &((*ppSym)->pNext);
} else {
return ((*ppSym)->nValue);
}
}
errx(1, "Unknown symbol '%s'", tzName);
}
}
int32_t
sym_GetBank(char *tzName)
{
struct ISymbol **ppSym;
ppSym = &(tHash[calchash(tzName)]);
while (*ppSym) {
if (strcmp(tzName, (*ppSym)->pzName)) {
if (strcmp(tzName, (*ppSym)->pzName))
ppSym = &((*ppSym)->pNext);
} else {
return ((*ppSym)->nBank);
}
else
return ((*ppSym)->nValue);
}
errx(1, "Unknown symbol '%s'", tzName);
}
void
sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank, char *tzObjFileName,
char *tzFileName, uint32_t nFileLine)
int32_t sym_GetBank(char *tzName)
{
struct ISymbol **ppSym;
ppSym = &(tHash[calchash(tzName)]);
while (*ppSym) {
if (strcmp(tzName, (*ppSym)->pzName))
ppSym = &((*ppSym)->pNext);
else
return ((*ppSym)->nBank);
}
errx(1, "Unknown symbol '%s'", tzName);
}
void sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank,
char *tzObjFileName, char *tzFileName, uint32_t nFileLine)
{
if (strcmp(tzName, "@") == 0)
return;
@@ -99,14 +96,18 @@ sym_CreateSymbol(char *tzName, int32_t nValue, int32_t nBank, char *tzObjFileNam
return;
errx(1, "'%s' in both %s : %s(%d) and %s : %s(%d)",
tzName, tzObjFileName, tzFileName, nFileLine,
(*ppSym)->tzObjFileName,
(*ppSym)->tzFileName, (*ppSym)->nFileLine);
tzName, tzObjFileName, tzFileName, nFileLine,
(*ppSym)->tzObjFileName,
(*ppSym)->tzFileName, (*ppSym)->nFileLine);
}
}
if ((*ppSym = malloc(sizeof **ppSym))) {
if (((*ppSym)->pzName = malloc(strlen(tzName) + 1))) {
*ppSym = malloc(sizeof **ppSym);
if (*ppSym != NULL) {
(*ppSym)->pzName = malloc(strlen(tzName) + 1);
if ((*ppSym)->pzName != NULL) {
strcpy((*ppSym)->pzName, tzName);
(*ppSym)->nValue = nValue;
(*ppSym)->nBank = nBank;