From b07c04cd74cb97c9dd2d1c083cfac54c8e22f718 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Sun, 19 Feb 2017 22:20:21 +0000 Subject: [PATCH 1/6] Implement a malloc-based readasciiz() Instead of reading into a pre-sized buffer, this function now uses malloc to create a buffer, and resizes it if necessary. This reduces the risk of memory issues if a long string (< 255 chars) was encountered. --- src/link/object.c | 65 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/src/link/object.c b/src/link/object.c index d216425d..47539041 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -46,21 +46,41 @@ readword(FILE * f) return (r); } + /* * Read a NULL terminated string from a file * */ - -SLONG -readasciiz(char *s, FILE * f) +SLONG +readasciiz(char **dest, FILE *f) { SLONG r = 0; - - while (((*s++) = fgetc(f)) != 0) + + size_t bufferLength = 16; + char *start = malloc(bufferLength); + char *s = start; + + if (!s) { + err(1, NULL); + } + + while (((*s++) = fgetc(f)) != 0) { r += 1; - + + if (r >= bufferLength) { + bufferLength *= 2; + start = realloc(start, bufferLength); + if (!start) { + err(1, NULL); + } + s = start + r; + } + } + + *dest = start; return (r + 1); } + /* * Allocate a new section and link it into the list * @@ -97,7 +117,6 @@ AllocSection(void) struct sSymbol * obj_ReadSymbol(FILE * f) { - char s[256]; struct sSymbol *pSym; pSym = malloc(sizeof *pSym); @@ -105,13 +124,7 @@ obj_ReadSymbol(FILE * f) err(1, NULL); } - readasciiz(s, f); - pSym->pzName = malloc(strlen(s) + 1); - if (!pSym->pzName) { - err(1, NULL); - } - - strcpy(pSym->pzName, s); + readasciiz(&pSym->pzName, f); if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) { pSym->nSectionID = readlong(f); pSym->nOffset = readlong(f); @@ -153,7 +166,6 @@ obj_ReadRGB0Section(FILE * f) SLONG nNumberOfPatches; struct sPatch **ppPatch, *pPatch; - char s[256]; fread(pSection->pData, sizeof(UBYTE), pSection->nByteSize, f); @@ -171,14 +183,7 @@ obj_ReadRGB0Section(FILE * f) } *ppPatch = pPatch; - readasciiz(s, f); - - pPatch->pzFilename = malloc(strlen(s) + 1); - if (!pPatch->pzFilename) { - err(1, NULL); - } - - strcpy(pPatch->pzFilename, s); + readasciiz(&pPatch->pzFilename, f); pPatch->nLineNo = readlong(f); @@ -306,7 +311,6 @@ obj_ReadRGB1Section(FILE * f) SLONG nNumberOfPatches; struct sPatch **ppPatch, *pPatch; - char s[256]; fread(pSection->pData, sizeof(UBYTE), pSection->nByteSize, f); @@ -324,13 +328,7 @@ obj_ReadRGB1Section(FILE * f) } *ppPatch = pPatch; - readasciiz(s, f); - pPatch->pzFilename = malloc(strlen(s) + 1); - if (!pPatch->pzFilename) { - err(1, NULL); - } - - strcpy(pPatch->pzFilename, s); + readasciiz(&pPatch->pzFilename, f); pPatch->nLineNo = readlong(f); pPatch->nOffset = readlong(f); pPatch->Type = (enum ePatchType) fgetc(f); @@ -482,9 +480,9 @@ lib_ReadXLB0(FILE * f) size = file_Length(f) - 4; while (size) { - char name[256]; + char *name; - size -= readasciiz(name, f); + size -= readasciiz(&name, f); readword(f); size -= 2; readword(f); @@ -492,5 +490,6 @@ lib_ReadXLB0(FILE * f) size -= readlong(f); size -= 4; obj_ReadOpenFile(f, name); + free(name); } } From e4cbf773f69913a36519e71f7ad159913c382ce7 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Sun, 19 Feb 2017 22:35:32 +0000 Subject: [PATCH 2/6] Add alignment of sections to objects Aligned sections can now be created with out_NewAlignedSection(). This information is stored in created object files, and read by the linker. The names of each section are also included in the object file, enabling potential improvements to error messages in the future. --- include/asm/output.h | 2 ++ include/link/mylink.h | 2 ++ src/asm/output.c | 30 +++++++++++++++++++++--------- src/link/object.c | 36 +++++++++++++++++++++++++++--------- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/include/asm/output.h b/include/asm/output.h index 2afbccc5..fab83e36 100644 --- a/include/asm/output.h +++ b/include/asm/output.h @@ -10,6 +10,7 @@ struct Section { ULONG nPC; ULONG nOrg; ULONG nBank; + ULONG nAlign; struct Section *pNext; struct Patch *pPatches; struct Charmap *charmap; @@ -20,6 +21,7 @@ void out_PrepPass2(void); void out_SetFileName(char *s); void out_NewSection(char *pzName, ULONG secttype); void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank); +void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank); void out_AbsByte(int b); void out_AbsByteGroup(char *s, int length); void out_RelByte(struct Expression * expr); diff --git a/include/link/mylink.h b/include/link/mylink.h index 707d5fbf..9ce6e4e4 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -63,8 +63,10 @@ enum eSectionType { struct sSection { SLONG nBank; SLONG nOrg; + SLONG nAlign; BBOOL oAssigned; + char *pzName; SLONG nByteSize; enum eSectionType Type; UBYTE *pData; diff --git a/src/asm/output.c b/src/asm/output.c index d4147a1b..601dff76 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -201,17 +201,18 @@ writepatch(struct Patch * pPatch, FILE * f) void writesection(struct Section * pSect, FILE * f) { - //printf("SECTION: %s, ID: %d\n", pSect->pzName, getsectid(pSect)); - + fputstring(pSect->pzName, f); // RGB3 addition fputlong(pSect->nPC, f); fputc(pSect->nType, f); fputlong(pSect->nOrg, f); //RGB1 addition - fputlong(pSect->nBank, f); + fputlong(pSect->nBank, f); //RGB1 addition + + fputlong(pSect->nAlign, f); // RGB3 addition - if ((pSect->nType == SECT_ROM0) + if ((pSect->nType == SECT_ROM0) || (pSect->nType == SECT_ROMX)) { struct Patch *pPatch; @@ -490,7 +491,7 @@ out_WriteObject(void) struct PatchSymbol *pSym; struct Section *pSect; - fwrite("RGB2", 1, 4, f); + fwrite("RGB3", 1, 4, f); fputlong(countsymbols(), f); fputlong(countsections(), f); @@ -546,7 +547,7 @@ out_SetFileName(char *s) * Find a section by name and type. If it doesn't exist, create it */ struct Section * -out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) +out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank, SLONG alignment) { struct Section *pSect, **ppSect; @@ -557,7 +558,8 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) if (strcmp(pzName, pSect->pzName) == 0) { if (secttype == pSect->nType && ((ULONG) org) == pSect->nOrg - && ((ULONG) bank) == pSect->nBank) { + && ((ULONG) bank) == pSect->nBank + && ((ULONG) alignment == pSect->nAlign)) { return (pSect); } else fatalerror @@ -574,6 +576,7 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) pSect->nPC = 0; pSect->nOrg = org; pSect->nBank = bank; + pSect->nAlign = alignment; pSect->pNext = NULL; pSect->pPatches = NULL; pSect->charmap = NULL; @@ -610,7 +613,7 @@ out_SetCurrentSection(struct Section * pSect) void out_NewSection(char *pzName, ULONG secttype) { - out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1)); + out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1)); } /* @@ -619,7 +622,16 @@ out_NewSection(char *pzName, ULONG secttype) void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) { - out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank)); + out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1)); +} + +/* + * Set the current section by name and type, using a given byte alignment + */ +void +out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank) +{ + out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, alignment)); } /* diff --git a/src/link/object.c b/src/link/object.c index 47539041..5d0e7195 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -18,6 +18,11 @@ struct sSection *pLibSections = NULL; UBYTE dummymem; BBOOL oReadLib = 0; +enum ObjectFileContents { + CONTAINS_SECTION_NAME = 1 << 0, + CONTAINS_SECTION_ALIGNMENT = 1 << 1 +}; + /* * The usual byte order stuff * @@ -143,10 +148,12 @@ obj_ReadRGB0Section(FILE * f) pSection = AllocSection(); + pSection->pzName = ""; pSection->nByteSize = readlong(f); pSection->Type = (enum eSectionType) fgetc(f); pSection->nOrg = -1; pSection->nBank = -1; + pSection->nAlign = 1; /* does the user want the -s mode? */ @@ -277,21 +284,28 @@ obj_ReadRGB0(FILE * pObjfile) */ struct sSection * -obj_ReadRGB1Section(FILE * f) +obj_ReadRGBSection(FILE * f, enum ObjectFileContents contents) { struct sSection *pSection; pSection = AllocSection(); + if (contents & CONTAINS_SECTION_NAME) { + readasciiz(&pSection->pzName, f); + } else { + pSection->pzName = ""; + } + pSection->nByteSize = readlong(f); pSection->Type = (enum eSectionType) fgetc(f); - /* - * And because of THIS new feature I'll have to rewrite loads and - * loads of stuff... oh well it needed to be done anyway - * - */ pSection->nOrg = readlong(f); pSection->nBank = readlong(f); + + if (contents & CONTAINS_SECTION_ALIGNMENT) { + pSection->nAlign = readlong(f); + } else { + pSection->nAlign = 1; + } /* does the user want the -s mode? */ @@ -356,7 +370,7 @@ obj_ReadRGB1Section(FILE * f) } void -obj_ReadRGB1(FILE * pObjfile) +obj_ReadRGB(FILE * pObjfile, enum ObjectFileContents contents) { struct sSection *pFirstSection; SLONG nNumberOfSymbols, nNumberOfSections, i; @@ -383,7 +397,7 @@ obj_ReadRGB1(FILE * pObjfile) while (nNumberOfSections--) { struct sSection *pNewSection; - pNewSection = obj_ReadRGB1Section(pObjfile); + pNewSection = obj_ReadRGBSection(pObjfile, contents); pNewSection->nNumberOfSymbols = nNumberOfSymbols; if (pFirstSection == NULL) pFirstSection = pNewSection; @@ -430,7 +444,11 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile) case '1': case '2': //V2 is really the same but the are new patch types - obj_ReadRGB1(pObjfile); + obj_ReadRGB(pObjfile, 0); + break; + case '3': + // V3 is very similiar, but contains section names and byte alignment + obj_ReadRGB(pObjfile, CONTAINS_SECTION_NAME | CONTAINS_SECTION_ALIGNMENT); break; default: errx(1, "'%s' is an unsupported version", tzObjectfile); From 1b05c43b979f8cc8c9bd571a7c96f13614724111 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Sun, 19 Feb 2017 22:43:45 +0000 Subject: [PATCH 3/6] Implement byte alignment in section assingment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Yay, more refactoring of the section assignment… This version of the linker will allocate sections by their alignment, and then by their size (largest first, in both cases). In future, this may be improved by using dense packing (as suggested by #83). --- src/link/assign.c | 243 +++++++++++++++++++++------------------------- 1 file changed, 110 insertions(+), 133 deletions(-) diff --git a/src/link/assign.c b/src/link/assign.c index e602ebd7..91192578 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -46,7 +46,7 @@ const struct sSectionAttributes SECT_ATTRIBUTES[] = { case SECT_WRAMX: DOMAXWBANK(y); break; \ case SECT_SRAM: DOMAXSBANK(y); break; \ case SECT_VRAM: DOMAXVBANK(y); break; \ - default: errx(1, "DOMAXBANK used with invalid parameters"); 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);} @@ -77,6 +77,40 @@ area_Avail(SLONG bank) return (r); } +SLONG +area_doAlloc(struct sFreeArea *pArea, SLONG org, SLONG size) +{ + 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); + } + } + } + } + + return -1; +} + SLONG area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size) { @@ -84,39 +118,11 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size) pArea = *ppArea; while (pArea) { - if (org >= pArea->nOrg - && (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) { - if (org == pArea->nOrg) { - pArea->nOrg += size; - pArea->nSize -= size; - return 0; - } else { - if ((org + size - 1) == - (pArea->nOrg + pArea->nSize - 1)) { - pArea->nSize -= size; - return 0; - } 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 0; - } else { - err(1, NULL); - } - } - } + SLONG result = area_doAlloc(pArea, org, size); + if (result != -1) { + return result; } + ppArea = &(pArea->pNext); pArea = *ppArea; } @@ -141,38 +147,42 @@ area_AllocAbsAnyBank(SLONG org, SLONG size, enum eSectionType type) return -1; } -SLONG -area_Alloc(struct sFreeArea ** ppArea, SLONG size) -{ +SLONG +area_Alloc(struct sFreeArea ** ppArea, SLONG size, SLONG alignment) { struct sFreeArea *pArea; - + if (alignment < 1) { + alignment = 1; + } + pArea = *ppArea; while (pArea) { - if (size <= pArea->nSize) { - SLONG r; - - r = pArea->nOrg; - pArea->nOrg += size; - pArea->nSize -= size; - - return (r); + SLONG org = pArea->nOrg; + if (org % alignment) { + org += alignment; } + org -= org % alignment; + + SLONG result = area_doAlloc(pArea, org, size); + if (result != -1) { + return result; + } + ppArea = &(pArea->pNext); pArea = *ppArea; } - return (-1); + return -1; } SLONG -area_AllocAnyBank(SLONG size, enum eSectionType type) { +area_AllocAnyBank(SLONG size, SLONG alignment, enum eSectionType type) { ensureSectionTypeIsValid(type); SLONG startBank = SECT_ATTRIBUTES[type].bank; SLONG bankCount = SECT_ATTRIBUTES[type].bankCount; for (int i = 0; i < bankCount; i++) { - SLONG org = area_Alloc(&BankFree[startBank + i], size); + SLONG org = area_Alloc(&BankFree[startBank + i], size, alignment); if (org != -1) { return ((startBank + i) << 16) | org; } @@ -182,45 +192,27 @@ area_AllocAnyBank(SLONG size, enum eSectionType type) { } struct sSection * -FindLargestSection(enum eSectionType type) +FindLargestSection(enum eSectionType type, bool bankFixed) { struct sSection *pSection, *r = NULL; SLONG nLargest = 0; + SLONG nLargestAlignment = 0; pSection = pSections; while (pSection) { - if (pSection->oAssigned == 0 && pSection->Type == type) { - if (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; } } pSection = pSection->pNext; } + return r; } -void -AssignBankedSections(enum eSectionType type) -{ - ensureSectionTypeIsValid(type); - - struct sSection *pSection; - - while ((pSection = FindLargestSection(type))) { - SLONG org; - - if ((org = area_AllocAnyBank(pSection->nByteSize, type)) != -1) { - pSection->nOrg = org & 0xFFFF; - pSection->nBank = org >> 16; - pSection->oAssigned = 1; - DOMAXBANK(pSection->Type, pSection->nBank); - } else { - errx(1, "Unable to place %s section anywhere", - SECT_ATTRIBUTES[type].name); - } - } -} bool VerifyAndSetBank(struct sSection *pSection) @@ -237,6 +229,47 @@ VerifyAndSetBank(struct sSection *pSection) } } +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 { + errx(1, "Unable to load fixed %s section into bank $%02lX", + SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank); + } + } +} + +void +AssignFloatingBankSections(enum eSectionType type) +{ + ensureSectionTypeIsValid(type); + + struct sSection *pSection; + + while ((pSection = FindLargestSection(type, false))) { + SLONG org; + + if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) { + pSection->nOrg = org & 0xFFFF; + pSection->nBank = org >> 16; + pSection->oAssigned = 1; + DOMAXBANK(pSection->Type, pSection->nBank); + } else { + errx(1, "Unable to place %s section anywhere", + SECT_ATTRIBUTES[type].name); + } + } +} + void AssignSections(void) { @@ -353,35 +386,11 @@ AssignSections(void) } /* - * Next, let's assign all the bankfixed ONLY ROMX sections... + * Next, let's assign all the bankfixed ONLY sections... * */ - - pSection = pSections; - while (pSection) { - if (pSection->oAssigned == 0 - && pSection->nOrg == -1 && pSection->nBank != -1) { - switch (pSection->Type) { - case SECT_ROMX: - case SECT_SRAM: - case SECT_VRAM: - case SECT_WRAMX: - if (VerifyAndSetBank(pSection) && - (pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) != -1) { - pSection->oAssigned = 1; - DOMAXBANK(pSection->Type, pSection->nBank); - } else { - errx(1, "Unable to load fixed %s section into bank $%02lX", - SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank); - } - break; - - default: // Handle other sections later - break; - } - } - - pSection = pSection->pNext; + for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) { + AssignFixedBankSections(i); } /* @@ -421,41 +430,9 @@ AssignSections(void) * sections * */ - - pSection = pSections; - while (pSection) { - if (pSection->oAssigned == 0) { - switch (pSection->Type) { - case SECT_WRAM0: - case SECT_HRAM: - case SECT_ROM0: - pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank; - if ((pSection->nOrg = - area_Alloc(&BankFree[pSection->nBank], - pSection->nByteSize)) == -1) { - errx(1, "%s section too large", SECT_ATTRIBUTES[pSection->Type].name); - } - pSection->oAssigned = 1; - break; - - case SECT_SRAM: - case SECT_VRAM: - case SECT_WRAMX: - case SECT_ROMX: - break; - - default: - errx(1, "(INTERNAL) Unknown section type!"); - break; - } - } - pSection = pSection->pNext; + for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) { + AssignFloatingBankSections(i); } - - AssignBankedSections(SECT_ROMX); - AssignBankedSections(SECT_VRAM); - AssignBankedSections(SECT_WRAMX); - AssignBankedSections(SECT_SRAM); } void From 1ab93a194e7242912929b08798447f91e831a090 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Thu, 23 Feb 2017 15:00:57 +0000 Subject: [PATCH 4/6] Implement ALIGN keyword in rgbasm The ALIGN keyword specifies the number of bits that should be zero at the start of a section. It works in a simliar fashion to BANK. --- src/asm/asmy.y | 14 +++++++++++++- src/asm/globlex.c | 1 + src/asm/output.c | 5 ++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/asm/asmy.y b/src/asm/asmy.y index a8b96f50..8d9f7e7a 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -442,7 +442,7 @@ void if_skip_to_endc( void ) %left T_OP_MUL T_OP_DIV T_OP_MOD %left T_OP_NOT %left T_OP_DEF -%left T_OP_BANK +%left T_OP_BANK T_OP_ALIGN %left T_OP_SIN %left T_OP_COS %left T_OP_TAN @@ -1095,6 +1095,10 @@ section: else yyerror("Address $%x not 16-bit", $6); } + | T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']' + { + out_NewAlignedSection($2, $4, $8, -1); + } | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' { bankrangecheck($2, $4, -1, $8); @@ -1106,6 +1110,14 @@ section: } bankrangecheck($2, $4, $6, $11); } + | T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']' ',' T_OP_BANK '[' const ']' + { + out_NewAlignedSection($2, $4, $8, $13); + } + | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' ',' T_OP_ALIGN '[' const ']' + { + out_NewAlignedSection($2, $4, $13, $8); + } ; sectiontype: diff --git a/src/asm/globlex.c b/src/asm/globlex.c index 9f9523a8..dd379277 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -267,6 +267,7 @@ struct sLexInitString staticstrings[] = { {"def", T_OP_DEF}, {"bank", T_OP_BANK}, + {"align", T_OP_ALIGN}, {"round", T_OP_ROUND}, {"ceil", T_OP_CEIL}, diff --git a/src/asm/output.c b/src/asm/output.c index 601dff76..e40f92c8 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -631,7 +631,10 @@ out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank) { - out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, alignment)); + if (alignment < 0) { + yyerror("Alignment must not be negative."); + } + out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment)); } /* From 7993d3455d9eef8173fe9d9fb24513989d72ce20 Mon Sep 17 00:00:00 2001 From: Ben10do Date: Thu, 2 Mar 2017 08:02:05 +0000 Subject: [PATCH 5/6] Update alignment error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure (in rgbasm) that the alignment value is between 1-16. Replaces the previous “alignment must not be negative” check. --- src/asm/output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/asm/output.c b/src/asm/output.c index e40f92c8..696c1a5b 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -631,8 +631,8 @@ out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank) { - if (alignment < 0) { - yyerror("Alignment must not be negative."); + if (alignment < 1 || alignment > 16) { + yyerror("Alignment must be between 1-16 bits."); } out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment)); } From 7e2457c9bee44041dbb9ace4d67158711be6352d Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 2 Mar 2017 08:29:28 +0000 Subject: [PATCH 6/6] Re-allow alignment of 0 bits --- src/asm/output.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/asm/output.c b/src/asm/output.c index 696c1a5b..92340fa8 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -631,8 +631,8 @@ out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank) void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank) { - if (alignment < 1 || alignment > 16) { - yyerror("Alignment must be between 1-16 bits."); + if (alignment < 0 || alignment > 16) { + yyerror("Alignment must be between 0-16 bits."); } out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment)); }