diff --git a/include/link/assign.h b/include/link/assign.h index 3e2a3249..09c44d23 100644 --- a/include/link/assign.h +++ b/include/link/assign.h @@ -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 */ diff --git a/include/link/library.h b/include/link/library.h index f8d1a078..963ff491 100644 --- a/include/link/library.h +++ b/include/link/library.h @@ -3,4 +3,4 @@ void AddNeededModules(void); -#endif +#endif /* RGBDS_LINK_LIBRARY_H */ diff --git a/include/link/main.h b/include/link/main.h index 576eda99..98e2cf4a 100644 --- a/include/link/main.h +++ b/include/link/main.h @@ -6,4 +6,4 @@ extern int32_t fillchar; extern char *smartlinkstartsymbol; -#endif +#endif /* RGBDS_LINK_MAIN_H */ diff --git a/include/link/mapfile.h b/include/link/mapfile.h index 62f04c24..2f14e9ff 100644 --- a/include/link/mapfile.h +++ b/include/link/mapfile.h @@ -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 */ diff --git a/include/link/mylink.h b/include/link/mylink.h index d13a99b9..2b23a43f 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -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 */ diff --git a/include/link/object.h b/include/link/object.h index ebe45608..454f3a0c 100644 --- a/include/link/object.h +++ b/include/link/object.h @@ -3,4 +3,4 @@ void obj_Readfile(char *tzObjectfile); -#endif +#endif /* RGBDS_LINK_OBJECT_H */ diff --git a/include/link/output.h b/include/link/output.h index 6142a3f8..dccb1840 100644 --- a/include/link/output.h +++ b/include/link/output.h @@ -5,4 +5,4 @@ void out_Setname(char *tzOutputfile); void out_SetOverlayname(char *tzOverlayfile); void Output(void); -#endif +#endif /* RGBDS_LINK_OUTPUT_H */ diff --git a/include/link/patch.h b/include/link/patch.h index e82b83fd..792b162f 100644 --- a/include/link/patch.h +++ b/include/link/patch.h @@ -6,4 +6,4 @@ void Patch(void); extern int32_t nPC; -#endif +#endif /* RGBDS_LINK_PATCH_H */ diff --git a/include/link/script.h b/include/link/script.h index a820bae5..9f284346 100644 --- a/include/link/script.h +++ b/include/link/script.h @@ -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 */ diff --git a/include/link/symbol.h b/include/link/symbol.h index 15b8f915..007a8b30 100644 --- a/include/link/symbol.h +++ b/include/link/symbol.h @@ -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 */ diff --git a/include/types.h b/include/types.h index 3d1f65b4..3ce70649 100644 --- a/include/types.h +++ b/include/types.h @@ -5,4 +5,4 @@ #define _MAX_PATH 512 #endif -#endif +#endif /* RGBDS_TYPES_H */ diff --git a/src/link/assign.c b/src/link/assign.c index e810077d..0c920c54 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -5,6 +5,7 @@ #include #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; diff --git a/src/link/lexer.l b/src/link/lexer.l index 1bf07946..4d95ec80 100644 --- a/src/link/lexer.l +++ b/src/link/lexer.l @@ -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; diff --git a/src/link/library.c b/src/link/library.c index a0e5bad5..44478a0c 100644 --- a/src/link/library.c +++ b/src/link/library.c @@ -4,13 +4,13 @@ #include #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; diff --git a/src/link/main.c b/src/link/main.c index f6c7e98e..11ec4c29 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -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; } diff --git a/src/link/mapfile.c b/src/link/mapfile.c index e75cbce8..4c725872 100644 --- a/src/link/mapfile.c +++ b/src/link/mapfile.c @@ -5,39 +5,35 @@ #include #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; diff --git a/src/link/object.c b/src/link/object.c index 3457d9f9..6a7a087e 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -1,6 +1,5 @@ /* * Here we have the routines that read an objectfile - * */ #include @@ -11,24 +10,23 @@ #include #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; } diff --git a/src/link/output.c b/src/link/output.c index cf46d1e1..52877957 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -4,20 +4,20 @@ #include #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)); diff --git a/src/link/parser.y b/src/link/parser.y index 92853f7d..183f7215 100644 --- a/src/link/parser.y +++ b/src/link/parser.y @@ -19,6 +19,7 @@ #include #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 INTEGER %token 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 */ - ; +; %% diff --git a/src/link/patch.c b/src/link/patch.c index 72cbd428..678b1456 100644 --- a/src/link/patch.c +++ b/src/link/patch.c @@ -4,87 +4,83 @@ #include #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; } diff --git a/src/link/script.c b/src/link/script.c index aec8680b..ed2385c4 100644 --- a/src/link/script.c +++ b/src/link/script.c @@ -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); } diff --git a/src/link/symbol.c b/src/link/symbol.c index 39e6ab05..eb360554 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.c @@ -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;