From 2ff286223b49b130983994e5e76a5dcd1ad6344e Mon Sep 17 00:00:00 2001 From: yenatch Date: Tue, 14 Jan 2014 11:39:57 -0500 Subject: [PATCH 01/36] add instruction "ld hl, sp+nn" The previous "ld hl, [sp+nn]" is incorrect, but remains for compatibility. --- src/asm/gameboy/yaccprt4.y | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/asm/gameboy/yaccprt4.y b/src/asm/gameboy/yaccprt4.y index 9b8bfcba..bc113e70 100644 --- a/src/asm/gameboy/yaccprt4.y +++ b/src/asm/gameboy/yaccprt4.y @@ -290,6 +290,8 @@ z80_ld : z80_ld_mem z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']' { out_AbsByte(0xF8); out_RelByte(&$6); } + | T_Z80_LD T_MODE_HL comma T_MODE_SP const_8bit + { out_AbsByte(0xF8); out_RelByte(&$5); } | T_Z80_LD T_MODE_HL comma const_16bit { out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4); } ; From 0f488b67599c5d93423cf9ed830d829825eaf283 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 31 Jan 2014 00:01:42 -0700 Subject: [PATCH 02/36] Remove unused alloca() implementation. --- Makefile | 1 - src/asm/alloca.c | 466 ----------------------------------------------- 2 files changed, 467 deletions(-) delete mode 100644 src/asm/alloca.c diff --git a/Makefile b/Makefile index fb166a56..b90d0875 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,6 @@ yacc_pre := \ src/asm/gameboy/yaccprt4.y rgbasm_obj := \ - src/asm/alloca.o \ src/asm/asmy.o \ src/asm/fstack.o \ src/asm/globlex.o \ diff --git a/src/asm/alloca.c b/src/asm/alloca.c deleted file mode 100644 index eb6ebd75..00000000 --- a/src/asm/alloca.c +++ /dev/null @@ -1,466 +0,0 @@ -/* alloca.c -- allocate automatically reclaimed memory - (Mostly) portable public-domain implementation -- D A Gwyn - - This implementation of the PWB library alloca function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - J.Otto Tennant contributed the Cray support. - - There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef emacs -#include "blockinput.h" -#endif - -/* If compiling with GCC 2, this file's not needed. */ -#if !defined (__GNUC__) || __GNUC__ < 2 - -/* If someone has defined alloca as a macro, - there must be some other way alloca is supposed to work. */ -#ifndef alloca - -#ifdef emacs -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you lose-- must know STACK_DIRECTION at compile - time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ -/* If your stack is a linked list of frames, you have to - provide an "address metric" ADDRESS_FUNCTION macro. */ -#if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc(); -#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -#else -#define ADDRESS_FUNCTION(arg) &(arg) -#endif -#if __STDC__ - typedef void *pointer; -#else - typedef char *pointer; -#endif - -#define NULL 0 - -/* Different portions of Emacs need to call different versions of - malloc. The Emacs executable needs alloca to call xmalloc, because - ordinary malloc isn't protected from input signals. On the other - hand, the utilities in lib-src need alloca to call malloc; some of - them are very simple, and don't have an xmalloc routine. - - Non-Emacs programs expect this to call use xmalloc. - - Callers below should use malloc. */ - -/* Carsten Sorensen 09/09/97 - * Commented out the following, I want malloc! -#ifndef emacs -#define malloc xmalloc -#endif -extern pointer malloc (); - And added the following line: - */ -#include - -/* Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* Direction unknown. */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ - -#else /* STACK_DIRECTION == 0; need run-time code. */ - -static int stack_dir; /* 1 or -1 once known. */ -#define STACK_DIR stack_dir - -static void -find_stack_direction() -{ - static char *addr = NULL; /* Address of first `dummy', once - * known. */ - auto char dummy; /* To get stack address. */ - - if (addr == NULL) { /* Initial entry. */ - addr = ADDRESS_FUNCTION(dummy); - - find_stack_direction(); /* Recurse once. */ - } else { - /* Second entry. */ - if (ADDRESS_FUNCTION(dummy) > addr) - stack_dir = 1; /* Stack grew upward. */ - else - stack_dir = -1; /* Stack grew downward. */ - } -} -#endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: - (a) chain together all alloca'ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc - alignment chunk size. The following default should work okay. */ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr { - char align[ALIGN_SIZE]; /* To force sizeof(header). */ - struct { - union hdr *next;/* For chaining headers. */ - char *deep; /* For stack depth measure. */ - } h; -} header; - -static header *last_alloca_header = NULL; /* -> last alloca header. */ - -/* Return a pointer to at least SIZE bytes of storage, - which will be automatically reclaimed upon exit from - the procedure that called alloca. Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. */ - -pointer -alloca(size) - unsigned size; -{ - auto char probe; /* Probes stack depth: */ - register char *depth = ADDRESS_FUNCTION(probe); - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* Unknown growth direction. */ - find_stack_direction(); -#endif - - /* Reclaim garbage, defined as all alloca'd storage that was allocated - * from deeper in the stack than currently. */ - - { - register header *hp; /* Traverses linked list. */ - -#ifdef emacs - BLOCK_INPUT; -#endif - - for (hp = last_alloca_header; hp != NULL;) - if ((STACK_DIR > 0 && hp->h.deep > depth) - || (STACK_DIR < 0 && hp->h.deep < depth)) { - register header *np = hp->h.next; - - free((pointer) hp); /* Collect garbage. */ - - hp = np; /* -> next header. */ - } else - break; /* Rest are not deeper. */ - - last_alloca_header = hp; /* -> last valid storage. */ - -#ifdef emacs - UNBLOCK_INPUT; -#endif - } - - if (size == 0) - return NULL; /* No allocation required. */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = malloc(sizeof(header) + size); - /* Address of header. */ - - ((header *) new)->h.next = last_alloca_header; - ((header *) new)->h.deep = depth; - - last_alloca_header = (header *) new; - - /* User storage begins just after header. */ - - return (pointer) ((char *) new + sizeof(header)); - } -} -#if defined (CRAY) && defined (CRAY_STACKSEG_END) - -#ifdef DEBUG_I00AFUNC -#include -#endif - -#ifndef CRAY_STACK -#define CRAY_STACK -#ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header { - long shgrow:32; /* Number of times stack has grown. */ - long shaseg:32; /* Size of increments to stack. */ - long shhwm:32; /* High water mark of stack. */ - long shsize:32; /* Current size of stack (all segments). */ -}; -/* The stack segment linkage control information occurs at - the high-address end of a stack segment. (The stack - grows from low addresses to high addresses.) The initial - part of the stack segment linkage control information is - 0200 (octal) words. This provides for register storage - for the routine which overflows the stack. */ - -struct stack_segment_linkage { - long ss[0200]; /* 0200 overflow words. */ - long sssize:32; /* Number of words in this segment. */ - long ssbase:32; /* Offset to stack base. */ - long:32; - long sspseg:32; /* Offset to linkage control of previous - * segment of stack. */ - long:32; - long sstcpt:32; /* Pointer to task common address block. */ - long sscsnm; /* Private control structure number for - * microtasking. */ - long ssusr1; /* Reserved for user. */ - long ssusr2; /* Reserved for user. */ - long sstpid; /* Process ID for pid based multi-tasking. */ - long ssgvup; /* Pointer to multitasking thread giveup. */ - long sscray[7]; /* Reserved for Cray Research. */ - long ssa0; - long ssa1; - long ssa2; - long ssa3; - long ssa4; - long ssa5; - long ssa6; - long ssa7; - long sss0; - long sss1; - long sss2; - long sss3; - long sss4; - long sss5; - long sss6; - long sss7; -}; -#else /* CRAY2 */ -/* The following structure defines the vector of words - returned by the STKSTAT library routine. */ -struct stk_stat { - long now; /* Current total stack size. */ - long maxc; /* Amount of contiguous space which would be - * required to satisfy the maximum stack - * demand to date. */ - long high_water; /* Stack high-water mark. */ - long overflows; /* Number of stack overflow ($STKOFEN) calls. */ - long hits; /* Number of internal buffer hits. */ - long extends; /* Number of block extensions. */ - long stko_mallocs; /* Block allocations by $STKOFEN. */ - long underflows; /* Number of stack underflow calls ($STKRETN). */ - long stko_free; /* Number of deallocations by $STKRETN. */ - long stkm_free; /* Number of deallocations by $STKMRET. */ - long segments; /* Current number of stack segments. */ - long maxs; /* Maximum number of stack segments so far. */ - long pad_size; /* Stack pad size. */ - long current_address; /* Current stack segment address. */ - long current_size; /* Current stack segment size. This number is - * actually corrupted by STKSTAT to include - * the fifteen word trailer area. */ - long initial_address; /* Address of initial segment. */ - long initial_size; /* Size of initial segment. */ -}; -/* The following structure describes the data structure which trails - any stack segment. I think that the description in 'asdef' is - out of date. I only describe the parts that I am sure about. */ - -struct stk_trailer { - long this_address; /* Address of this block. */ - long this_size; /* Size of this block (does not include this - * trailer). */ - long unknown2; - long unknown3; - long link; /* Address of trailer block of previous - * segment. */ - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - long unknown10; - long unknown11; - long unknown12; - long unknown13; - long unknown14; -}; -#endif /* CRAY2 */ -#endif /* not CRAY_STACK */ - -#ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. - I doubt that "lint" will like this much. */ - -static long -i00afunc(long *address) -{ - struct stk_stat status; - struct stk_trailer *trailer; - long *block, size; - long result = 0; - - /* We want to iterate through all of the segments. The first step is - * to get the stack status structure. We could do this more quickly - * and more directly, perhaps, by referencing the $LM00 common block, - * but I know that this works. */ - - STKSTAT(&status); - - /* Set up the iteration. */ - - trailer = (struct stk_trailer *) (status.current_address - + status.current_size - 15); - - /* There must be at least one stack segment. Therefore it is a fatal - * error if "trailer" is null. */ - - if (trailer == 0) - abort(); - - /* Discard segments that do not contain our argument address. */ - - while (trailer != 0) { - block = (long *) trailer->this_address; - size = trailer->this_size; - if (block == 0 || size == 0) - abort(); - trailer = (struct stk_trailer *) trailer->link; - if ((block <= address) && (address < (block + size))) - break; - } - - /* Set the result to the offset in this segment and add the sizes of - * all predecessor segments. */ - - result = address - block; - - if (trailer == 0) { - return result; - } - do { - if (trailer->this_size <= 0) - abort(); - result += trailer->this_size; - trailer = (struct stk_trailer *) trailer->link; - } - while (trailer != 0); - - /* We are done. Note that if you present a bogus address (one not in - * any segment), you will get a different number back, formed from - * subtracting the address of the first block. This is probably not - * what you want. */ - - return (result); -} -#else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. - Determine the number of the cell within the stack, - given the address of the cell. The purpose of this - routine is to linearize, in some sense, stack addresses - for alloca. */ - -static long -i00afunc(long address) -{ - long stkl = 0; - - long size, pseg, this_segment, stack; - long result = 0; - - struct stack_segment_linkage *ssptr; - - /* Register B67 contains the address of the end of the current stack - * segment. If you (as a subprogram) store your registers on the - * stack and find that you are past the contents of B67, you have - * overflowed the segment. - * - * B67 also points to the stack segment linkage control area, which is - * what we are really interested in. */ - - stkl = CRAY_STACKSEG_END(); - ssptr = (struct stack_segment_linkage *) stkl; - - /* If one subtracts 'size' from the end of the segment, one has the - * address of the first word of the segment. - * - * If this is not the first segment, 'pseg' will be nonzero. */ - - pseg = ssptr->sspseg; - size = ssptr->sssize; - - this_segment = stkl - size; - - /* It is possible that calling this routine itself caused a stack - * overflow. Discard stack segments which do not contain the target - * address. */ - - while (!(this_segment <= address && address <= stkl)) { -#ifdef DEBUG_I00AFUNC - fprintf(stderr, "%011o %011o %011o\n", this_segment, address, - stkl); -#endif - if (pseg == 0) - break; - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - this_segment = stkl - size; - } - - result = address - this_segment; - - /* If you subtract pseg from the current end of the stack, you get the - * address of the previous stack segment's end. This seems a little - * convoluted to me, but I'll bet you save a cycle somewhere. */ - - while (pseg != 0) { -#ifdef DEBUG_I00AFUNC - fprintf(stderr, "%011o %011o\n", pseg, size); -#endif - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - result += size; - } - return (result); -} -#endif /* not CRAY2 */ -#endif /* CRAY */ - -#endif /* no alloca */ -#endif /* not GCC version 2 */ From 17192ea6f07c2697bd87bc28df015a66f6e97fc3 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Sat, 8 Feb 2014 23:26:43 -0700 Subject: [PATCH 03/36] Improve performance when padding: don't write a byte at a time. --- src/fix/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fix/main.c b/src/fix/main.c index 36cc2df9..32ed3db5 100644 --- a/src/fix/main.c +++ b/src/fix/main.c @@ -390,12 +390,11 @@ main(int argc, char *argv[]) headbyte++; } - while (newsize != ftell(rom)) /* ROM needs resizing */ - fputc(padvalue, rom); - if (newsize > 0x800000) /* ROM is bigger than 8MiB */ fprintf(stderr, "ROM size is bigger than 8MiB\n"); + ftruncate(fileno(rom), newsize); + fseek(rom, 0x148, SEEK_SET); fputc(headbyte, rom); } From 08b1b97a45200af02cb7d76e6134d5e0f759a9d7 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Sun, 9 Feb 2014 02:58:00 -0700 Subject: [PATCH 04/36] Preserve the ability to set pad_value in rgbfix. --- src/fix/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/fix/main.c b/src/fix/main.c index 32ed3db5..f13bc14e 100644 --- a/src/fix/main.c +++ b/src/fix/main.c @@ -380,6 +380,7 @@ main(int argc, char *argv[]) /* We will pad the ROM to match the size given in the header. */ int romsize, newsize, headbyte; + uint8_t *buf; fseek(rom, 0, SEEK_END); romsize = ftell(rom); newsize = 0x8000; @@ -393,10 +394,14 @@ main(int argc, char *argv[]) if (newsize > 0x800000) /* ROM is bigger than 8MiB */ fprintf(stderr, "ROM size is bigger than 8MiB\n"); - ftruncate(fileno(rom), newsize); + buf = malloc(newsize - romsize); + memset(buf, padvalue, newsize - romsize); + fwrite(buf, 1, newsize - romsize, rom); fseek(rom, 0x148, SEEK_SET); fputc(headbyte, rom); + + free(buf); } if (setramsize) { From 2dab1474b88675cd7de23fa1b7347a1aea3fe5b8 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 21 Feb 2014 00:56:34 -0700 Subject: [PATCH 05/36] asmy.y should not be in gitignore. --- src/asm/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/src/asm/.gitignore b/src/asm/.gitignore index da241a7f..9d9e3ce6 100644 --- a/src/asm/.gitignore +++ b/src/asm/.gitignore @@ -1,3 +1,2 @@ asmy.c asmy.h -asmy.y From 3ecd169cd6f9d53e341efdbecb906357443b6bcf Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 21 Feb 2014 03:20:44 -0700 Subject: [PATCH 06/36] Revert previous commit. asmy.y is autogenerated from other .y files. --- src/asm/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/src/asm/.gitignore b/src/asm/.gitignore index 9d9e3ce6..da241a7f 100644 --- a/src/asm/.gitignore +++ b/src/asm/.gitignore @@ -1,2 +1,3 @@ asmy.c asmy.h +asmy.y From b1269ab53a1158cd233a3ccd517a5bd6d6f2f850 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Thu, 21 Aug 2014 02:57:43 -0700 Subject: [PATCH 07/36] Improve rgbasm performance --- include/asm/symbol.h | 3 ++- src/asm/output.c | 45 ++++++++++++++++++++++---------------------- src/asm/symbol.c | 4 ++-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/asm/symbol.h b/include/asm/symbol.h index e63aa196..516a5486 100644 --- a/include/asm/symbol.h +++ b/include/asm/symbol.h @@ -3,7 +3,7 @@ #include "asm/types.h" -#define HASHSIZE 73 +#define HASHSIZE (1 << 16) #define MAXSYMLEN 256 struct sSymbol { @@ -35,6 +35,7 @@ struct sSymbol { #define SYMF_CONST 0x200 /* symbol has a constant value, will * not be changed during linking */ +ULONG calchash(char *s); void sym_PrepPass1(void); void sym_PrepPass2(void); void sym_AddLocalReloc(char *tzSym); diff --git a/src/asm/output.c b/src/asm/output.c index e39f67d1..c36b0e88 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -43,6 +43,7 @@ struct PatchSymbol { ULONG ID; struct sSymbol *pSymbol; struct PatchSymbol *pNext; + struct PatchSymbol *pBucketNext; // next symbol in hash table bucket }; struct SectionStackEntry { @@ -56,8 +57,10 @@ struct SectionStackEntry { * */ +struct PatchSymbol *tHashedPatchSymbols[HASHSIZE]; struct Section *pSectionList = NULL, *pCurrentSection = NULL; struct PatchSymbol *pPatchSymbols = NULL; +struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols; char tzObjectname[_MAX_PATH]; struct SectionStackEntry *pSectionStack = NULL; @@ -327,30 +330,32 @@ ULONG addsymbol(struct sSymbol * pSym) { struct PatchSymbol *pPSym, **ppPSym; - ULONG ID = 0; + static ULONG nextID = 0; + ULONG hash; - pPSym = pPatchSymbols; - ppPSym = &(pPatchSymbols); + hash = calchash(pSym->tzName); + ppPSym = &(tHashedPatchSymbols[hash]); - while (pPSym) { - if (pSym == pPSym->pSymbol) - return (pPSym->ID); - ppPSym = &(pPSym->pNext); - pPSym = pPSym->pNext; - ID += 1; + while ((*ppPSym) != NULL) { + if (pSym == (*ppPSym)->pSymbol) + return (*ppPSym)->ID; + ppPSym = &((*ppPSym)->pBucketNext); } if ((*ppPSym = pPSym = (struct PatchSymbol *) malloc(sizeof(struct PatchSymbol))) != NULL) { pPSym->pNext = NULL; + pPSym->pBucketNext = NULL; pPSym->pSymbol = pSym; - pPSym->ID = ID; - return (ID); + pPSym->ID = nextID++; } else fatalerror("No memory for patchsymbol"); - return ((ULONG) - 1); + *ppPatchSymbolsTail = pPSym; + ppPatchSymbolsTail = &(pPSym->pNext); + + return pPSym->ID; } /* * RGBAsm - OUTPUT.C - Outputs an objectfile @@ -385,24 +390,18 @@ addexports(void) struct Patch * allocpatch(void) { - struct Patch *pPatch, **ppPatch; + struct Patch *pPatch; - pPatch = pCurrentSection->pPatches; - ppPatch = &(pCurrentSection->pPatches); - - while (pPatch) { - ppPatch = &(pPatch->pNext); - pPatch = pPatch->pNext; - } - - if ((*ppPatch = pPatch = + if ((pPatch = (struct Patch *) malloc(sizeof(struct Patch))) != NULL) { - pPatch->pNext = NULL; + pPatch->pNext = pCurrentSection->pPatches; pPatch->nRPNSize = 0; pPatch->pRPN = NULL; } else fatalerror("No memory for patch"); + pCurrentSection->pPatches = pPatch; + return (pPatch); } /* diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 21a07744..cd51bc85 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -75,10 +75,10 @@ getvaluefield(struct sSymbol * sym) ULONG calchash(char *s) { - ULONG hash = 0; + ULONG hash = 5381; while (*s != 0) - hash += (*s++); + hash = (hash * 33) ^ (*s++); return (hash % HASHSIZE); } From e4571bc0fc6309534cdd59bcb140d73ddefb2192 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Thu, 21 Aug 2014 19:53:42 -0700 Subject: [PATCH 08/36] Make _NARG work --- src/asm/symbol.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/asm/symbol.c b/src/asm/symbol.c index cd51bc85..b941b499 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -848,6 +848,10 @@ sym_PrepPass2(void) sym_AddString("__TIME__", SavedTIME); sym_AddString("__DATE__", SavedDATE); sym_AddSet("_RS", 0); + + sym_AddEqu("_NARG", 0); + p_NARGSymbol = findsymbol("_NARG", NULL); + p_NARGSymbol->Callback = Callback_NARG; } /* * RGBAsm - SYMBOL.C - Symboltable stuff From 6198cc185c24ec4ba794ed27c969ae65d31f89c3 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Fri, 22 Aug 2014 01:52:21 -0700 Subject: [PATCH 09/36] Remove __LINE__ --- src/asm/symbol.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/asm/symbol.c b/src/asm/symbol.c index b941b499..e63b3d5e 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -26,7 +26,6 @@ struct sSymbol *tHashedSymbols[HASHSIZE]; struct sSymbol *pScope = NULL; struct sSymbol *pPCSymbol = NULL; struct sSymbol *p_NARGSymbol = NULL; -struct sSymbol *p__LINE__Symbol = NULL; char *currentmacroargs[MAXMACROARGS + 1]; char *newmacroargs[MAXMACROARGS + 1]; char SavedTIME[256]; @@ -44,12 +43,6 @@ Callback_NARG(struct sSymbol * sym) return (i); } -SLONG -Callback__LINE__(struct sSymbol * sym) -{ - sym = sym; - return (nLineNo); -} /* * RGBAsm - SYMBOL.C - Symboltable stuff * @@ -879,9 +872,6 @@ sym_Init(void) sym_AddEqu("_NARG", 0); p_NARGSymbol = findsymbol("_NARG", NULL); p_NARGSymbol->Callback = Callback_NARG; - sym_AddEqu("__LINE__", 0); - p__LINE__Symbol = findsymbol("__LINE__", NULL); - p__LINE__Symbol->Callback = Callback__LINE__; sym_AddEqu("__ASM__", (SLONG) (atof(ASM_VERSION) * 65536)); sym_AddSet("_RS", 0); From 2bf31870a7b9be374e24c20aaac13985b5e33f67 Mon Sep 17 00:00:00 2001 From: YamaArashi Date: Fri, 22 Aug 2014 21:44:18 -0700 Subject: [PATCH 10/36] Cleaned up lexer - separated the lexer into multiple functions so it is more readable - fixed issue with long label names in macro arguments - added error checking code to prevent buffer overflows --- include/asm/lexer.h | 7 +- src/asm/lexer.c | 949 +++++++++++++++++++++----------------------- src/asm/yaccprt1.y | 40 +- 3 files changed, 490 insertions(+), 506 deletions(-) diff --git a/include/asm/lexer.h b/include/asm/lexer.h index 27fe475c..5b6db4a2 100644 --- a/include/asm/lexer.h +++ b/include/asm/lexer.h @@ -5,7 +5,8 @@ #include "asm/types.h" -#define LEXHASHSIZE 512 +#define LEXHASHSIZE (1 << 11) +#define MAXSTRLEN 255 struct sLexInitString { char *tzName; @@ -18,7 +19,9 @@ struct sLexFloat { }; struct yy_buffer_state { - char *pBufferStart; + char *pBufferRealStart; // actual starting address + char *pBufferStart; // address where the data is initially written + // after the "safety margin" char *pBuffer; ULONG nBufferSize; ULONG oAtLineStart; diff --git a/src/asm/lexer.c b/src/asm/lexer.c index ead1ee49..a4f43572 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -18,18 +18,18 @@ struct sLexString { ULONG nNameLength; struct sLexString *pNext; }; -#define pLexBuffer (pCurrentBuffer->pBuffer) -#define nLexBufferLeng (pCurrentBuffer->nBufferSize) +#define pLexBufferRealStart (pCurrentBuffer->pBufferRealStart) +#define pLexBuffer (pCurrentBuffer->pBuffer) +#define AtLineStart (pCurrentBuffer->oAtLineStart) #define SAFETYMARGIN 1024 -extern ULONG symvaluetostring(char *dest, char *s); +extern size_t symvaluetostring(char *dest, size_t maxLength, char *sym); struct sLexFloat tLexFloat[32]; struct sLexString *tLexHash[LEXHASHSIZE]; YY_BUFFER_STATE pCurrentBuffer; -ULONG yyleng; -ULONG nLexMaxLeng; +ULONG nLexMaxLength; // max length of all keywords and operators ULONG tFloatingSecondChar[256]; ULONG tFloatingFirstChar[256]; @@ -37,8 +37,6 @@ ULONG tFloatingChars[256]; ULONG nFloating; enum eLexerState lexerstate = LEX_STATE_NORMAL; -#define AtLineStart pCurrentBuffer->oAtLineStart - #ifdef __GNUC__ void strupr(char *s) @@ -73,18 +71,24 @@ yyunputbytes(ULONG count) void yyunput(char c) { + if (pLexBuffer <= pLexBufferRealStart) + fatalerror("Buffer safety margin exceeded"); + *(--pLexBuffer) = c; } void yyunputstr(char *s) { - SLONG i; + int i, len; - i = strlen(s) - 1; + len = strlen(s); - while (i >= 0) - yyunput(s[i--]); + if (pLexBuffer - len < pLexBufferRealStart) + fatalerror("Buffer safety margin exceeded"); + + for (i = len - 1; i >= 0; i--) + *(--pLexBuffer) = s[i]; } void @@ -114,10 +118,10 @@ yy_scan_bytes(char *mem, ULONG size) if ((pBuffer = (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) { - if ((pBuffer->pBuffer = pBuffer->pBufferStart = + if ((pBuffer->pBufferRealStart = (char *) malloc(size + 1 + SAFETYMARGIN)) != NULL) { - pBuffer->pBuffer += SAFETYMARGIN; - pBuffer->pBufferStart += SAFETYMARGIN; + pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN; + pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN; memcpy(pBuffer->pBuffer, mem, size); pBuffer->nBufferSize = size; pBuffer->oAtLineStart = 1; @@ -135,21 +139,20 @@ yy_create_buffer(FILE * f) YY_BUFFER_STATE pBuffer; if ((pBuffer = - (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != - NULL) { + (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) { ULONG size; fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); - if ((pBuffer->pBuffer = pBuffer->pBufferStart = + if ((pBuffer->pBufferRealStart = (char *) malloc(size + 2 + SAFETYMARGIN)) != NULL) { char *mem; ULONG instring = 0; - pBuffer->pBuffer += SAFETYMARGIN; - pBuffer->pBufferStart += SAFETYMARGIN; + pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN; + pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN; size = fread(pBuffer->pBuffer, sizeof(UBYTE), size, f); @@ -167,24 +170,19 @@ yy_create_buffer(FILE * f) mem += 1; } else { if ((mem[0] == 10 && mem[1] == 13) - || (mem[0] == 13 && mem[1] == 10)) { + || (mem[0] == 13 && mem[1] == 10)) { mem[0] = ' '; mem[1] = '\n'; mem += 2; } else if (mem[0] == 10 || mem[0] == 13) { mem[0] = '\n'; mem += 1; - } else if (mem[0] == '\n' - && mem[1] == '*') { + } else if (mem[0] == '\n' && mem[1] == '*') { mem += 1; - while (! - (*mem == '\n' - || *mem == '\0')) + while (!(*mem == '\n' || *mem == '\0')) *mem++ = ' '; } else if (*mem == ';') { - while (! - (*mem == '\n' - || *mem == '\0')) + while (!(*mem == '\n' || *mem == '\0')) *mem++ = ' '; } else mem += 1; @@ -199,17 +197,33 @@ yy_create_buffer(FILE * f) return (NULL); } -ULONG -lex_FloatAlloc(struct sLexFloat * tok) +ULONG +lex_FloatAlloc(struct sLexFloat *token) { - tLexFloat[nFloating] = (*tok); + tLexFloat[nFloating] = *token; return (1 << (nFloating++)); } +/* + * Make sure that only non-zero ASCII characters are used. Also, check if the + * start is greater than the end of the range. + */ +void +lex_CheckCharacterRange(UWORD start, UWORD end) +{ + if (start > end || start < 1 || end > 127) { + fprintf(stderr, "Invalid character range (start: %u, end: %u)\n", + start, end); + exit(1); + } +} + void lex_FloatDeleteRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingChars[start] &= ~id; start += 1; @@ -219,6 +233,8 @@ lex_FloatDeleteRange(ULONG id, UWORD start, UWORD end) void lex_FloatAddRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingChars[start] |= id; start += 1; @@ -228,6 +244,8 @@ lex_FloatAddRange(ULONG id, UWORD start, UWORD end) void lex_FloatDeleteFirstRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingFirstChar[start] &= ~id; start += 1; @@ -237,6 +255,8 @@ lex_FloatDeleteFirstRange(ULONG id, UWORD start, UWORD end) void lex_FloatAddFirstRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingFirstChar[start] |= id; start += 1; @@ -246,6 +266,8 @@ lex_FloatAddFirstRange(ULONG id, UWORD start, UWORD end) void lex_FloatDeleteSecondRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingSecondChar[start] &= ~id; start += 1; @@ -255,6 +277,8 @@ lex_FloatDeleteSecondRange(ULONG id, UWORD start, UWORD end) void lex_FloatAddSecondRange(ULONG id, UWORD start, UWORD end) { + lex_CheckCharacterRange(start, end); + while (start <= end) { tFloatingSecondChar[start] |= id; start += 1; @@ -262,32 +286,32 @@ lex_FloatAddSecondRange(ULONG id, UWORD start, UWORD end) } struct sLexFloat * -lexgetfloat(ULONG id) +lexgetfloat(ULONG nFloatMask) { - ULONG r = 0, mask = 1; - - if (id == 0) - return (NULL); - - while ((id & mask) == 0) { - mask <<= 1; - r += 1; + if (nFloatMask == 0) { + fatalerror("Internal error in lexgetfloat"); } - return (&tLexFloat[r]); + int i = 0; + + while ((nFloatMask & 1) == 0) { + nFloatMask >>= 1; + i++; + } + + return (&tLexFloat[i]); } ULONG lexcalchash(char *s) { - ULONG r = 0; + ULONG hash = 0; while (*s) { - r = ((r << 1) + (toupper(*s))) % LEXHASHSIZE; - s += 1; + hash = (hash * 283) ^ toupper(*s++); } - return (r); + return (hash % LEXHASHSIZE); } void @@ -295,17 +319,17 @@ lex_Init(void) { ULONG i; - for (i = 0; i < LEXHASHSIZE; i += 1) { + for (i = 0; i < LEXHASHSIZE; i++) { tLexHash[i] = NULL; } - for (i = 0; i < 256; i += 1) { + for (i = 0; i < 256; i++) { tFloatingFirstChar[i] = 0; tFloatingSecondChar[i] = 0; tFloatingChars[i] = 0; } - nLexMaxLeng = 0; + nLexMaxLength = 0; nFloating = 0; } @@ -333,8 +357,8 @@ lex_AddStrings(struct sLexInitString * lex) strupr((*ppHash)->tzName); - if ((*ppHash)->nNameLength > nLexMaxLeng) - nLexMaxLeng = (*ppHash)->nNameLength; + if ((*ppHash)->nNameLength > nLexMaxLength) + nLexMaxLength = (*ppHash)->nNameLength; } else fatalerror("Out of memory!"); @@ -345,458 +369,391 @@ lex_AddStrings(struct sLexInitString * lex) } } +/* + * Gets the "float" mask and "float" length. + * "Float" refers to the token type of a token that is not a keyword. + * The character classes floatingFirstChar, floatingSecondChar, and + * floatingChars are defined separately for each token type. + * It uses bit masks to match against a set of simple regular expressions + * of the form /[floatingFirstChar]([floatingSecondChar][floatingChars]*)?/. + * The token types with the longest match from the current position in the + * buffer will have their bits set in the float mask. + */ +void +yylex_GetFloatMaskAndFloatLen(ULONG *pnFloatMask, ULONG *pnFloatLen) +{ + // Note that '\0' should always have a bit mask of 0 in the "floating" + // tables, so it doesn't need to be checked for separately. + + char *s = pLexBuffer; + ULONG nOldFloatMask = 0; + ULONG nFloatMask = tFloatingFirstChar[(int)*s]; + + if (nFloatMask != 0) { + s++; + nOldFloatMask = nFloatMask; + nFloatMask &= tFloatingSecondChar[(int)*s]; + + while (nFloatMask != 0) { + s++; + nOldFloatMask = nFloatMask; + nFloatMask &= tFloatingChars[(int)*s]; + } + } + + *pnFloatMask = nOldFloatMask; + *pnFloatLen = (ULONG)(s - pLexBuffer); +} + +/* + * Gets the longest keyword/operator from the current position in the buffer. + */ +struct sLexString * +yylex_GetLongestFixed() +{ + struct sLexString *pLongestFixed = NULL; + char *s = pLexBuffer; + ULONG hash = 0; + ULONG length = 0; + + while (length < nLexMaxLength && *s) { + hash = (hash * 283) ^ toupper(*s); + s++; + length++; + + struct sLexString *lex = tLexHash[hash % LEXHASHSIZE]; + + while (lex) { + if (lex->nNameLength == length + && strncasecmp(pLexBuffer, lex->tzName, length) == 0) { + pLongestFixed = lex; + break; + } + lex = lex->pNext; + } + } + + return pLongestFixed; +} + +size_t +CopyMacroArg(char *dest, size_t maxLength, char c) +{ + int i; + char *s; + int argNum; + + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + argNum = c - '0'; + break; + case '@': + argNum = -1; + break; + default: + return 0; + } + + if ((s = sym_FindMacroArg(argNum)) == NULL) + fatalerror("Macro argument not defined"); + + for (i = 0; s[i] != 0; i++) { + if (i >= maxLength) { + fatalerror("Macro argument too long to fit buffer"); + } + dest[i] = s[i]; + } + + return i; +} + +static inline void +yylex_StringWriteChar(char *s, size_t index, char c) +{ + if (index >= MAXSTRLEN) { + fatalerror("String too long"); + } + + s[index] = c; +} + +static inline void +yylex_SymbolWriteChar(char *s, size_t index, char c) +{ + if (index >= MAXSYMLEN) { + fatalerror("Symbol too long"); + } + + s[index] = c; +} + +/* + * Trims white space at the end of a string. + * The index parameter is the index of the 0 at the end of the string. + */ +void yylex_TrimEnd(char *s, size_t index) +{ + int i; + + for (i = (int)index - 1; i >= 0 && (s[i] == ' ' || s[i] == '\t'); i--) + s[i] = 0; +} + +size_t +yylex_ReadBracketedSymbol(char *dest, size_t index) +{ + char sym[MAXSYMLEN + 1]; + char ch; + size_t i = 0; + size_t length, maxLength; + + for (ch = *pLexBuffer; + ch != '}' && ch != '"' && ch != '\n'; + ch = *(++pLexBuffer)) { + if (ch == '\\') { + ch = *(++pLexBuffer); + maxLength = MAXSYMLEN - i; + length = CopyMacroArg(&sym[i], maxLength, ch); + + if (length != 0) + i += length; + else + fatalerror("Illegal character escape '%c'", ch); + } else + yylex_SymbolWriteChar(sym, i++, ch); + } + + yylex_SymbolWriteChar(sym, i, 0); + + maxLength = MAXSTRLEN - index; // it's assumed we're writing to a T_STRING + length = symvaluetostring(&dest[index], maxLength, sym); + + if (*pLexBuffer == '}') + pLexBuffer++; + else + yyerror("Missing }"); + + return length; +} + +void +yylex_ReadQuotedString() +{ + size_t index = 0; + size_t length, maxLength; + + while (*pLexBuffer != '"' && *pLexBuffer != '\n') { + char ch = *pLexBuffer++; + + if (ch == '\\') { + ch = *pLexBuffer++; + + switch (ch) { + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case '\\': + ch = '\\'; + break; + case '"': + ch = '"'; + break; + default: + maxLength = MAXSTRLEN - index; + length = CopyMacroArg(&yylval.tzString[index], maxLength, ch); + + if (length != 0) + index += length; + else + fatalerror("Illegal character escape '%c'", ch); + + ch = 0; + break; + } + } else if (ch == '{') { + // Get bracketed symbol within string. + index += yylex_ReadBracketedSymbol(yylval.tzString, index); + ch = 0; + } + + if (ch) + yylex_StringWriteChar(yylval.tzString, index++, ch); + } + + yylex_StringWriteChar(yylval.tzString, index, 0); + + if (*pLexBuffer == '"') + pLexBuffer++; + else + yyerror("Unterminated string"); +} + +ULONG +yylex_NORMAL() +{ + struct sLexString *pLongestFixed = NULL; + ULONG nFloatMask, nFloatLen; + ULONG linestart = AtLineStart; + + AtLineStart = 0; + +scanagain: + while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { + linestart = 0; + pLexBuffer++; + } + + if (*pLexBuffer == 0) { + // Reached the end of a file, macro, or rept. + if (yywrap() == 0) { + linestart = AtLineStart; + AtLineStart = 0; + goto scanagain; + } + } + + // Try to match an identifier, macro argument (e.g. \1), + // or numeric literal. + yylex_GetFloatMaskAndFloatLen(&nFloatMask, &nFloatLen); + + // Try to match a keyword or operator. + pLongestFixed = yylex_GetLongestFixed(); + + if (nFloatLen == 0 && pLongestFixed == NULL) { + // No keyword, identifier, operator, or numerical literal matches. + + if (*pLexBuffer == '"') { + pLexBuffer++; + yylex_ReadQuotedString(); + return T_STRING; + } else if (*pLexBuffer == '{') { + pLexBuffer++; + yylex_ReadBracketedSymbol(yylval.tzString, 0); + return T_STRING; + } else { + // It's not a keyword, operator, identifier, macro argument, + // numeric literal, string, or bracketed symbol, so just return + // the ASCII character. + if (*pLexBuffer == '\n') + AtLineStart = 1; + + return *pLexBuffer++; + } + } + + if (pLongestFixed == NULL || nFloatLen > pLongestFixed->nNameLength) { + // Longest match was an identifier, macro argument, or numeric literal. + struct sLexFloat *token = lexgetfloat(nFloatMask); + + if (token->Callback) { + int done = token->Callback(pLexBuffer, nFloatLen); + if (!done) + goto scanagain; + } + + pLexBuffer += nFloatLen; + + if (token->nToken == T_ID && linestart) { + return T_LABEL; + } else { + return token->nToken; + } + } + + // Longest match was a keyword or operator. + pLexBuffer += pLongestFixed->nNameLength; + return pLongestFixed->nToken; +} + +ULONG +yylex_MACROARGS() +{ + size_t index = 0; + size_t length, maxLength; + + while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { + pLexBuffer++; + } + + while (*pLexBuffer != ',' && (*pLexBuffer != '\n')) { + char ch = *pLexBuffer++; + + if (ch == '\\') { + ch = *pLexBuffer++; + + switch (ch) { + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case '\\': + ch = '\\'; + break; + default: + maxLength = MAXSTRLEN - index; + length = CopyMacroArg(&yylval.tzString[index], maxLength, ch); + + if (length != 0) + index += length; + else + fatalerror("Illegal character escape '%c'", ch); + + ch = 0; + break; + } + } else if (ch == '{') { + index += yylex_ReadBracketedSymbol(yylval.tzString, index); + ch = 0; + } + if (ch) + yylex_StringWriteChar(yylval.tzString, index++, ch); + } + + if (index) { + yylex_StringWriteChar(yylval.tzString, index, 0); + + // trim trailing white space at the end of the line + if (*pLexBuffer == '\n') + yylex_TrimEnd(yylval.tzString, index); + + return T_STRING; + } else if (*pLexBuffer == '\n') { + pLexBuffer++; + AtLineStart = 1; + return '\n'; + } else if (*pLexBuffer == ',') { + pLexBuffer++; + return ','; + } + + fatalerror("Internal error in yylex_MACROARGS"); + return 0; +} + ULONG yylex(void) { - ULONG hash, maxlen; - char *s; - struct sLexString *pLongestFixed = NULL; - ULONG nFloatMask, nOldFloatMask, nFloatLen; - ULONG linestart = AtLineStart; - switch (lexerstate) { case LEX_STATE_NORMAL: - AtLineStart = 0; - -scanagain: - - while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { - linestart = 0; - pLexBuffer += 1; - } - - if (*pLexBuffer == 0) { - if (yywrap() == 0) { - linestart = AtLineStart; - AtLineStart = 0; - goto scanagain; - } - } - s = pLexBuffer; - nOldFloatMask = nFloatLen = 0; - nFloatMask = tFloatingFirstChar[(int) *s++]; - while (nFloatMask && nFloatLen < nLexBufferLeng) { - nFloatLen += 1; - nOldFloatMask = nFloatMask; - if (nFloatLen == 1) - nFloatMask &= tFloatingSecondChar[(int) *s++]; - else - nFloatMask &= tFloatingChars[(int) *s++]; - } - - maxlen = nLexBufferLeng; - if (nLexMaxLeng < maxlen) - maxlen = nLexMaxLeng; - - yyleng = 0; - hash = 0; - s = pLexBuffer; - while (yyleng < nLexMaxLeng) { - /* XXX: Kludge warning! The dereference of s below - * may go beyond the end of the buffer. We use the - * following test to stop that from happening, - * without really understanding what the rest of - * the code is doing. This may not be the correct - * fix! */ - if (!*s) - break; - - yyleng += 1; - hash = ((hash << 1) + (toupper(*s))) % LEXHASHSIZE; - s += 1; - if (tLexHash[hash]) { - struct sLexString *lex; - - lex = tLexHash[hash]; - while (lex) { - if (lex->nNameLength == yyleng) { - if (strncasecmp - (pLexBuffer, lex->tzName, - yyleng) == 0) { - pLongestFixed = lex; - } - } - lex = lex->pNext; - } - } - } - - if (nFloatLen == 0 && pLongestFixed == NULL) { - if (*pLexBuffer == '"') { - ULONG index = 0; - - pLexBuffer += 1; - while ((*pLexBuffer != '"') - && (*pLexBuffer != '\n')) { - char ch, *marg; - - if ((ch = *pLexBuffer++) == '\\') { - switch (ch = (*pLexBuffer++)) { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ((marg = - sym_FindMacroArg(ch - - - '0')) - != NULL) { - while (*marg) - yylval. - tzString - [index++] - = - *marg++; - ch = 0; - } - break; - case '@': - if ((marg = - sym_FindMacroArg - (-1)) != NULL) { - while (*marg) - yylval. - tzString - [index++] - = - *marg++; - ch = 0; - } - break; - } - } else if (ch == '{') { - char sym[MAXSYMLEN]; - int i = 0; - - while ((*pLexBuffer != '}') - && (*pLexBuffer != '"') - && (*pLexBuffer != - '\n')) { - if ((ch = - *pLexBuffer++) == - '\\') { - switch (ch = - (*pLexBuffer++)) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ((marg = sym_FindMacroArg(ch - '0')) != NULL) { - while - (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - case '@': - if ((marg = sym_FindMacroArg(-1)) != NULL) { - while - (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - } - } else - sym[i++] = ch; - } - - sym[i] = 0; - index += - symvaluetostring(&yylval. - tzString - [index], - sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror("Missing }"); - ch = 0; - } - if (ch) - yylval.tzString[index++] = ch; - } - - yylval.tzString[index++] = 0; - - if (*pLexBuffer == '\n') - yyerror("Unterminated string"); - else - pLexBuffer += 1; - - return (T_STRING); - } else if (*pLexBuffer == '{') { - char sym[MAXSYMLEN], ch, *marg; - int i = 0; - - pLexBuffer += 1; - - while ((*pLexBuffer != '}') - && (*pLexBuffer != '\n')) { - if ((ch = *pLexBuffer++) == '\\') { - switch (ch = (*pLexBuffer++)) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ((marg = - sym_FindMacroArg(ch - - - '0')) - != NULL) { - while (*marg) - sym[i++] - = - *marg++; - ch = 0; - } - break; - case '@': - if ((marg = - sym_FindMacroArg - (-1)) != NULL) { - while (*marg) - sym[i++] - = - *marg++; - ch = 0; - } - break; - } - } else - sym[i++] = ch; - } - sym[i] = 0; - symvaluetostring(yylval.tzString, sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror("Missing }"); - - return (T_STRING); - } else { - if (*pLexBuffer == '\n') - AtLineStart = 1; - - yyleng = 1; - return (*pLexBuffer++); - } - } - if (nFloatLen == 0) { - yyleng = pLongestFixed->nNameLength; - pLexBuffer += yyleng; - return (pLongestFixed->nToken); - } - if (pLongestFixed == NULL) { - struct sLexFloat *tok; - - tok = lexgetfloat(nOldFloatMask); - yyleng = nFloatLen; - if (tok->Callback) { - if (tok->Callback(pLexBuffer, yyleng) == 0) - goto scanagain; - } - if (tok->nToken == T_ID && linestart) { - pLexBuffer += yyleng; - return (T_LABEL); - } else { - pLexBuffer += yyleng; - return (tok->nToken); - } - } - if (nFloatLen > pLongestFixed->nNameLength) { - struct sLexFloat *tok; - - tok = lexgetfloat(nOldFloatMask); - yyleng = nFloatLen; - if (tok->Callback) { - if (tok->Callback(pLexBuffer, yyleng) == 0) - goto scanagain; - } - if (tok->nToken == T_ID && linestart) { - pLexBuffer += yyleng; - return (T_LABEL); - } else { - pLexBuffer += yyleng; - return (tok->nToken); - } - } else { - yyleng = pLongestFixed->nNameLength; - pLexBuffer += yyleng; - return (pLongestFixed->nToken); - } - break; - + return yylex_NORMAL(); case LEX_STATE_MACROARGS: - { - ULONG index = 0; - - while (*pLexBuffer == ' ' || *pLexBuffer == '\t') { - linestart = 0; - pLexBuffer += 1; - } - - while ((*pLexBuffer != ',') - && (*pLexBuffer != '\n')) { - char ch, *marg; - - if ((ch = *pLexBuffer++) == '\\') { - switch (ch = (*pLexBuffer++)) { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ((marg = - sym_FindMacroArg(ch - - '0')) != - NULL) { - while (*marg) - yylval. - tzString - [index++] = - *marg++; - ch = 0; - } - break; - case '@': - if ((marg = - sym_FindMacroArg(-1)) != - NULL) { - while (*marg) - yylval. - tzString - [index++] = - *marg++; - ch = 0; - } - break; - } - } else if (ch == '{') { - char sym[MAXSYMLEN]; - int i = 0; - - while ((*pLexBuffer != '}') - && (*pLexBuffer != '"') - && (*pLexBuffer != '\n')) { - if ((ch = - *pLexBuffer++) == '\\') { - switch (ch = - (*pLexBuffer++)) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if ((marg = - sym_FindMacroArg - (ch - - '0')) != - NULL) { - while - (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - case '@': - if ((marg = - sym_FindMacroArg - (-1)) != - NULL) { - while - (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - } - } else - sym[i++] = ch; - } - sym[i] = 0; - index += - symvaluetostring(&yylval. - tzString[index], - sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror("Missing }"); - ch = 0; - } - if (ch) - yylval.tzString[index++] = ch; - } - - if (index) { - yyleng = index; - yylval.tzString[index] = 0; - if (*pLexBuffer == '\n') { - while (yylval.tzString[--index] == ' ') { - yylval.tzString[index] = 0; - yyleng -= 1; - } - } - return (T_STRING); - } else if (*pLexBuffer == '\n') { - pLexBuffer += 1; - AtLineStart = 1; - yyleng = 1; - return ('\n'); - } else if (*pLexBuffer == ',') { - pLexBuffer += 1; - yyleng = 1; - return (','); - } else { - yyerror("INTERNAL ERROR IN YYLEX"); - return (0); - } - } - - break; + return yylex_MACROARGS(); } - yyerror("INTERNAL ERROR IN YYLEX"); - return (0); + fatalerror("Internal error in yylex"); + return 0; } diff --git a/src/asm/yaccprt1.y b/src/asm/yaccprt1.y index ea99ff52..8464d370 100644 --- a/src/asm/yaccprt1.y +++ b/src/asm/yaccprt1.y @@ -21,14 +21,38 @@ extern bool haltnop; char *tzNewMacro; ULONG ulNewMacroSize; -ULONG symvaluetostring( char *dest, char *sym ) +size_t symvaluetostring(char *dest, size_t maxLength, char *sym) { - if( sym_isString(sym) ) - strcpy( dest, sym_GetStringValue(sym) ); - else - sprintf( dest, "$%lX", sym_GetConstantValue(sym) ); + size_t length; - return( strlen(dest) ); + if (sym_isString(sym)) { + char *src = sym_GetStringValue(sym); + size_t i; + + for (i = 0; src[i] != 0; i++) { + if (i >= maxLength) { + fatalerror("Symbol value too long to fit buffer"); + } + dest[i] = src[i]; + } + + length = i; + } else { + ULONG value = sym_GetConstantValue(sym); + int fullLength = snprintf(dest, maxLength + 1, "$%lX", value); + + if (fullLength < 0) { + fatalerror("snprintf encoding error"); + } else { + length = (size_t)fullLength; + + if (length > maxLength) { + fatalerror("Symbol value too long to fit buffer"); + } + } + } + + return length; } ULONG str2int( char *s ) @@ -335,8 +359,8 @@ void if_skip_to_endc( void ) %union { - char tzSym[MAXSYMLEN+1]; - char tzString[256]; + char tzSym[MAXSYMLEN + 1]; + char tzString[MAXSTRLEN + 1]; struct Expression sVal; SLONG nConstValue; } From 284600ef1f634fd21b3e8daac345015cbb76b560 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Tue, 23 Sep 2014 22:17:43 -0600 Subject: [PATCH 11/36] rgblink: Don't allocate unnecessary buffer. Delete unused flag. --- src/link/output.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/link/output.c b/src/link/output.c index f849bb1d..7adfc8f1 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -7,8 +7,7 @@ #include "link/main.h" #include "link/assign.h" -char tzOutname[_MAX_PATH]; -BBOOL oOutput = 0; +char *tzOutname; void writehome(FILE * f) @@ -71,8 +70,7 @@ writebank(FILE * f, SLONG bank) void out_Setname(char *tzOutputfile) { - strcpy(tzOutname, tzOutputfile); - oOutput = 1; + tzOutname = tzOutputfile; } void From 056109652d78701062ff0bb925a07c2c6ad33a2c Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Tue, 23 Sep 2014 22:22:39 -0600 Subject: [PATCH 12/36] rgbasm: Don't allocate an unnecessary buffer. --- 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 c36b0e88..fe075cee 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -61,7 +61,7 @@ struct PatchSymbol *tHashedPatchSymbols[HASHSIZE]; struct Section *pSectionList = NULL, *pCurrentSection = NULL; struct PatchSymbol *pPatchSymbols = NULL; struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols; -char tzObjectname[_MAX_PATH]; +char *tzObjectname; struct SectionStackEntry *pSectionStack = NULL; /* @@ -592,7 +592,7 @@ out_PrepPass2(void) void out_SetFileName(char *s) { - strcpy(tzObjectname, s); + tzObjectname = s; if (CurrentOptions.verbose) { printf("Output filename %s\n", s); } From 45b6872e2ad5374c146d1ddca61487976ba65f84 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 00:23:40 -0600 Subject: [PATCH 13/36] rgbasm: Fix TOCTOU and reduce buffering. --- Makefile | 4 +- include/asm/fstack.h | 11 +++-- src/asm/fstack.c | 111 ++++++++++++++++++++++++------------------- src/asm/main.c | 111 +++++++++++++++++++++---------------------- src/asm/output.c | 90 +++++++++++++++++++---------------- src/asm/yaccprt3.y | 5 +- src/extern/strlcat.c | 55 +++++++++++++++++++++ src/extern/strlcpy.c | 51 ++++++++++++++++++++ 8 files changed, 282 insertions(+), 156 deletions(-) create mode 100644 src/extern/strlcat.c create mode 100644 src/extern/strlcpy.c diff --git a/Makefile b/Makefile index b90d0875..bc4d0225 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,9 @@ rgbasm_obj := \ src/asm/output.o \ src/asm/rpn.o \ src/asm/symbol.o \ - src/asm/gameboy/locallex.o + src/asm/gameboy/locallex.o \ + src/extern/strlcpy.o \ + src/extern/strlcat.o rgblib_obj := \ src/lib/library.o \ diff --git a/include/asm/fstack.h b/include/asm/fstack.h index 9978a3e2..c3ca1ef0 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -9,6 +9,8 @@ #ifndef ASMOTOR_ASM_FSTACK_H #define ASMOTOR_ASM_FSTACK_H +#include + #include "asm/asm.h" #include "asm/types.h" #include "asm/lexer.h" @@ -27,14 +29,17 @@ struct sContext { ULONG nREPTBlockSize; }; -extern ULONG fstk_RunInclude(char *s); +void +fstk_RunInclude(char *); extern void fstk_RunMacroArg(SLONG s); -extern ULONG fstk_Init(char *s); +void +fstk_Init(char *); extern void fstk_Dump(void); extern void fstk_AddIncludePath(char *s); extern ULONG fstk_RunMacro(char *s); extern void fstk_RunRept(ULONG count); -extern void fstk_FindFile(char *s); +FILE * +fstk_FindFile(char *); extern int yywrap(void); diff --git a/src/asm/fstack.c b/src/asm/fstack.c index b7c3d489..8fe3b1ee 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -5,10 +5,19 @@ * */ +#include +#include #include #include #include +#ifndef STRL_IN_LIBC +#define strlcpy rgbds_strlcpy +#define strlcat rgbds_strlcat +size_t strlcpy(char *, const char *, size_t); +size_t strlcat(char *, const char *, size_t); +#endif + #include "asm/symbol.h" #include "asm/fstack.h" #include "asm/types.h" @@ -195,28 +204,33 @@ fstk_AddIncludePath(char *s) strcpy(IncludePaths[NextIncPath++], s); } -void -fstk_FindFile(char *s) +FILE * +fstk_FindFile(char *fname) { - char t[_MAX_PATH + 1]; - SLONG i = -1; + char path[PATH_MAX]; + int i; + FILE *f; - strcpy(t, s); + if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) { + return f; + } - while (i < NextIncPath) { - FILE *f; - - if ((f = fopen(t, "rb")) != NULL) { - fclose(f); - strcpy(s, t); - return; + for (i = 0; i < NextIncPath; ++i) { + if (strlcpy(path, IncludePaths[i], sizeof path) >= + sizeof path) { + continue; } - i += 1; - if (i < NextIncPath) { - strcpy(t, IncludePaths[i]); - strcat(t, s); + if (strlcat(path, fname, sizeof path) >= sizeof path) { + continue; + } + + if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) { + return f; } } + + errno = ENOENT; + return NULL; } /* * RGBAsm - FSTACK.C (FileStack routines) @@ -225,33 +239,32 @@ fstk_FindFile(char *s) * */ -ULONG +void fstk_RunInclude(char *tzFileName) { FILE *f; - //printf("INCLUDE: %s\n", s); + f = fstk_FindFile(tzFileName); - fstk_FindFile(tzFileName); - //printf("INCLUDING: %s\n", tzFileName); + if (f == NULL) { + fprintf(stderr, "Unable to open included file '%s': ", + tzFileName); + perror(NULL); + exit(1); + } - if ((f = fopen(tzFileName, "r")) != NULL) { - pushcontext(); - nLineNo = 1; - nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); - pCurrentFile = f; - CurrentFlexHandle = yy_create_buffer(pCurrentFile); - yy_switch_to_buffer(CurrentFlexHandle); + pushcontext(); + nLineNo = 1; + nCurrentStatus = STAT_isInclude; + strcpy(tzCurrentFileName, tzFileName); + pCurrentFile = f; + CurrentFlexHandle = yy_create_buffer(pCurrentFile); + yy_switch_to_buffer(CurrentFlexHandle); - //Dirty hack to give the INCLUDE directive a linefeed + //Dirty hack to give the INCLUDE directive a linefeed - yyunput('\n'); - nLineNo -= 1; - - return (1); - } else - return (0); + yyunput('\n'); + nLineNo -= 1; } /* * RGBAsm - FSTACK.C (FileStack routines) @@ -360,7 +373,7 @@ fstk_RunRept(ULONG count) * */ -ULONG +void fstk_Init(char *s) { char tzFileName[_MAX_PATH + 1]; @@ -368,17 +381,19 @@ fstk_Init(char *s) sym_AddString("__FILE__", s); strcpy(tzFileName, s); - fstk_FindFile(tzFileName); - pFileStack = NULL; - if ((pCurrentFile = fopen(tzFileName, "r")) != NULL) { - nMacroCount = 0; - nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); - CurrentFlexHandle = yy_create_buffer(pCurrentFile); - yy_switch_to_buffer(CurrentFlexHandle); - nLineNo = 1; - return (1); - } else - return (0); + pCurrentFile = fopen(tzFileName, "rb"); + if (pCurrentFile == NULL) { + fprintf(stderr, "Unable to open file '%s': ", + tzFileName); + perror(NULL); + exit(1); + } + + nMacroCount = 0; + nCurrentStatus = STAT_isInclude; + strcpy(tzCurrentFileName, tzFileName); + CurrentFlexHandle = yy_create_buffer(pCurrentFile); + yy_switch_to_buffer(CurrentFlexHandle); + nLineNo = 1; } diff --git a/src/asm/main.c b/src/asm/main.c index 46194cfd..f5d14439 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -348,7 +348,6 @@ main(int argc, char *argv[]) DefaultOptions = CurrentOptions; - /* tzMainfile=argv[argn++]; argc-=1; */ tzMainfile = argv[argc - 1]; setuplex(); @@ -366,75 +365,71 @@ main(int argc, char *argv[]) nPass = 1; nErrors = 0; sym_PrepPass1(); - if (fstk_Init(tzMainfile)) { - if (CurrentOptions.verbose) { - printf("Pass 1...\n"); - } + fstk_Init(tzMainfile); + if (CurrentOptions.verbose) { + printf("Pass 1...\n"); + } - yy_set_state(LEX_STATE_NORMAL); - opt_SetCurrentOptions(&DefaultOptions); + yy_set_state(LEX_STATE_NORMAL); + opt_SetCurrentOptions(&DefaultOptions); - if (yyparse() == 0 && nErrors == 0) { - if (nIFDepth == 0) { - nTotalLines = 0; - nLineNo = 1; - nIFDepth = 0; - nPC = 0; - nPass = 2; - nErrors = 0; - sym_PrepPass2(); - out_PrepPass2(); - fstk_Init(tzMainfile); - yy_set_state(LEX_STATE_NORMAL); - opt_SetCurrentOptions(&DefaultOptions); + if (yyparse() == 0 && nErrors == 0) { + if (nIFDepth == 0) { + nTotalLines = 0; + nLineNo = 1; + nIFDepth = 0; + nPC = 0; + nPass = 2; + nErrors = 0; + sym_PrepPass2(); + out_PrepPass2(); + fstk_Init(tzMainfile); + yy_set_state(LEX_STATE_NORMAL); + opt_SetCurrentOptions(&DefaultOptions); + if (CurrentOptions.verbose) { + printf("Pass 2...\n"); + } + + if (yyparse() == 0 && nErrors == 0) { + double timespent; + + nEndClock = clock(); + timespent = + ((double) (nEndClock - nStartClock)) + / (double) CLOCKS_PER_SEC; if (CurrentOptions.verbose) { - printf("Pass 2...\n"); - } - - if (yyparse() == 0 && nErrors == 0) { - double timespent; - - nEndClock = clock(); - timespent = - ((double) (nEndClock - nStartClock)) - / (double) CLOCKS_PER_SEC; - if (CurrentOptions.verbose) { - printf - ("Success! %ld lines in %d.%02d seconds ", - nTotalLines, (int) timespent, - ((int) (timespent * 100.0)) % 100); - if (timespent == 0) - printf - ("(INFINITY lines/minute)\n"); - else - printf("(%d lines/minute)\n", - (int) (60 / timespent * - nTotalLines)); - } - out_WriteObject(); - } else { printf - ("Assembly aborted in pass 2 (%ld errors)!\n", - nErrors); - //sym_PrintSymbolTable(); - exit(5); + ("Success! %ld lines in %d.%02d seconds ", + nTotalLines, (int) timespent, + ((int) (timespent * 100.0)) % 100); + if (timespent == 0) + printf + ("(INFINITY lines/minute)\n"); + else + printf("(%d lines/minute)\n", + (int) (60 / timespent * + nTotalLines)); } + out_WriteObject(); } else { - fprintf(stderr, - "Unterminated IF construct (%ld levels)!\n", - nIFDepth); - exit(1); + printf + ("Assembly aborted in pass 2 (%ld errors)!\n", + nErrors); + //sym_PrintSymbolTable(); + exit(5); } } else { fprintf(stderr, - "Assembly aborted in pass 1 (%ld errors)!\n", - nErrors); + "Unterminated IF construct (%ld levels)!\n", + nIFDepth); exit(1); } } else { - printf("File '%s' not found\n", tzMainfile); - exit(5); + fprintf(stderr, + "Assembly aborted in pass 1 (%ld errors)!\n", + nErrors); + exit(1); } - return (0); + return 0; } diff --git a/src/asm/output.c b/src/asm/output.c index fe075cee..c60919d4 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -907,30 +907,33 @@ out_BinaryFile(char *s) { FILE *f; - fstk_FindFile(s); + f = fstk_FindFile(s); + if (f == NULL) { + fprintf(stderr, "Unable to open incbin file '%s': ", + s); + perror(NULL); + exit(1); + } - if ((f = fopen(s, "rb")) != NULL) { - SLONG fsize; + SLONG fsize; - fseek(f, 0, SEEK_END); - fsize = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(f, 0, SEEK_END); + fsize = ftell(f); + fseek(f, 0, SEEK_SET); - checkcodesection(fsize); + checkcodesection(fsize); - if (nPass == 2) { - SLONG dest = nPC; - SLONG todo = fsize; + if (nPass == 2) { + SLONG dest = nPC; + SLONG todo = fsize; - while (todo--) - pCurrentSection->tData[dest++] = fgetc(f); - } - pCurrentSection->nPC += fsize; - nPC += fsize; - pPCSymbol->nValue += fsize; - fclose(f); - } else - fatalerror("Could not open file '%s': %s", s, strerror(errno)); + while (todo--) + pCurrentSection->tData[dest++] = fgetc(f); + } + pCurrentSection->nPC += fsize; + nPC += fsize; + pPCSymbol->nValue += fsize; + fclose(f); } void @@ -944,36 +947,39 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length) if (length < 0) fatalerror("Number of bytes to read must be greater than zero"); - fstk_FindFile(s); + f = fstk_FindFile(s); + if (f == NULL) { + fprintf(stderr, "Unable to open included file '%s': ", + s); + perror(NULL); + exit(1); + } - if ((f = fopen(s, "rb")) != NULL) { - SLONG fsize; + SLONG fsize; - fseek(f, 0, SEEK_END); - fsize = ftell(f); + fseek(f, 0, SEEK_END); + fsize = ftell(f); - if (start_pos >= fsize) - fatalerror("Specified start position is greater than length of file"); + if (start_pos >= fsize) + fatalerror("Specified start position is greater than length of file"); - if ((start_pos + length) > fsize) - fatalerror("Specified range in INCBIN is out of bounds"); + if ((start_pos + length) > fsize) + fatalerror("Specified range in INCBIN is out of bounds"); - fseek(f, start_pos, SEEK_SET); + fseek(f, start_pos, SEEK_SET); - checkcodesection(length); + checkcodesection(length); - if (nPass == 2) { - SLONG dest = nPC; - SLONG todo = length; + if (nPass == 2) { + SLONG dest = nPC; + SLONG todo = length; - while (todo--) - pCurrentSection->tData[dest++] = fgetc(f); - } - pCurrentSection->nPC += length; - nPC += length; - pPCSymbol->nValue += length; + while (todo--) + pCurrentSection->tData[dest++] = fgetc(f); + } + pCurrentSection->nPC += length; + nPC += length; + pPCSymbol->nValue += length; - fclose(f); - } else - fatalerror("Could not open file '%s': %s", s, strerror(errno)); + fclose(f); } diff --git a/src/asm/yaccprt3.y b/src/asm/yaccprt3.y index f0a50a90..48c3c996 100644 --- a/src/asm/yaccprt3.y +++ b/src/asm/yaccprt3.y @@ -265,10 +265,7 @@ set : T_LABEL T_POP_SET const include : T_POP_INCLUDE string { - if( !fstk_RunInclude($2) ) - { - yyerror("Could not open file '%s' : %s\n", $2, strerror(errno)); - } + fstk_RunInclude($2); } ; diff --git a/src/extern/strlcat.c b/src/extern/strlcat.c new file mode 100644 index 00000000..ca202404 --- /dev/null +++ b/src/extern/strlcat.c @@ -0,0 +1,55 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +rgbds_strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/src/extern/strlcpy.c b/src/extern/strlcpy.c new file mode 100644 index 00000000..f20c00c2 --- /dev/null +++ b/src/extern/strlcpy.c @@ -0,0 +1,51 @@ +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +rgbds_strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} From cb383e6b1aed8690fa642eab9d66f52b94056739 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 00:26:46 -0600 Subject: [PATCH 14/36] Unclutter Makefile: use $Q instead of ${Q}. --- Makefile | 64 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index bc4d0225..03b465ba 100644 --- a/Makefile +++ b/Makefile @@ -46,53 +46,53 @@ rgbfix_obj := \ all: rgbasm rgblib rgblink rgbfix clean: - ${Q}rm -rf rgbds.html - ${Q}rm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html - ${Q}rm -rf rgblib rgblib.exe ${rgblib_obj} rgblib.html - ${Q}rm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html - ${Q}rm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html - ${Q}rm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y + $Qrm -rf rgbds.html + $Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html + $Qrm -rf rgblib rgblib.exe ${rgblib_obj} rgblib.html + $Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html + $Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html + $Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y install: all - ${Q}install -s -m 555 rgbasm ${BINPREFIX}/rgbasm - ${Q}install -s -m 555 rgbfix ${BINPREFIX}/rgbfix - ${Q}install -s -m 555 rgblink ${BINPREFIX}/rgblink - ${Q}install -s -m 555 rgblib ${BINPREFIX}/rgblib - ${Q}install -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \ + $Qinstall -s -m 555 rgbasm ${BINPREFIX}/rgbasm + $Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix + $Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink + $Qinstall -s -m 555 rgblib ${BINPREFIX}/rgblib + $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \ (echo Installing manpages to ${MANPREFIX} failed. >&2 && \ echo Check where your manpages are installed and set the \ proper directory >&2 && \ echo with, e.g., make install MANPREFIX=/usr/share/man \ >&2 ; false) - ${Q}install -m 444 src/asm/rgbasm.1 \ + $Qinstall -m 444 src/asm/rgbasm.1 \ ${MANPREFIX}/man1/rgbasm.1 - ${Q}install -m 444 src/fix/rgbfix.1 \ + $Qinstall -m 444 src/fix/rgbfix.1 \ ${MANPREFIX}/man1/rgbfix.1 - ${Q}install -m 444 src/link/rgblink.1 \ + $Qinstall -m 444 src/link/rgblink.1 \ ${MANPREFIX}/man1/rgblink.1 - ${Q}install -m 444 src/lib/rgblib.1 \ + $Qinstall -m 444 src/lib/rgblib.1 \ ${MANPREFIX}/man1/rgblib.1 rgbasm: ${rgbasm_obj} - ${Q}${CC} ${CFLAGS} -o $@ ${rgbasm_obj} -lm + $Q${CC} ${CFLAGS} -o $@ ${rgbasm_obj} -lm rgblib: ${rgblib_obj} - ${Q}${CC} ${CFLAGS} -o $@ ${rgblib_obj} + $Q${CC} ${CFLAGS} -o $@ ${rgblib_obj} rgblink: ${rgblink_obj} - ${Q}${CC} ${CFLAGS} -o $@ ${rgblink_obj} + $Q${CC} ${CFLAGS} -o $@ ${rgblink_obj} rgbfix: ${rgbfix_obj} - ${Q}${CC} ${CFLAGS} -o $@ ${rgbfix_obj} + $Q${CC} ${CFLAGS} -o $@ ${rgbfix_obj} .c.o: - ${Q}${CC} ${CFLAGS} -c -o $@ $< + $Q${CC} ${CFLAGS} -c -o $@ $< src/asm/asmy.c: src/asm/asmy.y - ${Q}${YACC} -d -o $@ $< + $Q${YACC} -d -o $@ $< src/asm/asmy.y: ${yacc_pre} - ${Q}cat ${yacc_pre} > $@ + $Qcat ${yacc_pre} > $@ # Below is a target for the project maintainer to easily create win32 exes. @@ -100,19 +100,19 @@ src/asm/asmy.y: ${yacc_pre} # If you're building on Windows with Cygwin or Mingw, just follow the Unix # install instructions instead. mingw: - ${Q}env PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" - ${Q}mv rgbasm rgbasm.exe - ${Q}mv rgblib rgblib.exe - ${Q}mv rgblink rgblink.exe - ${Q}mv rgbfix rgbfix.exe + $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" + $Qmv rgbasm rgbasm.exe + $Qmv rgblib rgblib.exe + $Qmv rgblink rgblink.exe + $Qmv rgbfix rgbfix.exe # Below is a target for the project maintainer to easily create web manuals. # It relies on mandoc: http://mdocml.bsd.lv MANDOC = -Thtml -Oman=/rgbds/manual/%N/ -Ostyle=/rgbds/manual/manual.css -Ios=General wwwman: - ${Q}mandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html - ${Q}mandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > rgbasm.html - ${Q}mandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > rgbfix.html - ${Q}mandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > rgblib.html - ${Q}mandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > rgblink.html + $Qmandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html + $Qmandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > rgbasm.html + $Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > rgbfix.html + $Qmandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > rgblib.html + $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > rgblink.html From a41bdff88f3a9315394fb3c4a39d0f4adf505492 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 00:28:14 -0600 Subject: [PATCH 15/36] Wrap Makefile to 80 characters. --- Makefile | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 03b465ba..ac9acbef 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,8 @@ src/asm/asmy.y: ${yacc_pre} # If you're building on Windows with Cygwin or Mingw, just follow the Unix # install instructions instead. mingw: - $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" + $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \ + make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" $Qmv rgbasm rgbasm.exe $Qmv rgblib rgblib.exe $Qmv rgblink rgblink.exe @@ -108,11 +109,16 @@ mingw: # Below is a target for the project maintainer to easily create web manuals. # It relies on mandoc: http://mdocml.bsd.lv -MANDOC = -Thtml -Oman=/rgbds/manual/%N/ -Ostyle=/rgbds/manual/manual.css -Ios=General +MANDOC = -Thtml -Ios=General -Oman=/rgbds/manual/%N/ \ + -Ostyle=/rgbds/manual/manual.css wwwman: $Qmandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html - $Qmandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > rgbasm.html - $Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > rgbfix.html - $Qmandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > rgblib.html - $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > rgblink.html + $Qmandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > \ + rgbasm.html + $Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > \ + rgbfix.html + $Qmandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > \ + rgblib.html + $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \ + rgblink.html From a849e1107e0c9bfedc0ab04cefc6a0d75947421d Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 00:38:19 -0600 Subject: [PATCH 16/36] Improve POSIX compliance in the Makefile. Set .POSIX and don't use the += operator. --- Makefile | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index ac9acbef..c8eb9427 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS += -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99 +REALCFLAGS = ${CFLAGS} -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99 # User-defined variables PREFIX = /usr/local @@ -74,19 +74,19 @@ install: all ${MANPREFIX}/man1/rgblib.1 rgbasm: ${rgbasm_obj} - $Q${CC} ${CFLAGS} -o $@ ${rgbasm_obj} -lm + $Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm rgblib: ${rgblib_obj} - $Q${CC} ${CFLAGS} -o $@ ${rgblib_obj} + $Q${CC} ${REALCFLAGS} -o $@ ${rgblib_obj} rgblink: ${rgblink_obj} - $Q${CC} ${CFLAGS} -o $@ ${rgblink_obj} + $Q${CC} ${REALCFLAGS} -o $@ ${rgblink_obj} rgbfix: ${rgbfix_obj} - $Q${CC} ${CFLAGS} -o $@ ${rgbfix_obj} + $Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj} .c.o: - $Q${CC} ${CFLAGS} -c -o $@ $< + $Q${CC} ${REALCFLAGS} -c -o $@ $< src/asm/asmy.c: src/asm/asmy.y $Q${YACC} -d -o $@ $< @@ -122,3 +122,5 @@ wwwman: rgblib.html $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \ rgblink.html + +.POSIX: From 97d431d1f4ad404e282e3781bd195be3f053734d Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 00:52:00 -0600 Subject: [PATCH 17/36] rgbasm: Avoid unnecessary filename copying. --- include/asm/asm.h | 2 +- include/asm/fstack.h | 2 +- src/asm/fstack.c | 41 +++++++---------------------------------- 3 files changed, 9 insertions(+), 36 deletions(-) diff --git a/include/asm/asm.h b/include/asm/asm.h index bde48eb3..d6a08848 100644 --- a/include/asm/asm.h +++ b/include/asm/asm.h @@ -24,7 +24,7 @@ extern ULONG nTotalLines; extern ULONG nPC; extern ULONG nPass; extern ULONG nIFDepth; -extern char tzCurrentFileName[_MAX_PATH + 1]; +extern char *tzCurrentFileName; extern struct Section *pCurrentSection; extern struct sSymbol *tHashedSymbols[HASHSIZE]; extern struct sSymbol *pPCSymbol; diff --git a/include/asm/fstack.h b/include/asm/fstack.h index c3ca1ef0..92e4c101 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -19,7 +19,7 @@ struct sContext { YY_BUFFER_STATE FlexHandle; struct sSymbol *pMacro; struct sContext *pNext; - char tzFileName[_MAX_PATH + 1]; + char *tzFileName; char *tzMacroArgs[MAXMACROARGS + 1]; SLONG nLine; ULONG nStatus; diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 8fe3b1ee..a06f5afc 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -36,7 +36,7 @@ struct sSymbol *pCurrentMacro; YY_BUFFER_STATE CurrentFlexHandle; FILE *pCurrentFile; ULONG nCurrentStatus; -char tzCurrentFileName[_MAX_PATH + 1]; +char *tzCurrentFileName; char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; SLONG NextIncPath = 0; ULONG nMacroCount; @@ -75,8 +75,7 @@ pushcontext(void) (struct sContext *) malloc(sizeof(struct sContext))) != NULL) { (*ppFileStack)->FlexHandle = CurrentFlexHandle; (*ppFileStack)->pNext = NULL; - strcpy((char *) (*ppFileStack)->tzFileName, - (char *) tzCurrentFileName); + (*ppFileStack)->tzFileName = tzCurrentFileName; (*ppFileStack)->nLine = nLineNo; switch ((*ppFileStack)->nStatus = nCurrentStatus) { case STAT_isMacroArg: @@ -137,8 +136,7 @@ popcontext(void) nLineNo += 1; CurrentFlexHandle = pLastFile->FlexHandle; - strcpy((char *) tzCurrentFileName, - (char *) pLastFile->tzFileName); + tzCurrentFileName = pLastFile->tzFileName; switch (nCurrentStatus = pLastFile->nStatus) { case STAT_isMacroArg: case STAT_isMacro: @@ -256,7 +254,7 @@ fstk_RunInclude(char *tzFileName) pushcontext(); nLineNo = 1; nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); + tzCurrentFileName = tzFileName; pCurrentFile = f; CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); @@ -284,7 +282,7 @@ fstk_RunMacro(char *s) nLineNo = -1; sym_UseNewMacroArgs(); nCurrentStatus = STAT_isMacro; - strcpy(tzCurrentFileName, s); + tzCurrentFileName = s; pCurrentMacro = sym; CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, @@ -294,32 +292,7 @@ fstk_RunMacro(char *s) } else return (0); } -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up a macroargument for parsing - * - */ -void -fstk_RunMacroArg(SLONG s) -{ - char *sym; - - if (s == '@') - s = -1; - else - s -= '0'; - - if ((sym = sym_FindMacroArg(s)) != NULL) { - pushcontext(); - nCurrentStatus = STAT_isMacroArg; - sprintf(tzCurrentFileName, "%c", (UBYTE) s); - CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym)); - yy_switch_to_buffer(CurrentFlexHandle); - } else - fatalerror("No such macroargument"); -} /* * RGBAsm - FSTACK.C (FileStack routines) * @@ -335,7 +308,7 @@ fstk_RunString(char *s) if ((pSym = sym_FindSymbol(s)) != NULL) { pushcontext(); nCurrentStatus = STAT_isMacroArg; - strcpy(tzCurrentFileName, s); + tzCurrentFileName = s; CurrentFlexHandle = yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro)); yy_switch_to_buffer(CurrentFlexHandle); @@ -392,7 +365,7 @@ fstk_Init(char *s) nMacroCount = 0; nCurrentStatus = STAT_isInclude; - strcpy(tzCurrentFileName, tzFileName); + tzCurrentFileName = tzFileName; CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); nLineNo = 1; From c0be5ddbb28f8e1826b5a9b1d72f1994f348c9d9 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 01:19:05 -0600 Subject: [PATCH 18/36] Remove dead stores. --- src/fix/main.c | 2 -- src/lib/main.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/fix/main.c b/src/fix/main.c index f13bc14e..3c7c676a 100644 --- a/src/fix/main.c +++ b/src/fix/main.c @@ -221,8 +221,6 @@ main(int argc, char *argv[]) /* NOTREACHED */ } } - argc -= optind; - argv += optind; /* * Write changes to ROM diff --git a/src/lib/main.c b/src/lib/main.c index 6c023350..42d553cc 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -98,9 +98,6 @@ main(int argc, char *argv[]) } lib_Free(lib); } else if (strcmp(argv[argn], "list") == 0) { - argn += 1; - argc -= 1; - sLibrary *l; l = lib; From d661b3a5329756fe334548bf8b23d65bd67de4be Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 02:50:39 -0600 Subject: [PATCH 19/36] Now that we replace missing libc functions, switch back to err(). --- Makefile | 10 +++- include/extern/err.h | 63 ++++++++++++++++++++ include/extern/strl.h | 13 +++++ src/asm/fstack.c | 18 ++---- src/asm/lexer.c | 6 +- src/asm/main.c | 44 ++++++-------- src/asm/output.c | 11 +--- src/extern/err.c | 90 +++++++++++++++++++++++++++++ src/fix/main.c | 86 ++++++++++------------------ src/lib/library.c | 31 ++++------ src/lib/main.c | 7 +-- src/link/assign.c | 130 +++++++++++++++--------------------------- src/link/library.c | 4 +- src/link/main.c | 4 +- src/link/mapfile.c | 8 +-- src/link/object.c | 58 ++++++------------- src/link/patch.c | 32 +++++------ src/link/symbol.c | 12 ++-- 18 files changed, 331 insertions(+), 296 deletions(-) create mode 100644 include/extern/err.h create mode 100644 include/extern/strl.h create mode 100644 src/extern/err.c diff --git a/Makefile b/Makefile index c8eb9427..a89f586e 100644 --- a/Makefile +++ b/Makefile @@ -23,12 +23,14 @@ rgbasm_obj := \ src/asm/rpn.o \ src/asm/symbol.o \ src/asm/gameboy/locallex.o \ + src/extern/err.o \ src/extern/strlcpy.o \ src/extern/strlcat.o rgblib_obj := \ src/lib/library.o \ - src/lib/main.o + src/lib/main.o \ + src/extern/err.o rgblink_obj := \ src/link/assign.o \ @@ -38,10 +40,12 @@ rgblink_obj := \ src/link/object.o \ src/link/output.o \ src/link/patch.o \ - src/link/symbol.o + src/link/symbol.o \ + src/extern/err.o rgbfix_obj := \ - src/fix/main.o + src/fix/main.o \ + src/extern/err.o all: rgbasm rgblib rgblink rgbfix diff --git a/include/extern/err.h b/include/extern/err.h new file mode 100644 index 00000000..ffb4f26d --- /dev/null +++ b/include/extern/err.h @@ -0,0 +1,63 @@ +/* + * Copyright © 2005-2013 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef EXTERN_ERR_H +#define EXTERN_ERR_H + +#ifdef ERR_IN_LIBC +#include +#else + +#include + +#define warn rgbds_warn +#define vwarn rgbds_vwarn +#define warnx rgbds_warnx +#define vwarnx rgbds_vwarnx + +#define err rgbds_err +#define verr rgbds_verr +#define errx rgbds_errx +#define verrx rgbds_verrx + +#ifdef __cplusplus +extern "C" { +#endif + +void warn(const char *, ...); +void vwarn(const char *, va_list); +void warnx(const char *, ...); +void vwarnx(const char *, va_list); + +void err(int, const char *, ...); +void verr(int, const char *, va_list); +void errx(int, const char *, ...); +void verrx(int, const char *, va_list); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/include/extern/strl.h b/include/extern/strl.h new file mode 100644 index 00000000..02c9bd43 --- /dev/null +++ b/include/extern/strl.h @@ -0,0 +1,13 @@ +#ifndef STRL_H +#define STRL_H + +#ifdef STRL_IN_LIBC +#include +#else +#define strlcpy rgbds_strlcpy +#define strlcat rgbds_strlcat +size_t strlcpy(char *, const char *, size_t); +size_t strlcat(char *, const char *, size_t); +#endif + +#endif diff --git a/src/asm/fstack.c b/src/asm/fstack.c index a06f5afc..40abba0b 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -11,18 +11,13 @@ #include #include -#ifndef STRL_IN_LIBC -#define strlcpy rgbds_strlcpy -#define strlcat rgbds_strlcat -size_t strlcpy(char *, const char *, size_t); -size_t strlcat(char *, const char *, size_t); -#endif - #include "asm/symbol.h" #include "asm/fstack.h" #include "asm/types.h" #include "asm/main.h" #include "asm/lexer.h" +#include "extern/err.h" +#include "extern/strl.h" /* * RGBAsm - FSTACK.C (FileStack routines) @@ -245,10 +240,8 @@ fstk_RunInclude(char *tzFileName) f = fstk_FindFile(tzFileName); if (f == NULL) { - fprintf(stderr, "Unable to open included file '%s': ", + err(1, "Unable to open included file '%s'", tzFileName); - perror(NULL); - exit(1); } pushcontext(); @@ -357,10 +350,7 @@ fstk_Init(char *s) pFileStack = NULL; pCurrentFile = fopen(tzFileName, "rb"); if (pCurrentFile == NULL) { - fprintf(stderr, "Unable to open file '%s': ", - tzFileName); - perror(NULL); - exit(1); + err(1, "Unable to open file '%s'", tzFileName); } nMacroCount = 0; diff --git a/src/asm/lexer.c b/src/asm/lexer.c index a4f43572..b6fac43c 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -4,6 +4,7 @@ #include "asm/main.h" #include "asm/rpn.h" #include "asm/fstack.h" +#include "extern/err.h" #include "asmy.h" @@ -213,9 +214,8 @@ void lex_CheckCharacterRange(UWORD start, UWORD end) { if (start > end || start < 1 || end > 127) { - fprintf(stderr, "Invalid character range (start: %u, end: %u)\n", + errx(1, "Invalid character range (start: %u, end: %u)", start, end); - exit(1); } } @@ -344,8 +344,6 @@ lex_AddStrings(struct sLexInitString * lex) while (*ppHash) ppHash = &((*ppHash)->pNext); - //printf("%s has hashvalue %d\n", lex->tzName, hash); - if (((*ppHash) = (struct sLexString *) malloc(sizeof(struct sLexString))) != NULL) { diff --git a/src/asm/main.c b/src/asm/main.c index f5d14439..822f96b0 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -19,6 +19,7 @@ #include "asm/fstack.h" #include "asm/output.h" #include "asm/main.h" +#include "extern/err.h" int yyparse(void); void setuplex(void); @@ -133,9 +134,8 @@ opt_Parse(char *s) newopt.gbgfx[2] = s[3]; newopt.gbgfx[3] = s[4]; } else { - fprintf(stderr, "Must specify exactly 4 characters " - "for option 'g'\n"); - exit(1); + errx(1, "Must specify exactly 4 characters for " + "option 'g'"); } break; case 'b': @@ -143,9 +143,8 @@ opt_Parse(char *s) newopt.binary[0] = s[1]; newopt.binary[1] = s[2]; } else { - fprintf(stderr, "Must specify exactly 2 characters " - "for option 'b'\n"); - exit(1); + errx(1, "Must specify exactly 2 characters for option " + "'b'"); } break; case 'z': @@ -154,12 +153,10 @@ opt_Parse(char *s) result = sscanf(&s[1], "%lx", &newopt.fillchar); if (!((result == EOF) || (result == 1))) { - fprintf(stderr, - "Invalid argument for option 'z'\n"); - exit(1); + errx(1, "Invalid argument for option 'z'"); } } else { - fprintf(stderr, "Invalid argument for option 'z'\n"); + errx(1, "Invalid argument for option 'z'"); exit(1); } break; @@ -295,9 +292,8 @@ main(int argc, char *argv[]) newopt.binary[0] = optarg[1]; newopt.binary[1] = optarg[2]; } else { - fprintf(stderr, "Must specify exactly " - "2 characters for option 'b'\n"); - exit(1); + errx(1, "Must specify exactly 2 characters for " + "option 'b'"); } break; case 'g': @@ -307,9 +303,8 @@ main(int argc, char *argv[]) newopt.gbgfx[2] = optarg[3]; newopt.gbgfx[3] = optarg[4]; } else { - fprintf(stderr, "Must specify exactly " - "4 characters for option 'g'\n"); - exit(1); + errx(1, "Must specify exactly 4 characters for " + "option 'g'"); } break; case 'h': @@ -324,14 +319,11 @@ main(int argc, char *argv[]) case 'p': newopt.fillchar = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'p'\n"); - exit(1); + errx(1, "Invalid argument for option 'p'"); } if (newopt.fillchar < 0 || newopt.fillchar > 0xFF) { - fprintf(stderr, "Argument for option 'p' " - "must be between 0 and 0xFF\n"); - exit(1); + errx(1, "Argument for option 'p' must be " + "between 0 and 0xFF"); } break; case 'v': @@ -420,16 +412,12 @@ main(int argc, char *argv[]) exit(5); } } else { - fprintf(stderr, - "Unterminated IF construct (%ld levels)!\n", + errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth); - exit(1); } } else { - fprintf(stderr, - "Assembly aborted in pass 1 (%ld errors)!\n", + errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors); - exit(1); } return 0; } diff --git a/src/asm/output.c b/src/asm/output.c index c60919d4..b1c254a6 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -17,6 +17,7 @@ #include "asm/main.h" #include "asm/rpn.h" #include "asm/fstack.h" +#include "extern/err.h" #define SECTIONCHUNK 0x4000 @@ -909,10 +910,7 @@ out_BinaryFile(char *s) f = fstk_FindFile(s); if (f == NULL) { - fprintf(stderr, "Unable to open incbin file '%s': ", - s); - perror(NULL); - exit(1); + err(1, "Unable to open incbin file '%s'", s); } SLONG fsize; @@ -949,10 +947,7 @@ out_BinaryFileSlice(char *s, SLONG start_pos, SLONG length) f = fstk_FindFile(s); if (f == NULL) { - fprintf(stderr, "Unable to open included file '%s': ", - s); - perror(NULL); - exit(1); + err(1, "Unable to open included file '%s'", s); } SLONG fsize; diff --git a/src/extern/err.c b/src/extern/err.c new file mode 100644 index 00000000..3d363e04 --- /dev/null +++ b/src/extern/err.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2005-2013 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +extern char *__progname; + +void rgbds_vwarn(const char *fmt, va_list ap) +{ + fprintf (stderr, "%s: ", __progname); + if (fmt) { + vfprintf(stderr, fmt, ap); + fputs (": ", stderr); + } + perror(0); +} + +void rgbds_vwarnx(const char *fmt, va_list ap) +{ + fprintf (stderr, "%s: ", __progname); + if (fmt) vfprintf(stderr, fmt, ap); + putc('\n', stderr); +} + +void rgbds_verr(int status, const char *fmt, va_list ap) +{ + vwarn(fmt, ap); + exit(status); +} + +void rgbds_verrx(int status, const char *fmt, va_list ap) +{ + vwarnx(fmt, ap); + exit(status); +} + +void rgbds_warn(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarn(fmt, ap); + va_end(ap); +} + +void rgbds_warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} + +void rgbds_err(int status, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verr(status, fmt, ap); + va_end(ap); +} + +void rgbds_errx(int status, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(status, fmt, ap); + va_end(ap); +} diff --git a/src/fix/main.c b/src/fix/main.c index 3c7c676a..69ab45b6 100644 --- a/src/fix/main.c +++ b/src/fix/main.c @@ -22,6 +22,8 @@ #include #include +#include "extern/err.h" + static void usage(void) { @@ -47,9 +49,7 @@ main(int argc, char *argv[]) usage(); if ((rom = fopen(argv[argc - 1], "rb+")) == NULL) { - fprintf(stderr, "Error opening file %s: \n", argv[argc - 1]); - perror(NULL); - exit(1); + err(1, "Error opening file %s", argv[argc - 1]); } /* @@ -93,9 +93,8 @@ main(int argc, char *argv[]) setid = true; if (strlen(optarg) != 4) { - fprintf(stderr, "Game ID %s must be exactly 4 " - "characters\n", optarg); - exit(1); + errx(1, "Game ID %s must be exactly 4 " + "characters", optarg); } id = optarg; @@ -107,10 +106,8 @@ main(int argc, char *argv[]) setnewlicensee = true; if (strlen(optarg) != 2) { - fprintf(stderr, - "New licensee code %s is not the correct " - "length of 2 characters\n", optarg); - exit(1); + errx(1, "New licensee code %s is not the " + "correct length of 2 characters", optarg); } newlicensee = optarg; @@ -120,15 +117,11 @@ main(int argc, char *argv[]) licensee = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'l'\n"); - exit(1); + errx(1, "Invalid argument for option 'l'"); } if (licensee < 0 || licensee > 0xFF) { - fprintf(stderr, - "Argument for option 'l' must be " - "between 0 and 255\n"); - exit(1); + errx(1, "Argument for option 'l' must be " + "between 0 and 255"); } break; case 'm': @@ -136,15 +129,11 @@ main(int argc, char *argv[]) cartridge = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'm'\n"); - exit(1); + errx(1, "Invalid argument for option 'm'"); } if (cartridge < 0 || cartridge > 0xFF) { - fprintf(stderr, - "Argument for option 'm' must be " - "between 0 and 255\n"); - exit(1); + errx(1, "Argument for option 'm' must be " + "between 0 and 255"); } break; case 'n': @@ -152,15 +141,11 @@ main(int argc, char *argv[]) version = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'n'\n"); - exit(1); + errx(1, "Invalid argument for option 'n'"); } if (version < 0 || version > 0xFF) { - fprintf(stderr, - "Argument for option 'n' must be " - "between 0 and 255\n"); - exit(1); + errx(1, "Argument for option 'n' must be " + "between 0 and 255"); } break; case 'p': @@ -168,15 +153,11 @@ main(int argc, char *argv[]) padvalue = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'p'\n"); - exit(1); + errx(1, "Invalid argument for option 'p'"); } if (padvalue < 0 || padvalue > 0xFF) { - fprintf(stderr, - "Argument for option 'p' must be " - "between 0 and 255\n"); - exit(1); + errx(1, "Argument for option 'p' must be " + "between 0 and 255"); } break; case 'r': @@ -184,14 +165,11 @@ main(int argc, char *argv[]) ramsize = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, - "Invalid argument for option 'r'\n"); + errx(1, "Invalid argument for option 'r'"); } if (ramsize < 0 || ramsize > 0xFF) { - fprintf(stderr, - "Argument for option 'r' must be " - "between 0 and 255\n"); - exit(1); + errx(1, "Argument for option 'r' must be " + "between 0 and 255"); } break; case 's': @@ -201,15 +179,13 @@ main(int argc, char *argv[]) settitle = true; if (strlen(optarg) > 16) { - fprintf(stderr, "Title %s is greater than the " - "maximum of 16 characters\n", optarg); - exit(1); + errx(1, "Title %s is greater than the " + "maximum of 16 characters", optarg); } if (strlen(optarg) == 16) - fprintf(stderr, - "Title %s is 16 chars, it is best " - "to keep it to 15 or fewer\n", optarg); + warnx("Title %s is 16 chars, it is best to " + "keep it to 15 or fewer", optarg); title = optarg; break; @@ -313,8 +289,7 @@ main(int argc, char *argv[]) byte |= 1 << 6; if (byte & 0x3F) - fprintf(stderr, - "Color flag conflicts with game title\n"); + warnx("Color flag conflicts with game title"); fseek(rom, 0x143, SEEK_SET); fputc(byte, rom); @@ -351,9 +326,8 @@ main(int argc, char *argv[]) */ if (!setlicensee) - fprintf(stderr, - "You should probably set both '-s' and " - "'-l 0x33'\n"); + warnx("You should probably set both '-s' and " + "'-l 0x33'"); fseek(rom, 0x146, SEEK_SET); fputc(3, rom); @@ -390,7 +364,7 @@ main(int argc, char *argv[]) } if (newsize > 0x800000) /* ROM is bigger than 8MiB */ - fprintf(stderr, "ROM size is bigger than 8MiB\n"); + warnx("ROM size is bigger than 8MiB"); buf = malloc(newsize - romsize); memset(buf, padvalue, newsize - romsize); diff --git a/src/lib/library.c b/src/lib/library.c index 6f322d9a..3cebb71d 100644 --- a/src/lib/library.c +++ b/src/lib/library.c @@ -88,16 +88,14 @@ lib_ReadLib0(FILE * f, SLONG size) if (l == NULL) { l = malloc(sizeof *l); if (!l) { - fprintf(stderr, "Out of memory\n"); - exit(1); + err(1, NULL); } first = l; } else { l->pNext = malloc(sizeof *l->pNext); if (!l->pNext) { - fprintf(stderr, "Out of memory\n"); - exit(1); + err(1, NULL); } l = l->pNext; @@ -115,8 +113,7 @@ lib_ReadLib0(FILE * f, SLONG size) f); size -= l->nByteLength; } else { - fprintf(stderr, "Out of memory\n"); - exit(1); + err(1, NULL); } l->pNext = NULL; @@ -153,8 +150,7 @@ lib_Read(char *filename) return (r); } else { fclose(f); - fprintf(stderr, "Not a valid xLib library\n"); - exit(1); + errx(1, "Not a valid xLib library"); } } else { printf @@ -191,8 +187,7 @@ sLibrary * lib_Find(sLibrary * lib, char *filename) { if (strlen(filename) >= MAXNAMELENGTH) { - fprintf(stderr, "Module name too long: %s\n", filename); - exit(1); + errx(1, "Module name too long: %s", filename); } while (lib) { @@ -214,16 +209,13 @@ lib_AddReplace(sLibrary * lib, char *filename) sLibrary *module; if (strlen(filename) >= MAXNAMELENGTH) { - fprintf(stderr, "Module name too long: %s\n", - filename); - exit(1); + errx(1, "Module name too long: %s\n", filename); } if ((module = lib_Find(lib, filename)) == NULL) { module = malloc(sizeof *module); if (!module) { - fprintf(stderr, "Out of memory\n"); - exit(1); + err(1, NULL); } module->pNext = lib; @@ -237,8 +229,7 @@ lib_AddReplace(sLibrary * lib, char *filename) strcpy(module->tName, filename); module->pData = malloc(module->nByteLength); if (!module->pData) { - fprintf(stderr, "Out of memory\n"); - exit(1); + err(1, NULL); } fread(module->pData, sizeof(UBYTE), module->nByteLength, f); @@ -260,8 +251,7 @@ lib_DeleteModule(sLibrary * lib, char *filename) first = pp; if (strlen(filename) >= MAXNAMELENGTH) { - fprintf(stderr, "Module name too long: %s\n", filename); - exit(1); + errx(1, "Module name too long: %s\n", filename); } while ((*pp) && (!found)) { @@ -282,8 +272,7 @@ lib_DeleteModule(sLibrary * lib, char *filename) } if (!found) { - fprintf(stderr, "Module not found\n"); - exit(1); + errx(1, "Module not found\n"); } else printf("Module '%s' deleted from library\n", filename); diff --git a/src/lib/main.c b/src/lib/main.c index 42d553cc..3aeb4c61 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -6,6 +6,7 @@ #include "asmotor.h" +#include "extern/err.h" #include "lib/types.h" #include "lib/library.h" @@ -83,10 +84,8 @@ main(int argc, char *argv[]) ("Extracted module '%s'\n", argv[argn]); } else { - fprintf(stderr, - "Unable to write module '%s': ", argv[argn]); - perror(NULL); - exit(1); + err(1, + "Unable to write module '%s'", argv[argn]); } } else { fprintf(stderr, "Module not found\n"); diff --git a/src/link/assign.c b/src/link/assign.c index 09b0dc6f..a5d37acb 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -1,6 +1,7 @@ #include #include +#include "extern/err.h" #include "link/mylink.h" #include "link/main.h" #include "link/symbol.h" @@ -77,9 +78,7 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size) return (org); } else { - fprintf(stderr, - "Out of memory!\n"); - exit(1); + err(1, NULL); } } } @@ -310,9 +309,7 @@ AssignVRAMSections(void) pSection->oAssigned = 1; DOMAXVBANK(pSection->nBank); } else { - fprintf(stderr, - "Unable to place VRAM section anywhere\n"); - exit(1); + errx(1, "Unable to place VRAM section anywhere"); } } } @@ -331,9 +328,7 @@ AssignSRAMSections(void) pSection->oAssigned = 1; DOMAXSBANK(pSection->nBank); } else { - fprintf(stderr, - "Unable to place SRAM section anywhere\n"); - exit(1); + errx(1, "Unable to place SRAM section anywhere"); } } } @@ -352,9 +347,7 @@ AssignWRAMSections(void) pSection->oAssigned = 1; DOMAXWBANK(pSection->nBank); } else { - fprintf(stderr, - "Unable to place WRAMX section anywhere\n"); - exit(1); + errx(1, "Unable to place WRAMX section anywhere"); } } } @@ -373,9 +366,7 @@ AssignCodeSections(void) pSection->oAssigned = 1; DOMAXBANK(pSection->nBank); } else { - fprintf(stderr, - "Unable to place ROMX section anywhere\n"); - exit(1); + errx(1, "Unable to place ROMX section anywhere"); } } } @@ -397,8 +388,7 @@ AssignSections(void) BankFree[i] = malloc(sizeof *BankFree[i]); if (!BankFree[i]) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } if (i == 0) { @@ -472,10 +462,9 @@ AssignSections(void) if (area_AllocAbs (&BankFree[BANK_WRAM0], pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, - "Unable to load fixed WRAM0 section " - "at $%lX\n", pSection->nOrg); - exit(1); + errx(1, + "Unable to load fixed WRAM0 " + "section at $%lX", pSection->nOrg); } pSection->oAssigned = 1; pSection->nBank = BANK_WRAM0; @@ -484,10 +473,8 @@ AssignSections(void) if (area_AllocAbs (&BankFree[BANK_HRAM], pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, "Unable to load fixed " - "HRAM section at $%lX\n", - pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed HRAM " + "section at $%lX", pSection->nOrg); } pSection->oAssigned = 1; pSection->nBank = BANK_HRAM; @@ -530,17 +517,15 @@ AssignSections(void) pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, -"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } DOMAXVBANK(pSection-> nBank); pSection->oAssigned = 1; } else { - fprintf(stderr, -"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } } } @@ -583,17 +568,15 @@ AssignSections(void) pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, -"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } DOMAXWBANK(pSection-> nBank); pSection->oAssigned = 1; } else { - fprintf(stderr, -"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } } } @@ -636,17 +619,15 @@ AssignSections(void) pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, -"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } DOMAXVBANK(pSection-> nBank); pSection->oAssigned = 1; } else { - fprintf(stderr, -"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, +"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } } } @@ -655,10 +636,8 @@ AssignSections(void) if (area_AllocAbs (&BankFree[BANK_ROM0], pSection->nOrg, pSection->nByteSize) != pSection->nOrg) { - fprintf(stderr, "Unable to load fixed " - "ROM0 section at $%lX\n", - pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed ROM0 " + "section at $%lX", pSection->nOrg); } pSection->oAssigned = 1; pSection->nBank = BANK_ROM0; @@ -703,15 +682,15 @@ AssignSections(void) pSection-> nByteSize) != pSection->nOrg) { - fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, + "Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } DOMAXBANK(pSection-> nBank); pSection->oAssigned = 1; } else { - fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank); - exit(1); + errx(1, + "Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); } } @@ -737,14 +716,13 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, + "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank); } pSection->oAssigned = 1; DOMAXBANK(pSection->nBank); } else { - fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank); } } else if (pSection->oAssigned == 0 && pSection->Type == SECT_SRAM @@ -755,14 +733,12 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed SRAM section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, "Unable to load fixed SRAM section into bank $%02lX", pSection->nBank); } pSection->oAssigned = 1; DOMAXSBANK(pSection->nBank); } else { - fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank); } } else if (pSection->oAssigned == 0 && pSection->Type == SECT_VRAM @@ -773,14 +749,12 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank); } pSection->oAssigned = 1; DOMAXVBANK(pSection->nBank); } else { - fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank); - exit(1); + errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank); } } else if (pSection->oAssigned == 0 && pSection->Type == SECT_WRAMX @@ -791,14 +765,12 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX); - exit(1); + errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX); } pSection->oAssigned = 1; DOMAXWBANK(pSection->nBank); } else { - fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX); - exit(1); + errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX); } } pSection = pSection->pNext; @@ -820,8 +792,7 @@ AssignSections(void) area_AllocAbsROMXAnyBank(pSection->nOrg, pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed ROMX section at $%lX into any bank\n", pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed ROMX section at $%lX into any bank", pSection->nOrg); } pSection->oAssigned = 1; DOMAXBANK(pSection->nBank); @@ -834,8 +805,7 @@ AssignSections(void) area_AllocAbsVRAMAnyBank(pSection->nOrg, pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed VRAM section at $%lX into any bank\n", pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed VRAM section at $%lX into any bank", pSection->nOrg); } pSection->oAssigned = 1; DOMAXVBANK(pSection->nBank); @@ -848,8 +818,7 @@ AssignSections(void) area_AllocAbsSRAMAnyBank(pSection->nOrg, pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed SRAM section at $%lX into any bank\n", pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed SRAM section at $%lX into any bank", pSection->nOrg); } pSection->oAssigned = 1; DOMAXSBANK(pSection->nBank); @@ -862,8 +831,7 @@ AssignSections(void) area_AllocAbsWRAMAnyBank(pSection->nOrg, pSection->nByteSize)) == -1) { - fprintf(stderr, "Unable to load fixed WRAMX section at $%lX into any bank\n", pSection->nOrg); - exit(1); + errx(1, "Unable to load fixed WRAMX section at $%lX into any bank", pSection->nOrg); } pSection->oAssigned = 1; DOMAXWBANK(pSection->nBank); @@ -885,8 +853,7 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[BANK_WRAM0], pSection->nByteSize)) == -1) { - fprintf(stderr, "WRAM0 section too large\n"); - exit(1); + errx(1, "WRAM0 section too large"); } pSection->nBank = BANK_WRAM0; pSection->oAssigned = 1; @@ -895,8 +862,7 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[BANK_HRAM], pSection->nByteSize)) == -1) { - fprintf(stderr, "HRAM section too large\n"); - exit(1); + errx(1, "HRAM section too large"); } pSection->nBank = BANK_HRAM; pSection->oAssigned = 1; @@ -911,8 +877,7 @@ AssignSections(void) if ((pSection->nOrg = area_Alloc(&BankFree[BANK_ROM0], pSection->nByteSize)) == -1) { - fprintf(stderr, "ROM0 section too large\n"); - exit(1); + errx(1, "ROM0 section too large"); } pSection->nBank = BANK_ROM0; pSection->oAssigned = 1; @@ -920,8 +885,7 @@ AssignSections(void) case SECT_ROMX: break; default: - fprintf(stderr, "(INTERNAL) Unknown section type!\n"); - exit(1); + errx(1, "(INTERNAL) Unknown section type!"); break; } } diff --git a/src/link/library.c b/src/link/library.c index 9e847c55..e49d7671 100644 --- a/src/link/library.c +++ b/src/link/library.c @@ -2,6 +2,7 @@ #include #include +#include "extern/err.h" #include "link/types.h" #include "link/mylink.h" #include "link/main.h" @@ -91,9 +92,8 @@ AddNeededModules(void) } if (options & OPT_SMART_C_LINK) { if (!addmodulecontaining(smartlinkstartsymbol)) { - fprintf(stderr, "Can't find start symbol '%s'\n", + errx(1, "Can't find start symbol '%s'", smartlinkstartsymbol); - exit(1); } else printf("Smart linking with symbol '%s'\n", smartlinkstartsymbol); diff --git a/src/link/main.c b/src/link/main.c index 84ecb8f6..29c7d1cc 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -6,6 +6,7 @@ #include "asmotor.h" +#include "extern/err.h" #include "link/object.h" #include "link/output.h" #include "link/assign.h" @@ -73,8 +74,7 @@ main(int argc, char *argv[]) case 'p': fillchar = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { - fprintf(stderr, "Invalid argument for option 'p'\n"); - exit(1); + errx(1, "Invalid argument for option 'p'"); } if (fillchar < 0 || fillchar > 0xFF) { fprintf(stderr, "Argument for option 'p' must be between 0 and 0xFF"); diff --git a/src/link/mapfile.c b/src/link/mapfile.c index f953afe5..fce261f8 100644 --- a/src/link/mapfile.c +++ b/src/link/mapfile.c @@ -5,6 +5,7 @@ #include "asmotor.h" +#include "extern/err.h" #include "link/main.h" #include "link/mylink.h" #include "link/assign.h" @@ -20,9 +21,7 @@ SetMapfileName(char *name) mf = fopen(name, "w"); if (mf == NULL) { - fprintf(stderr, "Cannot open mapfile '%s': ", name); - perror(NULL); - exit(1); + err(1, "Cannot open mapfile '%s'", name); } } @@ -32,8 +31,7 @@ SetSymfileName(char *name) sf = fopen(name, "w"); if (sf == NULL) { - fprintf(stderr, "Cannot open symfile '%s'\n", name); - exit(1); + err(1, "Cannot open symfile '%s'", name); } fprintf(sf, ";File generated by xLink v" LINK_VERSION "\n\n"); diff --git a/src/link/object.c b/src/link/object.c index 9a45b74b..3d15bcb1 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -8,6 +8,7 @@ #include #include +#include "extern/err.h" #include "link/mylink.h" #include "link/main.h" @@ -80,8 +81,7 @@ AllocSection(void) *ppSections = malloc(sizeof **ppSections); if (!*ppSections) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } (*ppSections)->tSymbols = tSymbols; (*ppSections)->pNext = NULL; @@ -102,15 +102,13 @@ obj_ReadSymbol(FILE * f) pSym = malloc(sizeof *pSym); if (!pSym) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } readasciiz(s, f); pSym->pzName = malloc(strlen(s) + 1); if (!pSym->pzName) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } strcpy(pSym->pzName, s); @@ -150,7 +148,7 @@ obj_ReadRGB0Section(FILE * f) if (pSection->nByteSize) { pSection->pData = malloc(pSection->nByteSize); if (!pSection->pData) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } SLONG nNumberOfPatches; @@ -169,7 +167,7 @@ obj_ReadRGB0Section(FILE * f) while (nNumberOfPatches--) { pPatch = malloc(sizeof *pPatch); if (!pPatch) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } *ppPatch = pPatch; @@ -177,7 +175,7 @@ obj_ReadRGB0Section(FILE * f) pPatch->pzFilename = malloc(strlen(s) + 1); if (!pPatch->pzFilename) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } strcpy(pPatch->pzFilename, s); @@ -193,8 +191,7 @@ obj_ReadRGB0Section(FILE * f) if ((pPatch->nRPNSize = readlong(f)) > 0) { pPatch->pRPN = malloc(pPatch->nRPNSize); if (!pPatch->pRPN) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } fread(pPatch->pRPN, sizeof(UBYTE), @@ -228,8 +225,7 @@ obj_ReadRGB0(FILE * pObjfile) if (nNumberOfSymbols) { tSymbols = malloc(nNumberOfSymbols * sizeof(struct sSymbol *)); if (!tSymbols) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } for (i = 0; i < nNumberOfSymbols; i += 1) @@ -305,8 +301,7 @@ obj_ReadRGB1Section(FILE * f) if (pSection->nByteSize) { pSection->pData = malloc(pSection->nByteSize); if (!pSection->pData) { - fprintf(stderr, "Out of memory!\n"); - exit(1); + err(1, NULL); } SLONG nNumberOfPatches; @@ -325,14 +320,14 @@ obj_ReadRGB1Section(FILE * f) while (nNumberOfPatches--) { pPatch = malloc(sizeof *pPatch); if (!pPatch) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } *ppPatch = pPatch; readasciiz(s, f); pPatch->pzFilename = malloc(strlen(s) + 1); if (!pPatch->pzFilename) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } strcpy(pPatch->pzFilename, s); @@ -342,7 +337,7 @@ obj_ReadRGB1Section(FILE * f) if ((pPatch->nRPNSize = readlong(f)) > 0) { pPatch->pRPN = malloc(pPatch->nRPNSize); if (!pPatch->pRPN) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } fread(pPatch->pRPN, sizeof(UBYTE), @@ -376,7 +371,7 @@ obj_ReadRGB1(FILE * pObjfile) if (nNumberOfSymbols) { tSymbols = malloc(nNumberOfSymbols * sizeof *tSymbols); if (!tSymbols) { - fprintf(stderr, "Out of memory!\n"); + err(1, NULL); } for (i = 0; i < nNumberOfSymbols; i += 1) @@ -440,14 +435,10 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile) obj_ReadRGB1(pObjfile); break; default: - fprintf(stderr, "'%s' is an unsupported version", - tzObjectfile); - exit(1); - break; + errx(1, "'%s' is an unsupported version", tzObjectfile); } } else { - fprintf(stderr, "'%s' is not a valid object\n", tzObjectfile); - exit(1); + errx(1, "'%s' is not a valid object", tzObjectfile); } } @@ -463,10 +454,7 @@ obj_Readfile(char *tzObjectfile) pObjfile = fopen(tzObjectfile, "rb"); if (pObjfile == NULL) { - fprintf(stderr, "Unable to open object '%s': ", - tzObjectfile); - perror(NULL); - exit(1); + err(1, "Unable to open object '%s'", tzObjectfile); } obj_ReadOpenFile(pObjfile, tzObjectfile); fclose(pObjfile); @@ -516,13 +504,7 @@ lib_Readfile(char *tzLibfile) pObjfile = fopen(tzLibfile, "rb"); if (pObjfile == NULL) { - fprintf(stderr, "Unable to open object '%s': ", tzLibfile); - perror(NULL); - exit(1); - } - if (!pObjfile) { - fprintf(stderr, "Unable to open '%s'\n", tzLibfile); - exit(1); + err(1, "Unable to open object '%s'", tzLibfile); } char tzHeader[5]; @@ -531,9 +513,7 @@ lib_Readfile(char *tzLibfile) if (strcmp(tzHeader, "XLB0") == 0) lib_ReadXLB0(pObjfile); else { - fprintf(stderr, "'%s' is an invalid library\n", - tzLibfile); - exit(1); + errx(1, "'%s' is an invalid library", tzLibfile); } fclose(pObjfile); } diff --git a/src/link/patch.c b/src/link/patch.c index 822a7c24..d9376586 100644 --- a/src/link/patch.c +++ b/src/link/patch.c @@ -2,6 +2,7 @@ #include #include +#include "extern/err.h" #include "link/mylink.h" #include "link/symbol.h" #include "link/main.h" @@ -46,8 +47,7 @@ getsymvalue(SLONG symid) default: break; } - fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n"); - exit(1); + errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE"); } SLONG @@ -64,8 +64,7 @@ getsymbank(SLONG symid) default: break; } - fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n"); - exit(1); + errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE"); } SLONG @@ -159,20 +158,18 @@ calcrpn(struct sPatch * pPatch) t = rpnpop(); rpnpush(t & 0xFF); if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) { - fprintf(stderr, - "%s(%ld) : Value must be in the HRAM area\n", + errx(1, + "%s(%ld) : Value must be in the HRAM area", pPatch->pzFilename, pPatch->nLineNo); - exit(1); } break; case RPN_PCEZP: t = rpnpop(); rpnpush(t & 0xFF); if (t < 0x2000 || t > 0x20FF) { - fprintf(stderr, - "%s(%ld) : Value must be in the ZP area\n", + errx(1, + "%s(%ld) : Value must be in the ZP area", pPatch->pzFilename, pPatch->nLineNo); - exit(1); } break; case RPN_CONST: @@ -217,11 +214,10 @@ calcrpn(struct sPatch * pPatch) high |= (*rpn++) << 24; t = rpnpop(); if (t < low || t > high) { - fprintf(stderr, - "%s(%ld) : Value must be in the range [%ld;%ld]\n", + errx(1, + "%s(%ld) : Value must be in the range [%ld;%ld]", pPatch->pzFilename, pPatch->nLineNo, low, high); - exit(1); } rpnpush(t); size -= 8; @@ -255,11 +251,10 @@ Patch(void) pSect->pData[pPatch->nOffset] = (UBYTE) t; } else { - fprintf(stderr, - "%s(%ld) : Value must be 8-bit\n", + errx(1, + "%s(%ld) : Value must be 8-bit", pPatch->pzFilename, pPatch->nLineNo); - exit(1); } break; case PATCH_WORD_L: @@ -280,11 +275,10 @@ Patch(void) 1] = t & 0xFF; } } else { - fprintf(stderr, - "%s(%ld) : Value must be 16-bit\n", + errx(1, + "%s(%ld) : Value must be 16-bit", pPatch->pzFilename, pPatch->nLineNo); - exit(1); } break; case PATCH_LONG_L: diff --git a/src/link/symbol.c b/src/link/symbol.c index ee696cc5..6f5cc9cc 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.c @@ -2,6 +2,7 @@ #include #include +#include "extern/err.h" #include "link/main.h" #include "link/patch.h" #include "link/types.h" @@ -53,8 +54,7 @@ sym_GetValue(char *tzName) } } - fprintf(stderr, "Unknown symbol '%s'\n", tzName); - exit(1); + errx(1, "Unknown symbol '%s'", tzName); } } @@ -72,8 +72,7 @@ sym_GetBank(char *tzName) } } - fprintf(stderr, "Unknown symbol '%s'\n", tzName); - exit(1); + errx(1, "Unknown symbol '%s'", tzName); } void @@ -93,10 +92,7 @@ sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank) if (nBank == -1) return; - fprintf(stderr, - "Symbol '%s' defined more than once\n", - tzName); - exit(1); + errx(1, "Symbol '%s' defined more than once", tzName); } } From d7319ecd0020ff6b494578c2f81b2f37cbd7af89 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 03:03:42 -0600 Subject: [PATCH 20/36] Remove rgblib. I have never used it and it's probably been broken for years. --- LICENSE | 4 +- Makefile | 17 +-- README | 1 - doc/index.htm | 1 - doc/lib.htm | 47 ------- include/lib/library.h | 13 -- include/lib/libwrap.h | 19 --- include/lib/types.h | 14 -- include/link/object.h | 1 - src/asm/rgbasm.1 | 1 - src/fix/rgbfix.1 | 1 - src/lib/library.c | 295 ------------------------------------------ src/lib/main.c | 116 ----------------- src/lib/rgblib.1 | 36 ------ src/link/main.c | 5 +- src/link/object.c | 23 ---- src/link/rgblink.1 | 7 - src/rgbds.7 | 1 - 18 files changed, 4 insertions(+), 598 deletions(-) delete mode 100644 doc/lib.htm delete mode 100644 include/lib/library.h delete mode 100644 include/lib/libwrap.h delete mode 100644 include/lib/types.h delete mode 100644 src/lib/library.c delete mode 100644 src/lib/main.c delete mode 100644 src/lib/rgblib.1 diff --git a/LICENSE b/LICENSE index 4e031993..27ec9897 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ -rgbasm, rgblink, and rgblib are derived from Justin Lloyd's RGBDS, which -is released under the following license: +rgbasm, and rgblink are derived from Justin Lloyd's RGBDS, which is +released under the following license: DO WHATEVER PUBLIC LICENSE* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION diff --git a/Makefile b/Makefile index a89f586e..8d02b52c 100644 --- a/Makefile +++ b/Makefile @@ -27,11 +27,6 @@ rgbasm_obj := \ src/extern/strlcpy.o \ src/extern/strlcat.o -rgblib_obj := \ - src/lib/library.o \ - src/lib/main.o \ - src/extern/err.o - rgblink_obj := \ src/link/assign.o \ src/link/library.o \ @@ -47,12 +42,11 @@ rgbfix_obj := \ src/fix/main.o \ src/extern/err.o -all: rgbasm rgblib rgblink rgbfix +all: rgbasm rgblink rgbfix clean: $Qrm -rf rgbds.html $Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html - $Qrm -rf rgblib rgblib.exe ${rgblib_obj} rgblib.html $Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html $Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html $Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y @@ -61,7 +55,6 @@ install: all $Qinstall -s -m 555 rgbasm ${BINPREFIX}/rgbasm $Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix $Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink - $Qinstall -s -m 555 rgblib ${BINPREFIX}/rgblib $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \ (echo Installing manpages to ${MANPREFIX} failed. >&2 && \ echo Check where your manpages are installed and set the \ @@ -74,15 +67,10 @@ install: all ${MANPREFIX}/man1/rgbfix.1 $Qinstall -m 444 src/link/rgblink.1 \ ${MANPREFIX}/man1/rgblink.1 - $Qinstall -m 444 src/lib/rgblib.1 \ - ${MANPREFIX}/man1/rgblib.1 rgbasm: ${rgbasm_obj} $Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm -rgblib: ${rgblib_obj} - $Q${CC} ${REALCFLAGS} -o $@ ${rgblib_obj} - rgblink: ${rgblink_obj} $Q${CC} ${REALCFLAGS} -o $@ ${rgblink_obj} @@ -107,7 +95,6 @@ mingw: $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \ make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" $Qmv rgbasm rgbasm.exe - $Qmv rgblib rgblib.exe $Qmv rgblink rgblink.exe $Qmv rgbfix rgbfix.exe @@ -122,8 +109,6 @@ wwwman: rgbasm.html $Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > \ rgbfix.html - $Qmandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > \ - rgblib.html $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \ rgblink.html diff --git a/README b/README index 8b08fedd..c5d562ba 100644 --- a/README +++ b/README @@ -7,7 +7,6 @@ for the Game Boy and Game Boy Color. It consists of: - rgbasm (assembler) - rgblink (linker) - - rgblib (library manager) - rgbfix (checksum/header fixer) rgbds-linux is a fork of the original RGBDS which aims to make the programs diff --git a/doc/index.htm b/doc/index.htm index 2896cf88..148e4e34 100644 --- a/doc/index.htm +++ b/doc/index.htm @@ -12,7 +12,6 @@
  • ASMotor General Information
  • xASM Documentation
  • xLink Documentation -
  • xLib Documentation
  • RGBFix Documentation
  • The RGB0-2 ObjectFileFormat diff --git a/doc/lib.htm b/doc/lib.htm deleted file mode 100644 index 559e1e60..00000000 --- a/doc/lib.htm +++ /dev/null @@ -1,47 +0,0 @@ - - - - - xLib - - - -

    xLib Documentation

    -

    Table of Contents

    - -
    -

    History

    - - - - - - - - - - - - - - -
    The history of xLib
    VersionDatedRelease notes
    1.021 Sep. 1997First release
    -

    Usage

    -
        xlib library command [module1 module2 ... modulen]
    -

    The Commands

    -

    The command specified after library on the commandline tells xLib what to do. -

    The following commands are available: -

      -
    • a — Adds (or replaces if already present) the modules to the library -
    • d — Deletes the modules specified from the library -
    • l — Lists the library contents -
    • x — Extracts the modules from the library -
    -
    -

    Last updated 21 September 1997 by Carsten Sorensen

    - - diff --git a/include/lib/library.h b/include/lib/library.h deleted file mode 100644 index 4037c930..00000000 --- a/include/lib/library.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef ASMOTOR_LIB_LIBRARY_H -#define ASMOTOR_LIB_LIBRARY_H - -#include "lib/libwrap.h" - -extern sLibrary *lib_Read(char *filename); -extern BBOOL lib_Write(sLibrary * lib, char *filename); -extern sLibrary *lib_AddReplace(sLibrary * lib, char *filename); -extern void lib_Free(sLibrary * lib); -extern sLibrary *lib_DeleteModule(sLibrary * lib, char *filename); -extern sLibrary *lib_Find(sLibrary * lib, char *filename); - -#endif diff --git a/include/lib/libwrap.h b/include/lib/libwrap.h deleted file mode 100644 index d8c81447..00000000 --- a/include/lib/libwrap.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ASMOTOR_LIB_LIBWRAP_H -#define ASMOTOR_LIB_LIBWRAP_H - -#include "lib/types.h" - -#define MAXNAMELENGTH 256 - -struct LibraryWrapper { - char tName[MAXNAMELENGTH]; - UWORD uwTime; - UWORD uwDate; - SLONG nByteLength; - UBYTE *pData; - struct LibraryWrapper *pNext; -}; - -typedef struct LibraryWrapper sLibrary; - -#endif diff --git a/include/lib/types.h b/include/lib/types.h deleted file mode 100644 index 89c6e34a..00000000 --- a/include/lib/types.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef ASMOTOR_LIB_TYPES_H -#define ASMOTOR_LIB_TYPES_H - -#define _MAX_PATH 512 - -typedef unsigned char UBYTE; -typedef signed char SBYTE; -typedef unsigned short UWORD; -typedef signed short SWORD; -typedef unsigned long ULONG; -typedef signed long SLONG; -typedef signed char BBOOL; - -#endif diff --git a/include/link/object.h b/include/link/object.h index 72cb9f9e..3f514adf 100644 --- a/include/link/object.h +++ b/include/link/object.h @@ -2,6 +2,5 @@ #define ASMOTOR_LINK_OBJECT_H extern void obj_Readfile(char *tzObjectfile); -extern void lib_Readfile(char *tzLibfile); #endif diff --git a/src/asm/rgbasm.1 b/src/asm/rgbasm.1 index 2a7804a0..c31d5507 100644 --- a/src/asm/rgbasm.1 +++ b/src/asm/rgbasm.1 @@ -60,7 +60,6 @@ and .Sh SEE ALSO .Xr rgbds 7 , .Xr rgbfix 1 , -.Xr rgblib 1 , .Xr rgblink 1 , .Xr gbz80 7 .Sh HISTORY diff --git a/src/fix/rgbfix.1 b/src/fix/rgbfix.1 index 93397993..5db9814c 100644 --- a/src/fix/rgbfix.1 +++ b/src/fix/rgbfix.1 @@ -130,7 +130,6 @@ of the game .Sh SEE ALSO .Xr rgbds 7 , .Xr rgbasm 1 , -.Xr rgblib 1 , .Xr rgblink 1 , .Xr gbz80 7 .Sh HISTORY diff --git a/src/lib/library.c b/src/lib/library.c deleted file mode 100644 index 3cebb71d..00000000 --- a/src/lib/library.c +++ /dev/null @@ -1,295 +0,0 @@ -#include -#include -#include - -#include "lib/types.h" -#include "lib/libwrap.h" - -SLONG -file_Length(FILE * f) -{ - ULONG r, p; - - p = ftell(f); - fseek(f, 0, SEEK_END); - r = ftell(f); - fseek(f, p, SEEK_SET); - - return (r); -} - -SLONG -file_ReadASCIIz(char *b, FILE * f) -{ - SLONG r = 0; - - while ((*b++ = fgetc(f)) != 0) - r += 1; - - return (r + 1); -} - -void -file_WriteASCIIz(char *b, FILE * f) -{ - while (*b) - fputc(*b++, f); - - fputc(0, f); -} - -UWORD -file_ReadWord(FILE * f) -{ - UWORD r; - - r = fgetc(f); - r |= fgetc(f) << 8; - - return (r); -} - -void -file_WriteWord(UWORD w, FILE * f) -{ - fputc(w, f); - fputc(w >> 8, f); -} - -ULONG -file_ReadLong(FILE * f) -{ - ULONG r; - - r = fgetc(f); - r |= fgetc(f) << 8; - r |= fgetc(f) << 16; - r |= fgetc(f) << 24; - - return (r); -} - -void -file_WriteLong(UWORD w, FILE * f) -{ - fputc(w, f); - fputc(w >> 8, f); - fputc(w >> 16, f); - fputc(w >> 24, f); -} - -sLibrary * -lib_ReadLib0(FILE * f, SLONG size) -{ - if (size) { - sLibrary *l = NULL, *first = NULL; - - while (size > 0) { - if (l == NULL) { - l = malloc(sizeof *l); - if (!l) { - err(1, NULL); - } - - first = l; - } else { - l->pNext = malloc(sizeof *l->pNext); - if (!l->pNext) { - err(1, NULL); - } - - l = l->pNext; - } - - size -= file_ReadASCIIz(l->tName, f); - l->uwTime = file_ReadWord(f); - size -= 2; - l->uwDate = file_ReadWord(f); - size -= 2; - l->nByteLength = file_ReadLong(f); - size -= 4; - if ((l->pData = malloc(l->nByteLength))) { - fread(l->pData, sizeof(UBYTE), l->nByteLength, - f); - size -= l->nByteLength; - } else { - err(1, NULL); - } - - l->pNext = NULL; - } - return (first); - } - return (NULL); -} - -sLibrary * -lib_Read(char *filename) -{ - FILE *f; - - if ((f = fopen(filename, "rb"))) { - SLONG size; - char ID[5]; - - size = file_Length(f); - if (size == 0) { - fclose(f); - return (NULL); - } - fread(ID, sizeof(char), 4, f); - ID[4] = 0; - size -= 4; - - if (strcmp(ID, "XLB0") == 0) { - sLibrary *r; - - r = lib_ReadLib0(f, size); - fclose(f); - printf("Library '%s' opened\n", filename); - return (r); - } else { - fclose(f); - errx(1, "Not a valid xLib library"); - } - } else { - printf - ("Library '%s' not found, it will be created if necessary\n", - filename); - return (NULL); - } -} - -BBOOL -lib_Write(sLibrary * lib, char *filename) -{ - FILE *f; - - if ((f = fopen(filename, "wb"))) { - fwrite("XLB0", sizeof(char), 4, f); - while (lib) { - file_WriteASCIIz(lib->tName, f); - file_WriteWord(lib->uwTime, f); - file_WriteWord(lib->uwDate, f); - file_WriteLong(lib->nByteLength, f); - fwrite(lib->pData, sizeof(UBYTE), lib->nByteLength, f); - lib = lib->pNext; - } - - fclose(f); - printf("Library '%s' closed\n", filename); - return (1); - } - return (0); -} - -sLibrary * -lib_Find(sLibrary * lib, char *filename) -{ - if (strlen(filename) >= MAXNAMELENGTH) { - errx(1, "Module name too long: %s", filename); - } - - while (lib) { - if (strcmp(lib->tName, filename) == 0) - break; - - lib = lib->pNext; - } - - return (lib); -} - -sLibrary * -lib_AddReplace(sLibrary * lib, char *filename) -{ - FILE *f; - - if ((f = fopen(filename, "rb"))) { - sLibrary *module; - - if (strlen(filename) >= MAXNAMELENGTH) { - errx(1, "Module name too long: %s\n", filename); - } - - if ((module = lib_Find(lib, filename)) == NULL) { - module = malloc(sizeof *module); - if (!module) { - err(1, NULL); - } - - module->pNext = lib; - lib = module; - } else { - /* Module already exists */ - free(module->pData); - } - - module->nByteLength = file_Length(f); - strcpy(module->tName, filename); - module->pData = malloc(module->nByteLength); - if (!module->pData) { - err(1, NULL); - } - - fread(module->pData, sizeof(UBYTE), module->nByteLength, f); - - printf("Added module '%s'\n", filename); - - fclose(f); - } - return (lib); -} - -sLibrary * -lib_DeleteModule(sLibrary * lib, char *filename) -{ - sLibrary **pp, **first; - BBOOL found = 0; - - pp = &lib; - first = pp; - - if (strlen(filename) >= MAXNAMELENGTH) { - errx(1, "Module name too long: %s\n", filename); - } - - while ((*pp) && (!found)) { - if (strcmp((*pp)->tName, filename) == 0) { - sLibrary *t; - - t = *pp; - - if (t->pData) - free(t->pData); - - *pp = t->pNext; - - free(t); - found = 1; - } - pp = &((*pp)->pNext); - } - - if (!found) { - errx(1, "Module not found\n"); - } else - printf("Module '%s' deleted from library\n", filename); - - return (*first); -} - -void -lib_Free(sLibrary * lib) -{ - while (lib) { - sLibrary *l; - - if (lib->pData) - free(lib->pData); - - l = lib; - lib = lib->pNext; - free(l); - } -} diff --git a/src/lib/main.c b/src/lib/main.c deleted file mode 100644 index 3aeb4c61..00000000 --- a/src/lib/main.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include - -#include "asmotor.h" - -#include "extern/err.h" -#include "lib/types.h" -#include "lib/library.h" - -/* - * Print the usagescreen - * - */ - -static void -usage(void) -{ - printf("RGBLib v" LIB_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n"); - printf("usage: rgblib file [add | delete | extract | list] [module ...]\n"); - exit(1); -} -/* - * The main routine - * - */ - -int -main(int argc, char *argv[]) -{ - SLONG argn = 0; - char *libname; - - argc -= 1; - argn += 1; - - if (argc >= 2) { - sLibrary *lib; - - lib = lib_Read(libname = argv[argn++]); - argc -= 1; - - if (strcmp(argv[argn], "add") == 0) { - argn += 1; - argc -= 1; - - while (argc) { - lib = lib_AddReplace(lib, argv[argn++]); - argc -= 1; - } - lib_Write(lib, libname); - lib_Free(lib); - } else if (strcmp(argv[argn], "delete") == 0) { - argn += 1; - argc -= 1; - - while (argc) { - lib = - lib_DeleteModule(lib, argv[argn++]); - argc -= 1; - } - lib_Write(lib, libname); - lib_Free(lib); - } else if (strcmp(argv[argn], "extract") == 0) { - argn += 1; - argc -= 1; - - while (argc) { - sLibrary *l; - - l = lib_Find(lib, argv[argn]); - if (l) { - FILE *f; - - if ((f = fopen(argv[argn], "wb"))) { - fwrite(l->pData, - sizeof(UBYTE), - l->nByteLength, - f); - fclose(f); - printf - ("Extracted module '%s'\n", - argv[argn]); - } else { - err(1, - "Unable to write module '%s'", argv[argn]); - } - } else { - fprintf(stderr, "Module not found\n"); - exit(1); - } - - argn += 1; - argc -= 1; - } - lib_Free(lib); - } else if (strcmp(argv[argn], "list") == 0) { - sLibrary *l; - - l = lib; - - while (l) { - printf("%10ld %s\n", - l->nByteLength, - l->tName); - l = l->pNext; - } - } else - usage(); - } else - usage(); - - return (0); -} diff --git a/src/lib/rgblib.1 b/src/lib/rgblib.1 deleted file mode 100644 index 7a53b3d5..00000000 --- a/src/lib/rgblib.1 +++ /dev/null @@ -1,36 +0,0 @@ -.Dd $Mdocdate$ -.Dt RGBLIB 1 -.Os RGBDS Manual -.Sh NAME -.Nm rgblib -.Nd Game Boy library manager -.Sh SYNOPSIS -.Nm rgblib -.Ar library -.Op add | delete | extract | list -.Ar module ... -.Sh DESCRIPTION -The -.Nm -program manages libraries for use with -.Xr rgblink 1 . -.Bl -tag -width Ds -.It add -Add the given modules to the library. -.It delete -Delete the given modules from the library. -.It extract -Extract the given modules from the library. -.It list -List all the modules in the library. -.El -.Sh SEE ALSO -.Xr rgbds 7 , -.Xr rgbasm 1 , -.Xr rgbfix 1 , -.Xr rgblink 1 , -.Xr gbz80 7 -.Sh HISTORY -.Nm -was originally released by Carsten S\(/orensen as part of the ASMotor package, -and was later packaged in RGBDS by Justin Lloyd. diff --git a/src/link/main.c b/src/link/main.c index 29c7d1cc..16465558 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -37,7 +37,7 @@ usage(void) { printf("RGBLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n"); - printf("usage: rgblink [-t] [-l library] [-m mapfile] [-n symfile] [-o outfile]\n"); + printf("usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile]\n"); printf("\t [-s symbol] [-z pad_value] objectfile [...]\n"); exit(1); @@ -59,9 +59,6 @@ main(int argc, char *argv[]) while ((ch = getopt(argc, argv, "l:m:n:o:p:s:t")) != -1) { switch (ch) { - case 'l': - lib_Readfile(optarg); - break; case 'm': SetMapfileName(optarg); break; diff --git a/src/link/object.c b/src/link/object.c index 3d15bcb1..d216425d 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -494,26 +494,3 @@ lib_ReadXLB0(FILE * f) obj_ReadOpenFile(f, name); } } - -void -lib_Readfile(char *tzLibfile) -{ - FILE *pObjfile; - - oReadLib = 1; - - pObjfile = fopen(tzLibfile, "rb"); - if (pObjfile == NULL) { - err(1, "Unable to open object '%s'", tzLibfile); - } - char tzHeader[5]; - - fread(tzHeader, sizeof(char), 4, pObjfile); - tzHeader[4] = 0; - if (strcmp(tzHeader, "XLB0") == 0) - lib_ReadXLB0(pObjfile); - else { - errx(1, "'%s' is an invalid library", tzLibfile); - } - fclose(pObjfile); -} diff --git a/src/link/rgblink.1 b/src/link/rgblink.1 index 8c350450..64eee3d0 100644 --- a/src/link/rgblink.1 +++ b/src/link/rgblink.1 @@ -29,12 +29,6 @@ option to override this. .Pp The arguments are as follows: .Bl -tag -width Ds -.It Fl l Ar library -Include a referenced library module created with -.Xr rgblib 1 . -Note that specified libraries will be included only if needed\(emthat is, if -a SECTION from a library is referenced by an object file. -Only the relevant SECTION will be included, rather than the entire module. .It Fl m Ar mapfile Write a mapfile to the given filename. .It Fl n Ar symfile @@ -70,7 +64,6 @@ to fix these so that the program will actually run in a Game Boy: .Xr rgbds 7 , .Xr rgbasm 1 , .Xr rgbfix 1 , -.Xr rgblib 1 , .Xr gbz80 7 .Sh HISTORY .Nm diff --git a/src/rgbds.7 b/src/rgbds.7 index 28dcde59..72ed881c 100644 --- a/src/rgbds.7 +++ b/src/rgbds.7 @@ -13,7 +13,6 @@ To get a working ROM image from a single assembly source file: .Sh SEE ALSO .Xr rgbasm 1 , .Xr rgbfix 1 , -.Xr rgblib 1 , .Xr rgblink 1 , .Xr gbz80 7 .Sh HISTORY From e3df758897b30efdfd803a6212012904e220580d Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 03:07:43 -0600 Subject: [PATCH 21/36] Update license. --- LICENSE | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 27ec9897..1ad679d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -rgbasm, and rgblink are derived from Justin Lloyd's RGBDS, which is +rgbasm and rgblink are derived from Justin Lloyd's RGBDS, which is released under the following license: DO WHATEVER PUBLIC LICENSE* @@ -17,3 +17,9 @@ released under the following license: rgbfix was rewritten from scratch by Anthony J. Bentley, and is released under the ISC license; see the source file for the text of the license. + +extern/err.c is derived from the Musl C library, http://www.musl-libc.org, +and is released under the MIT license. + +extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org, +and is released under the BSD license. From f3394f46b4d322bc746540c16122a5f69585927c Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 03:17:33 -0600 Subject: [PATCH 22/36] Fix MinGW target. --- Makefile | 3 ++- src/extern/err.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8d02b52c..c693c21e 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,8 @@ src/asm/asmy.y: ${yacc_pre} # install instructions instead. mingw: $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \ - make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}" + make CC=gcc CFLAGS="-I/usr/local/mingw32/include \ + -D__progname=\\\"\\\" ${CFLAGS}" $Qmv rgbasm rgbasm.exe $Qmv rgblink rgblink.exe $Qmv rgbfix rgbfix.exe diff --git a/src/extern/err.c b/src/extern/err.c index 3d363e04..1b5892dd 100644 --- a/src/extern/err.c +++ b/src/extern/err.c @@ -21,12 +21,14 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include #include #include #include +#include "extern/err.h" +#ifndef __MINGW32__ extern char *__progname; +#endif void rgbds_vwarn(const char *fmt, va_list ap) { From 215d6f0c5b57b6be70fc4eac8f14859151c17f2d Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 24 Sep 2014 03:40:50 -0600 Subject: [PATCH 23/36] Revert 97d431d1f4ad404e282e3781bd195be3f053734d; it breaks things. --- include/asm/asm.h | 2 +- include/asm/fstack.h | 2 +- src/asm/fstack.c | 41 ++++++++++++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/asm/asm.h b/include/asm/asm.h index d6a08848..bde48eb3 100644 --- a/include/asm/asm.h +++ b/include/asm/asm.h @@ -24,7 +24,7 @@ extern ULONG nTotalLines; extern ULONG nPC; extern ULONG nPass; extern ULONG nIFDepth; -extern char *tzCurrentFileName; +extern char tzCurrentFileName[_MAX_PATH + 1]; extern struct Section *pCurrentSection; extern struct sSymbol *tHashedSymbols[HASHSIZE]; extern struct sSymbol *pPCSymbol; diff --git a/include/asm/fstack.h b/include/asm/fstack.h index 92e4c101..c3ca1ef0 100644 --- a/include/asm/fstack.h +++ b/include/asm/fstack.h @@ -19,7 +19,7 @@ struct sContext { YY_BUFFER_STATE FlexHandle; struct sSymbol *pMacro; struct sContext *pNext; - char *tzFileName; + char tzFileName[_MAX_PATH + 1]; char *tzMacroArgs[MAXMACROARGS + 1]; SLONG nLine; ULONG nStatus; diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 40abba0b..8c749616 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -31,7 +31,7 @@ struct sSymbol *pCurrentMacro; YY_BUFFER_STATE CurrentFlexHandle; FILE *pCurrentFile; ULONG nCurrentStatus; -char *tzCurrentFileName; +char tzCurrentFileName[_MAX_PATH + 1]; char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; SLONG NextIncPath = 0; ULONG nMacroCount; @@ -70,7 +70,8 @@ pushcontext(void) (struct sContext *) malloc(sizeof(struct sContext))) != NULL) { (*ppFileStack)->FlexHandle = CurrentFlexHandle; (*ppFileStack)->pNext = NULL; - (*ppFileStack)->tzFileName = tzCurrentFileName; + strcpy((char *) (*ppFileStack)->tzFileName, + (char *) tzCurrentFileName); (*ppFileStack)->nLine = nLineNo; switch ((*ppFileStack)->nStatus = nCurrentStatus) { case STAT_isMacroArg: @@ -131,7 +132,8 @@ popcontext(void) nLineNo += 1; CurrentFlexHandle = pLastFile->FlexHandle; - tzCurrentFileName = pLastFile->tzFileName; + strcpy((char *) tzCurrentFileName, + (char *) pLastFile->tzFileName); switch (nCurrentStatus = pLastFile->nStatus) { case STAT_isMacroArg: case STAT_isMacro: @@ -247,7 +249,7 @@ fstk_RunInclude(char *tzFileName) pushcontext(); nLineNo = 1; nCurrentStatus = STAT_isInclude; - tzCurrentFileName = tzFileName; + strcpy(tzCurrentFileName, tzFileName); pCurrentFile = f; CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); @@ -275,7 +277,7 @@ fstk_RunMacro(char *s) nLineNo = -1; sym_UseNewMacroArgs(); nCurrentStatus = STAT_isMacro; - tzCurrentFileName = s; + strcpy(tzCurrentFileName, s); pCurrentMacro = sym; CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, @@ -285,7 +287,32 @@ fstk_RunMacro(char *s) } else return (0); } +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up a macroargument for parsing + * + */ +void +fstk_RunMacroArg(SLONG s) +{ + char *sym; + + if (s == '@') + s = -1; + else + s -= '0'; + + if ((sym = sym_FindMacroArg(s)) != NULL) { + pushcontext(); + nCurrentStatus = STAT_isMacroArg; + sprintf(tzCurrentFileName, "%c", (UBYTE) s); + CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym)); + yy_switch_to_buffer(CurrentFlexHandle); + } else + fatalerror("No such macroargument"); +} /* * RGBAsm - FSTACK.C (FileStack routines) * @@ -301,7 +328,7 @@ fstk_RunString(char *s) if ((pSym = sym_FindSymbol(s)) != NULL) { pushcontext(); nCurrentStatus = STAT_isMacroArg; - tzCurrentFileName = s; + strcpy(tzCurrentFileName, s); CurrentFlexHandle = yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro)); yy_switch_to_buffer(CurrentFlexHandle); @@ -355,7 +382,7 @@ fstk_Init(char *s) nMacroCount = 0; nCurrentStatus = STAT_isInclude; - tzCurrentFileName = tzFileName; + strcpy(tzCurrentFileName, tzFileName); CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); nLineNo = 1; From 3992ce2502e46caf0105d093ee8f65651b2c6650 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Thu, 25 Sep 2014 20:40:25 -0600 Subject: [PATCH 24/36] Separate errors that shouldn't have been combined in the first place. --- src/asm/output.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/asm/output.c b/src/asm/output.c index b1c254a6..24d88290 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -504,9 +504,12 @@ void checkcodesection(SLONG size) { checksection(); - if ((pCurrentSection->nType == SECT_ROM0 - || pCurrentSection->nType == SECT_ROMX) - && (pCurrentSection->nPC + size <= MAXSECTIONSIZE)) { + if (pCurrentSection->nType != SECT_ROM0 && + pCurrentSection->nType != SECT_ROMX) { + errx(1, "Section '%s' cannot contain code or data (not a " + "ROM0 or ROMX)", pCurrentSection->pzName); + } + if (pCurrentSection->nPC + size <= MAXSECTIONSIZE) { if (((pCurrentSection->nPC % SECTIONCHUNK) > ((pCurrentSection->nPC + size) % SECTIONCHUNK)) && (pCurrentSection->nType == SECT_ROM0 @@ -523,8 +526,7 @@ checkcodesection(SLONG size) } return; } else - fatalerror - ("Section can't contain initialized data or section limit exceeded"); + errx(1, "Section '%s' is too big", pCurrentSection->pzName); } /* * RGBAsm - OUTPUT.C - Outputs an objectfile From 0d07caba60b5d082a22cbbb4eb78cfefabb0ea64 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Thu, 25 Sep 2014 20:56:15 -0600 Subject: [PATCH 25/36] Remove inconsistent version numbering. --- include/asm/asm.h | 2 -- include/asmotor.h | 21 --------------------- src/asm/main.c | 2 -- src/asm/symbol.c | 1 - src/link/main.c | 4 ---- src/link/mapfile.c | 4 +--- 6 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 include/asmotor.h diff --git a/include/asm/asm.h b/include/asm/asm.h index bde48eb3..548a412e 100644 --- a/include/asm/asm.h +++ b/include/asm/asm.h @@ -17,8 +17,6 @@ #include "localasm.h" -#include "asmotor.h" - extern SLONG nLineNo; extern ULONG nTotalLines; extern ULONG nPC; diff --git a/include/asmotor.h b/include/asmotor.h deleted file mode 100644 index d9fa856c..00000000 --- a/include/asmotor.h +++ /dev/null @@ -1,21 +0,0 @@ -/* asmotor.h - * - * Contains defines for every program in the ASMotor package - * - * Copyright 1997 Carsten Sorensen - * - */ - -#ifndef ASMOTOR_ASMOTOR_H -#define ASMOTOR_ASMOTOR_H - -#define ASMOTOR - -#define ASMOTOR_VERSION "1.10-linux" - -#define ASM_VERSION "1.08c" -#define LINK_VERSION "1.06c" -#define RGBFIX_VERSION "1.02" -#define LIB_VERSION "1.00" - -#endif diff --git a/src/asm/main.c b/src/asm/main.c index 822f96b0..cca7d954 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -242,8 +242,6 @@ fatalerror(const char *fmt, ...) void PrintUsage(void) { - printf("RGBAsm v" ASM_VERSION " (part of ASMotor " ASMOTOR_VERSION - ")\n\n"); printf("Usage: rgbasm [-v] [-h] [-b chars] [-g chars] [-i path] [-o outfile] [-p pad_value]\n" " file\n"); exit(1); diff --git a/src/asm/symbol.c b/src/asm/symbol.c index e63b3d5e..1d9f556d 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -873,7 +873,6 @@ sym_Init(void) p_NARGSymbol = findsymbol("_NARG", NULL); p_NARGSymbol->Callback = Callback_NARG; - sym_AddEqu("__ASM__", (SLONG) (atof(ASM_VERSION) * 65536)); sym_AddSet("_RS", 0); if (time(&tod) != -1) { diff --git a/src/link/main.c b/src/link/main.c index 16465558..f81f85d8 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -4,8 +4,6 @@ #include #include -#include "asmotor.h" - #include "extern/err.h" #include "link/object.h" #include "link/output.h" @@ -35,8 +33,6 @@ char smartlinkstartsymbol[256]; static void usage(void) { - printf("RGBLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION - ")\n\n"); printf("usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile]\n"); printf("\t [-s symbol] [-z pad_value] objectfile [...]\n"); diff --git a/src/link/mapfile.c b/src/link/mapfile.c index fce261f8..1264d7c3 100644 --- a/src/link/mapfile.c +++ b/src/link/mapfile.c @@ -3,8 +3,6 @@ #include #include -#include "asmotor.h" - #include "extern/err.h" #include "link/main.h" #include "link/mylink.h" @@ -34,7 +32,7 @@ SetSymfileName(char *name) err(1, "Cannot open symfile '%s'", name); } - fprintf(sf, ";File generated by xLink v" LINK_VERSION "\n\n"); + fprintf(sf, ";File generated by rgblink\n\n"); } void From 3e4350afa4a855b9c33f971cc5484a911b4ca987 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 26 Sep 2014 00:39:29 -0600 Subject: [PATCH 26/36] Don't cast calls to malloc(). --- src/asm/fstack.c | 3 +-- src/asm/lexer.c | 15 +++++---------- src/asm/main.c | 4 +--- src/asm/output.c | 23 +++++++---------------- src/asm/symbol.c | 6 ++---- src/asm/yaccprt1.y | 6 ++---- src/link/assign.c | 1 - 7 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/asm/fstack.c b/src/asm/fstack.c index 8c749616..a8d0ade5 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -66,8 +66,7 @@ pushcontext(void) while (*ppFileStack) ppFileStack = &((*ppFileStack)->pNext); - if ((*ppFileStack = - (struct sContext *) malloc(sizeof(struct sContext))) != NULL) { + if ((*ppFileStack = malloc(sizeof(struct sContext))) != NULL) { (*ppFileStack)->FlexHandle = CurrentFlexHandle; (*ppFileStack)->pNext = NULL; strcpy((char *) (*ppFileStack)->tzFileName, diff --git a/src/asm/lexer.c b/src/asm/lexer.c index b6fac43c..ce341ec0 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -116,11 +116,9 @@ yy_scan_bytes(char *mem, ULONG size) { YY_BUFFER_STATE pBuffer; - if ((pBuffer = - (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != - NULL) { + if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) { if ((pBuffer->pBufferRealStart = - (char *) malloc(size + 1 + SAFETYMARGIN)) != NULL) { + malloc(size + 1 + SAFETYMARGIN)) != NULL) { pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN; pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN; memcpy(pBuffer->pBuffer, mem, size); @@ -139,8 +137,7 @@ yy_create_buffer(FILE * f) { YY_BUFFER_STATE pBuffer; - if ((pBuffer = - (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) != NULL) { + if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) { ULONG size; fseek(f, 0, SEEK_END); @@ -148,7 +145,7 @@ yy_create_buffer(FILE * f) fseek(f, 0, SEEK_SET); if ((pBuffer->pBufferRealStart = - (char *) malloc(size + 2 + SAFETYMARGIN)) != NULL) { + malloc(size + 2 + SAFETYMARGIN)) != NULL) { char *mem; ULONG instring = 0; @@ -344,9 +341,7 @@ lex_AddStrings(struct sLexInitString * lex) while (*ppHash) ppHash = &((*ppHash)->pNext); - if (((*ppHash) = - (struct sLexString *) malloc(sizeof(struct sLexString))) != - NULL) { + if (((*ppHash) = malloc(sizeof(struct sLexString))) != NULL) { if (((*ppHash)->tzName = (char *) strdup(lex->tzName)) != NULL) { (*ppHash)->nNameLength = strlen(lex->tzName); diff --git a/src/asm/main.c b/src/asm/main.c index cca7d954..ee2fa262 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -173,9 +173,7 @@ opt_Push(void) { struct sOptionStackEntry *pOpt; - if ((pOpt = - (struct sOptionStackEntry *) - malloc(sizeof(struct sOptionStackEntry))) != NULL) { + if ((pOpt = malloc(sizeof(struct sOptionStackEntry))) != NULL) { pOpt->Options = CurrentOptions; pOpt->pNext = pOptionStack; pOptionStack = pOpt; diff --git a/src/asm/output.c b/src/asm/output.c index 24d88290..de3cfc5c 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -77,9 +77,7 @@ out_PushSection(void) { struct SectionStackEntry *pSect; - if ((pSect = - (struct SectionStackEntry *) - malloc(sizeof(struct SectionStackEntry))) != NULL) { + if ((pSect = malloc(sizeof(struct SectionStackEntry))) != NULL) { pSect->pSection = pCurrentSection; pSect->pNext = pSectionStack; pSectionStack = pSect; @@ -343,9 +341,7 @@ addsymbol(struct sSymbol * pSym) ppPSym = &((*ppPSym)->pBucketNext); } - if ((*ppPSym = pPSym = - (struct PatchSymbol *) malloc(sizeof(struct PatchSymbol))) != - NULL) { + if ((*ppPSym = pPSym = malloc(sizeof(struct PatchSymbol))) != NULL) { pPSym->pNext = NULL; pPSym->pBucketNext = NULL; pPSym->pSymbol = pSym; @@ -393,8 +389,7 @@ allocpatch(void) { struct Patch *pPatch; - if ((pPatch = - (struct Patch *) malloc(sizeof(struct Patch))) != NULL) { + if ((pPatch = malloc(sizeof(struct Patch))) != NULL) { pPatch->pNext = pCurrentSection->pPatches; pPatch->nRPNSize = 0; pPatch->pRPN = NULL; @@ -472,7 +467,7 @@ createpatch(ULONG type, struct Expression * expr) break; } } - if ((pPatch->pRPN = (UBYTE *) malloc(rpnptr)) != NULL) { + if ((pPatch->pRPN = malloc(rpnptr)) != NULL) { memcpy(pPatch->pRPN, rpnexpr, rpnptr); pPatch->nRPNSize = rpnptr; } @@ -633,11 +628,8 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, pSect = pSect->pNext; } - if ((*ppSect = - (pSect = - (struct Section *) malloc(sizeof(struct Section)))) != NULL) { - if ((pSect->pzName = - (char *) malloc(strlen(pzName) + 1)) != NULL) { + if ((*ppSect = (pSect = malloc(sizeof(struct Section)))) != NULL) { + if ((pSect->pzName = malloc(strlen(pzName) + 1)) != NULL) { strcpy(pSect->pzName, pzName); pSect->nType = secttype; pSect->nPC = 0; @@ -647,8 +639,7 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, pSect->pPatches = NULL; pPatchSymbols = NULL; - if ((pSect->tData = - (UBYTE *) malloc(SECTIONCHUNK)) != NULL) { + if ((pSect->tData = malloc(SECTIONCHUNK)) != NULL) { return (pSect); } else fatalerror("Not enough memory for section"); diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 1d9f556d..64b8ad1b 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -94,8 +94,7 @@ createsymbol(char *s) while ((*ppsym) != NULL) ppsym = &((*ppsym)->pNext); - if (((*ppsym) = - (struct sSymbol *) malloc(sizeof(struct sSymbol))) != NULL) { + if (((*ppsym) = malloc(sizeof(struct sSymbol))) != NULL) { strcpy((*ppsym)->tzName, s); (*ppsym)->nValue = 0; (*ppsym)->nType = 0; @@ -570,8 +569,7 @@ sym_AddString(char *tzSym, char *tzValue) nsym = createsymbol(tzSym); if (nsym) { - if ((nsym->pMacro = - (char *) malloc(strlen(tzValue) + 1)) != NULL) + if ((nsym->pMacro = malloc(strlen(tzValue) + 1)) != NULL) strcpy(nsym->pMacro, tzValue); else fatalerror("No memory for stringequate"); diff --git a/src/asm/yaccprt1.y b/src/asm/yaccprt1.y index 8464d370..7463cec6 100644 --- a/src/asm/yaccprt1.y +++ b/src/asm/yaccprt1.y @@ -130,8 +130,7 @@ void copyrept( void ) src=pCurrentBuffer->pBuffer; ulNewMacroSize=len; - if( (tzNewMacro=(char *)malloc(ulNewMacroSize+1))!=NULL ) - { + if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) { ULONG i; tzNewMacro[ulNewMacroSize]=0; @@ -140,8 +139,7 @@ void copyrept( void ) if( (tzNewMacro[i]=src[i])=='\n' ) nLineNo+=1; } - } - else + } else fatalerror( "No mem for REPT block" ); yyskipbytes( ulNewMacroSize+4 ); diff --git a/src/link/assign.c b/src/link/assign.c index a5d37acb..edbefc33 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -64,7 +64,6 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size) struct sFreeArea *pNewArea; if ((pNewArea = - (struct sFreeArea *) malloc(sizeof(struct sFreeArea))) != NULL) { *pNewArea = *pArea; From 73e44cb803809f1dacaeb1de203ecf42ab1e96a4 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 26 Sep 2014 15:27:52 -0600 Subject: [PATCH 27/36] Fix dependencies for Yacc files. Improve Makefile POSIX compliance. Parallel building issue pointed out by murphm8 and chastai. --- Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c693c21e..350fc79f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.POSIX: + REALCFLAGS = ${CFLAGS} -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99 # User-defined variables @@ -77,11 +79,14 @@ rgblink: ${rgblink_obj} rgbfix: ${rgbfix_obj} $Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj} +.y.c: + $Q${YACC} -d ${YFLAGS} -o $@ $< + .c.o: $Q${CC} ${REALCFLAGS} -c -o $@ $< -src/asm/asmy.c: src/asm/asmy.y - $Q${YACC} -d -o $@ $< +src/asm/gameboy/locallex.c src/asm/globlex.c src/asm/lexer.c: src/asm/asmy.h +src/asm/asmy.h: src/asm/asmy.c src/asm/asmy.y: ${yacc_pre} $Qcat ${yacc_pre} > $@ @@ -112,5 +117,3 @@ wwwman: rgbfix.html $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \ rgblink.html - -.POSIX: From 32fa032a62e9e6385e9aa9e3c296526bec3fa939 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 3 Oct 2014 15:14:40 -0600 Subject: [PATCH 28/36] =?UTF-8?q?Makefile:=20Create=20install=20directorie?= =?UTF-8?q?s=20if=20they=20don=E2=80=99t=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 350fc79f..9860e2ac 100644 --- a/Makefile +++ b/Makefile @@ -54,9 +54,11 @@ clean: $Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y install: all + $Qmkdir -p ${BINPREFIX} $Qinstall -s -m 555 rgbasm ${BINPREFIX}/rgbasm $Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix $Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink + $Qmkdir -p ${MANPREFIX}/man1 ${MANPREFIX}/man7 $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \ (echo Installing manpages to ${MANPREFIX} failed. >&2 && \ echo Check where your manpages are installed and set the \ From 00de7674af6d7636e99c057f52d1913142454b85 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 3 Oct 2014 15:17:49 -0600 Subject: [PATCH 29/36] Now that install dirs are created, this error is unlikely to occur. --- Makefile | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 9860e2ac..9ec29fd8 100644 --- a/Makefile +++ b/Makefile @@ -59,18 +59,10 @@ install: all $Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix $Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink $Qmkdir -p ${MANPREFIX}/man1 ${MANPREFIX}/man7 - $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \ - (echo Installing manpages to ${MANPREFIX} failed. >&2 && \ - echo Check where your manpages are installed and set the \ - proper directory >&2 && \ - echo with, e.g., make install MANPREFIX=/usr/share/man \ - >&2 ; false) - $Qinstall -m 444 src/asm/rgbasm.1 \ - ${MANPREFIX}/man1/rgbasm.1 - $Qinstall -m 444 src/fix/rgbfix.1 \ - ${MANPREFIX}/man1/rgbfix.1 - $Qinstall -m 444 src/link/rgblink.1 \ - ${MANPREFIX}/man1/rgblink.1 + $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 + $Qinstall -m 444 src/asm/rgbasm.1 ${MANPREFIX}/man1/rgbasm.1 + $Qinstall -m 444 src/fix/rgbfix.1 ${MANPREFIX}/man1/rgbfix.1 + $Qinstall -m 444 src/link/rgblink.1 ${MANPREFIX}/man1/rgblink.1 rgbasm: ${rgbasm_obj} $Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm From 191f98a008c428b24fdeae6ef302abfd017d9428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Sta=C3=AFesse?= Date: Sun, 5 Oct 2014 11:37:11 +0200 Subject: [PATCH 30/36] Fix incorrect dependencies in Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9ec29fd8..56eddfba 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ rgbfix: ${rgbfix_obj} .c.o: $Q${CC} ${REALCFLAGS} -c -o $@ $< -src/asm/gameboy/locallex.c src/asm/globlex.c src/asm/lexer.c: src/asm/asmy.h +src/asm/gameboy/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h src/asm/asmy.h: src/asm/asmy.c src/asm/asmy.y: ${yacc_pre} From 424702b272c78e1bc5a9e383948561f569467cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Sta=C3=AFesse?= Date: Tue, 1 Apr 2014 16:48:26 +0200 Subject: [PATCH 31/36] Fix bug: rgbasm segfault when \@ is used outside a macro The problem occurs when \@ is accessed outside the definition of a macro and is not between "" or {}, or when it is used in an argument of a macro call, i.e. when the access is processed by PutUniqueArg(). PutUniqueArg(), puts back the string value of \@ to the lexer's buffer (to substitute \@ by the unique label string). When \@ is not defined, sym_FindMacroArg(-1) returns NULL, which yyunputstr() doesn't expect and crashes. Solution: Generate an error when \@ is not defined. Regression test: SECTION "HOME", HOME ld a,\@ Will segfault. On the fixed version, it will return an error as \@ is not available. --- src/asm/globlex.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/asm/globlex.c b/src/asm/globlex.c index c26cdc4d..88ae4167 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -219,9 +219,15 @@ PutMacroArg(char *src, ULONG size) ULONG PutUniqueArg(char *src, ULONG size) { + char *s; + src = src; yyskipbytes(size); - yyunputstr(sym_FindMacroArg(-1)); + if ((s = sym_FindMacroArg(-1)) != NULL) { + yyunputstr(s); + } else { + yyerror("Macro unique label string not defined"); + } return (0); } From 67583876684ec56b99d71b7480d6bcfa4d1f4c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Sta=C3=AFesse?= Date: Sun, 5 Oct 2014 16:36:57 +0200 Subject: [PATCH 32/36] Add assertion to symFindMacroArg() to debug oob array access --- src/asm/symbol.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 64b8ad1b..18f942af 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -5,6 +5,7 @@ * */ +#include #include #include #include @@ -431,6 +432,8 @@ sym_FindMacroArg(SLONG i) if (i == -1) i = MAXMACROARGS + 1; + assert(i-1 >= 0 && + i-1 < sizeof(currentmacroargs)/sizeof(*currentmacroargs)); return (currentmacroargs[i - 1]); } From 4577a01c688aa0b9a28c69fd89153cc96808a667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Sta=C3=AFesse?= Date: Sun, 5 Oct 2014 13:42:07 +0200 Subject: [PATCH 33/36] Fix out of bounds array access on invalid macro arg references A reference to an invalid macro argument (\ not followed by a digit between 1 and 9) will cause an access outside of the bounds of the currentmacroargs array in sym_FindMacroArg(). Macro arg references are processed in two places: In CopyMacroArg(): called when scanning tokens between "", {} and arguments of a macro call. The only problem here is that it accepts \0 as valid and so calls sym_FindMacroArg with a invalid value. In PutMacroArg(): called by the lexer automata when it encounters a token matching \\[0-9]? (in other cases than above). So not only it accepts \0 but also \ alone. Memo: In setuplex(), a rule is defined with a regex composed of up to three ranges of chars and takes the form: [FirstRange] or [FirstRange][SecondRange]? or [FirstRange]([SecondRange][Range]*)? On scanning, when several rules match, the first longuest one is choosen. Regression test: 1) SECTION "HOME", HOME db "\0" 2) SECTION "HOME", HOME db \A 3) SECTION "HOME", HOME db \ --- src/asm/globlex.c | 12 ++++++++---- src/asm/lexer.c | 1 - 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/asm/globlex.c b/src/asm/globlex.c index c26cdc4d..3bb64164 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -208,10 +208,14 @@ PutMacroArg(char *src, ULONG size) char *s; yyskipbytes(size); - if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) { - yyunputstr(s); + if ((size == 2 && src[1] >= '1' && src[1] <= '9')) { + if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) { + yyunputstr(s); + } else { + yyerror("Macro argument not defined"); + } } else { - yyerror("Macro argument not defined"); + yyerror("Invalid macro argument"); } return (0); } @@ -387,7 +391,7 @@ setuplex(void) id = lex_FloatAlloc(&tMacroArgToken); lex_FloatAddFirstRange(id, '\\', '\\'); - lex_FloatAddSecondRange(id, '0', '9'); + lex_FloatAddSecondRange(id, '1', '9'); id = lex_FloatAlloc(&tMacroUniqueToken); lex_FloatAddFirstRange(id, '\\', '\\'); lex_FloatAddSecondRange(id, '@', '@'); diff --git a/src/asm/lexer.c b/src/asm/lexer.c index ce341ec0..8d6a8a25 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -437,7 +437,6 @@ CopyMacroArg(char *dest, size_t maxLength, char c) int argNum; switch (c) { - case '0': case '1': case '2': case '3': From cd8d895c1b5695c63d4faa3efb97c4b70fe3bf3e Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Mon, 6 Oct 2014 01:54:03 -0600 Subject: [PATCH 34/36] Style. --- src/asm/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 18f942af..34f08445 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -433,7 +433,7 @@ sym_FindMacroArg(SLONG i) i = MAXMACROARGS + 1; assert(i-1 >= 0 && - i-1 < sizeof(currentmacroargs)/sizeof(*currentmacroargs)); + i-1 < sizeof currentmacroargs / sizeof *currentmacroargs); return (currentmacroargs[i - 1]); } From c6c7b99fadba635b03653c784c5c03a3edd1ac25 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Fri, 10 Oct 2014 03:48:52 -0600 Subject: [PATCH 35/36] PATH_MAX is not exactly portable. Hack around it for now. --- src/asm/fstack.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/asm/fstack.c b/src/asm/fstack.c index a8d0ade5..79da9ccc 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -19,6 +19,10 @@ #include "extern/err.h" #include "extern/strl.h" +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + /* * RGBAsm - FSTACK.C (FileStack routines) * From 25efb00769cb1a16fe3ab643e4b63d33402a5bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christophe=20Sta=C3=AFesse?= Date: Fri, 10 Oct 2014 15:22:00 +0200 Subject: [PATCH 36/36] fix a bug in the lexer involving double quote escaping and semicolons The bug showed up when a semicolon was located anywhere after \". These three test cases are syntaxically correct but didn't compile: 1) SECTION "HOME", HOME db "\";" 2) SECTION "HOME", HOME db "\"" nop ; 3) SECTION "HOME", HOME db "\"" ; The problem was located in yy_create_buffer(). Basicaly, this function loads an entire source file, uniformizes EOL terminators and filters out comments without touching literal strings. However, bounds of literal strings were wrongly guessed because \" was interpreted as two characters (and so the double quote was not escaped). In test 1, the string terminates early and so ;" is filtered out as it was a comment and so the assembler complains of an unterminated string. In test 2 and 3, the string is in fact interpreted as two strings, the second one terminates at EOF in these cases and so comments are not filtered out and that makes the assembler complains. A special case must be taken into account: 4) SECTION "HOME", HOME db "\\" ; So we need to ignore \\ as well. Note that there is still a problem left: in yy_create_buffer() a string may span multiple lines but not in the lexer. However in this case I think the lexer would quit at the first newline so there should be nothing to worry about. --- src/asm/lexer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 8d6a8a25..92288425 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -164,7 +164,10 @@ yy_create_buffer(FILE * f) if (*mem == '\"') instring = 1 - instring; - if (instring) { + if (mem[0] == '\\' && + (mem[1] == '\"' || mem[1] == '\\')) { + mem += 2; + } else if (instring) { mem += 1; } else { if ((mem[0] == 10 && mem[1] == 13)