From d95ee7f628ceac9af515079fb6797476557a23d2 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 13 Jan 2015 11:06:11 -0600 Subject: [PATCH] Fixed bug with -l switch. Turns out that the tokenClass buffer was too small, leading the eval() function to dip into random memory. *facepalm* --- expr.c | 68 +++++++++++++++++++---------------------- listing.c | 91 +++++++++++++++++++++++++------------------------------ object.c | 72 +++++++++++++++++++++---------------------- procln.c | 12 ++++---- riscasm.c | 2 -- token.c | 20 +++++------- version.h | 2 +- 7 files changed, 122 insertions(+), 145 deletions(-) diff --git a/expr.c b/expr.c index 6373114..9eeb6e7 100644 --- a/expr.c +++ b/expr.c @@ -17,45 +17,48 @@ #include "symbol.h" #include "token.h" -#define DEF_KW // Declare keyword values -#include "kwtab.h" // Incl generated keyword tables & defs +#define DEF_KW // Declare keyword values +#include "kwtab.h" // Incl generated keyword tables & defs -static char tokenClass[128]; // Generated table of token classes -static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack -static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack +// N.B.: The size of tokenClass should be identical to the largest value of +// a token; we're assuming 256 but not 100% sure! +static char tokenClass[256]; // Generated table of token classes +static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack +static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack // Token-class initialization list char itokcl[] = { - 0, // END - CONST, SYMBOL, 0, // ID - '(', '[', '{', 0, // OPAR - ')', ']', '}', 0, // CPAR - CR_DEFINED, CR_REFERENCED, // SUNARY (special unary) + 0, // END + CONST, SYMBOL, 0, // ID + '(', '[', '{', 0, // OPAR + ')', ']', '}', 0, // CPAR + CR_DEFINED, CR_REFERENCED, // SUNARY (special unary) CR_STREQ, CR_MACDEF, CR_DATE, CR_TIME, 0, - '!', '~', UNMINUS, 0, // UNARY - '*', '/', '%', 0, // MULT - '+', '-', 0, // ADD - SHL, SHR, 0, // SHIFT - LE, GE, '<', '>', NE, '=', 0, // REL - '&', 0, // AND - '^', 0, // XOR - '|', 0, // OR - 1 // (the end) + '!', '~', UNMINUS, 0, // UNARY + '*', '/', '%', 0, // MULT + '+', '-', 0, // ADD + SHL, SHR, 0, // SHIFT + LE, GE, '<', '>', NE, '=', 0, // REL + '&', 0, // AND + '^', 0, // XOR + '|', 0, // OR + 1 // (the end) }; const char missym_error[] = "missing symbol"; const char str_error[] = "missing symbol or string"; // Convert expression to postfix -static TOKEN * evalTokenBuffer; // Deposit tokens here (this is really a - // pointer to exprbuf from direct.c) - // (Can also be from others, like riscasm.c) -static symbolNum; // Pointer to the entry in symbolPtr[] +static TOKEN * evalTokenBuffer; // Deposit tokens here (this is really a + // pointer to exprbuf from direct.c) + // (Can also be from others, like + // riscasm.c) +static symbolNum; // Pointer to the entry in symbolPtr[] // -// Obtain a String Value +// Obtain a string value // static VALUE str_value(char * p) { @@ -69,15 +72,15 @@ static VALUE str_value(char * p) // -// Initialize Expression Analyzer +// Initialize expression analyzer // void InitExpression(void) { - int i; // Iterator - char * p; // Token pointer + int i; + char * p; // Initialize token-class table (all set to END) - for(i=0; i<128; i++) + for(i=0; i<256; i++) tokenClass[i] = END; for(i=0, p=itokcl; *p!=1; p++) @@ -273,16 +276,8 @@ int expr2(void) case '*': *evalTokenBuffer++ = ACONST; // Attributed const -#if 0 - if (orgactive) - *evalTokenBuffer++ = orgaddr; - else - *evalTokenBuffer++ = pcloc; // Location at start of line -#else // pcloc == location at start of line *evalTokenBuffer++ = (orgactive ? orgaddr : pcloc); -#endif - *evalTokenBuffer++ = ABS | DEFINED; // Store attribs break; default: @@ -731,3 +726,4 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym) return OK; } + diff --git a/listing.c b/listing.c index 5306913..f9064cd 100644 --- a/listing.c +++ b/listing.c @@ -47,8 +47,9 @@ static char * month[16] = { "Dec", "", "", "" }; + // -// Eject the Page (Print Empty Lines), Reset the Line Count and Bump the Page Number +// Eject the page, reset the line count and bump the page number // int eject(void) { @@ -63,7 +64,7 @@ int eject(void) // -// Return GEMDOS Format Date +// Return GEMDOS format date // VALUE dos_date(void) { @@ -73,14 +74,14 @@ VALUE dos_date(void) time(&tloc); tm = localtime(&tloc); - v = ((tm->tm_year - 80) << 9) | ((tm->tm_mon+1) << 5) | tm->tm_mday; + v = ((tm->tm_year - 80) << 9) | ((tm->tm_mon + 1) << 5) | tm->tm_mday; return v; } // -// Return GEMDOS Format Time +// Return GEMDOS format time // VALUE dos_time(void) { @@ -97,12 +98,12 @@ VALUE dos_time(void) // -// Generate a Time String +// Generate a time string // void time_string(char * buf, VALUE time) { int hour; - char *ampm; + char * ampm; hour = (time >> 11); @@ -120,7 +121,7 @@ void time_string(char * buf, VALUE time) // -// Generate a Date String +// Generate a date string // void date_string(char * buf, VALUE date) { @@ -129,20 +130,6 @@ void date_string(char * buf, VALUE date) } -// -// Copy `n' Characters from `src' to `dest' (also stops on EOS in src). -// Does not null-terminate dest. -// -void scopy(char *dest, char *src, int len) -{ - if (len < 0) - len = 1000; // Some large number [Shamus: wha...?] - - while (len-- && *src) - *dest++ = *src++; -} - - // // Transform letters a-f in the address and data columns of the listing to // uppercase. (People seem to like uppercase hex better in assembly-language @@ -162,7 +149,7 @@ void uc_ln(char * ln) // -// Fill Region `dest' with `len' Characters `c' and Null Terminate the Region +// Fill region 'dest' with 'len' characters 'c' and null terminate the region // void lnfill(char * dest, int len, char chr) { @@ -174,7 +161,7 @@ void lnfill(char * dest, int len, char chr) // -// Create Listing File with the Appropriate Name +// Create listing file with the appropriate name // void list_setup(void) { @@ -196,16 +183,16 @@ void list_setup(void) // -// Tag Listing with a Character, Typically for Errors or Warnings +// Tag listing with a character, typically for errors or warnings // void taglist(char chr) { - lnimage[TAG_COL+1] = chr; + lnimage[TAG_COL + 1] = chr; } // -// Print a Line to the Listing File +// Print a line to the listing file // void println(const char * ln) { @@ -222,7 +209,7 @@ void println(const char * ln) // -// Ship Line `ln' Out; Do Page Breaks and Title Stuff +// Ship line 'ln' out; do page breaks and title stuff // void ship_ln(const char * ln) { @@ -237,13 +224,14 @@ void ship_ln(const char * ln) // Print title, boilerplate, and subtitle at top of page if (nlines == 0) { - ++pageno; + pageno++; println(""); date_string(datestr, dos_date()); time_string(timestr, dos_time()); sprintf(buf, "%-40s%-20s Page %-4d %s %s RMAC %01i.%01i.%02i (%s)", - title, curfname, pageno, timestr, datestr, MAJOR, MINOR, PATCH, PLATFORM); + title, curfname, pageno, timestr, datestr, MAJOR, MINOR, PATCH, + PLATFORM); println(buf); sprintf(buf, "%s", subttl); println(buf); @@ -252,12 +240,12 @@ void ship_ln(const char * ln) } println(ln); - ++nlines; + nlines++; } // -// Initialize Listing Generator +// Initialize listing generator // void InitListing(void) { @@ -286,18 +274,18 @@ void listeol(void) LONG count; int fixcount; - DEBUG printf("~list: lsloc=$%ux sloc=$%ux\n", lsloc, sloc); + DEBUG printf("~list: lsloc=$%X sloc=$%X\n", lsloc, sloc); if (lsloc != sloc) { - sprintf(buf, "%08ux", lsloc); - scopy(lnimage+LOC_COL, buf, 8); + sprintf(buf, "%08X", lsloc); + strncpy(lnimage + LOC_COL, buf, 8); } if (llineno != curlineno) { sprintf(buf, "%5d", llineno); - scopy(lnimage+LN_COL, buf, 5); + strncpy(lnimage + LN_COL, buf, 5); } // List bytes only when section stayed the same and the section is not a @@ -306,7 +294,7 @@ void listeol(void) // deposited with dcb. The fix (kludge) is an extra variable which records // the fact that a 'ds.x' directive generated all the data, and it // shouldn't be listed - SaveSection(); // Update section variables + SaveSection(); // Update section variables if (lcursect == cursect && (sect[lcursect].scattr & SBSS) == 0 && lsloc != sloc && just_bss == 0) @@ -323,7 +311,7 @@ void listeol(void) if (ch == NULL) { nochunk: - interror(6); // Can't find generated code in section + interror(6); // Can't find generated code in section } p = ch->chptr + (lsloc - ch->chloc); @@ -333,13 +321,14 @@ nochunk: for(count=sloc-lsloc; count--; col+=2, ++lsloc) { if (col >= DATA_END) - { // Ship the line + { + // Ship the line col = DATA_COL; uc_ln(lnimage); ship_ln(lnimage); - lnfill(lnimage, SRC_COL, SPACE); // Fill with spaces - sprintf(buf, "%08ux", lsloc); - scopy(lnimage+LOC_COL, buf, 8); + lnfill(lnimage, SRC_COL, SPACE); // Fill with spaces + sprintf(buf, "%08X", lsloc); + strncpy(lnimage + LOC_COL, buf, 8); } if (lsloc >= (ch->chloc + ch->ch_size)) @@ -355,14 +344,14 @@ nochunk: if (fixcount) { - --fixcount; + fixcount--; strcpy(buf, "xx"); - ++p; // Advance anyway + p++; // Advance anyway } else sprintf(buf, "%02x", *p++ & 0xff); - scopy(lnimage+col, buf, 2); + strncpy(lnimage + col, buf, 2); } // Flush partial line @@ -381,7 +370,7 @@ nochunk: // -// Copy Current (Saved) Line to Output Buffer and Tag it with a Character +// Copy current (saved) line to output buffer and tag it with a character // void lstout(char tag) { @@ -392,7 +381,7 @@ void lstout(char tag) lcursect = cursect; llineno = curlineno; - lnfill(lnimage, SRC_COL, SPACE); // Fill with spaces + lnfill(lnimage, SRC_COL, SPACE); // Fill with spaces lnimage[TAG_COL] = tag; // Copy line image and handle control characters @@ -414,12 +403,12 @@ void lstout(char tag) // -// Output a Value to Listing +// Output a value to listing // int listvalue(VALUE v) { - sprintf(buf, "=%08ux", v); - scopy(lnimage + DATA_COL - 1, buf, 9); + sprintf(buf, "=%08X", v); + strncpy(lnimage + DATA_COL - 1, buf, 9); return 0; } @@ -463,7 +452,8 @@ int d_subttl(void) // -// Set title on titles not on the first page, do an eject and clobber the subtitle +// Set title on titles not on the first page, do an eject and clobber the +// subtitle // int d_title(void) { @@ -482,3 +472,4 @@ int d_title(void) return 0; } + diff --git a/object.c b/object.c index 4e9613f..ffff623 100644 --- a/object.c +++ b/object.c @@ -13,10 +13,10 @@ #include "error.h" #include "riscasm.h" -LONG symsize = 0; // Size of BSD symbol table -LONG strindx = 0x00000004; // BSD string table index -char * strtable; // Pointer to the symbol string table -char * objimage; // Global object image pointer +LONG symsize = 0; // Size of BSD symbol table +LONG strindx = 0x00000004; // BSD string table index +char * strtable; // Pointer to the symbol string table +char * objimage; // Global object image pointer // @@ -24,20 +24,16 @@ char * objimage; // Global object image pointer // char * constr_bsdsymtab(char * buf, SYM * sym, int globflag) { - LONG z; // Scratch long - WORD w1; // Scratch word - int w2; // Scratch long + chptr = buf; // Point to buffer for deposit longs + D_long(strindx); // Deposit the symbol string index - chptr = buf; // Point to buffer for deposit longs - D_long(strindx); // Deposit the symbol string index - - w1 = sym->sattr; // Obtain symbol attribute - w2 = sym->sattre; - z = 0; // Initialise resulting symbol flags + WORD w1 = sym->sattr; // Obtain symbol attribute + int w2 = sym->sattre; + LONG z = 0; // Initialise resulting symbol flags if (w1 & EQUATED) { - z = 0x02000000; // Set equated flag + z = 0x02000000; // Set equated flag } else { @@ -50,26 +46,26 @@ char * constr_bsdsymtab(char * buf, SYM * sym, int globflag) } if (globflag) - z |= 0x01000000; // Set global flag if requested + z |= 0x01000000; // Set global flag if requested - D_long(z); // Deposit symbol attribute + D_long(z); // Deposit symbol attribute - z = sym->svalue; // Obtain symbol value - w1 &= DATA | BSS; // Determine DATA or BSS flag + z = sym->svalue; // Obtain symbol value + w1 &= DATA | BSS; // Determine DATA or BSS flag if (w1) - z += sect[TEXT].sloc; // If DATA or BSS add TEXT segment size + z += sect[TEXT].sloc; // If DATA or BSS add TEXT segment size if (w1 & BSS) - z += sect[DATA].sloc; // If BSS add DATA segment size + z += sect[DATA].sloc; // If BSS add DATA segment size - D_long(z); // Deposit symbol value + D_long(z); // Deposit symbol value strcpy(strtable + strindx, sym->sname); - strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate - buf += 12; // Increment buffer to next record - symsize += 12; // Increment symbol table size + strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate + buf += 12; // Increment buffer to next record + symsize += 12; // Increment symbol table size return buf; } @@ -140,36 +136,36 @@ int object(WORD fd) } // Do relocation tables (and make changes to segment data) - p = buf + (BSDHDRSIZE + tds); // Move obj image ptr to reloc info + p = buf + (BSDHDRSIZE + tds); // Move obj image ptr to reloc info trsize = bsdmarkimg(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table - chptr = buf + 24; // Point to relocation hdr entry - D_long(trsize); // Write the relocation table size - p = buf + (BSDHDRSIZE + tds + trsize); // Move obj image ptr to reloc info + chptr = buf + 24; // Point to relocation hdr entry + D_long(trsize); // Write the relocation table size + p = buf + (BSDHDRSIZE + tds + trsize); // Move obj image ptr to reloc info drsize = bsdmarkimg(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table - chptr = buf + 28; // Point to relocation hdr entry - D_long(drsize); // Write the relocation table size + chptr = buf + 28; // Point to relocation hdr entry + D_long(drsize); // Write the relocation table size p = buf + (BSDHDRSIZE + tds + trsize + drsize);// Point to start of symbol table - sy_assign(p, constr_bsdsymtab); // Build symbol and string tables - chptr = buf + 16; // Point to sym table size hdr entry - D_long(symsize); // Write the symbol table size + sy_assign(p, constr_bsdsymtab); // Build symbol and string tables + chptr = buf + 16; // Point to sym table size hdr entry + D_long(symsize); // Write the symbol table size // Point to string table p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize); - memcpy(p, strtable, strindx); // Copy string table to object image + memcpy(p, strtable, strindx); // Copy string table to object image if (buf) - free(strtable); // Free allocated memory + free(strtable); // Free allocated memory - chptr = p; // Point to string table size long - D_long(strindx); // Write string table size + chptr = p; // Point to string table size long + D_long(strindx); // Write string table size // Write the BSD object file from the object image buffer unused = write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4); if (buf) - free(buf); // Free allocated memory + free(buf); // Free allocated memory break; } diff --git a/procln.c b/procln.c index b56b254..e851408 100644 --- a/procln.c +++ b/procln.c @@ -450,9 +450,9 @@ checking to see if it's already been equated, issue a warning. // What needs to happen here is to prime registerbank with regbank, then use // registerbank down below for the bank marking. #warning "!!! regbank <-> registerbank confusion here !!!" -// The question here is why, if we're allowed to override the ".regbankN" rules above, -// then why is it using the one set by the directive in the extended attributes and -// not in what ends up in symbol->svalue? +// The question here is why, if we're allowed to override the ".regbankN" rules +// above, then why is it using the one set by the directive in the extended +// attributes and not in what ends up in symbol->svalue? // ".regbankN" is not an original Madmac directive, so it's suspect sy->sattre |= regbank; // Store register bank #endif @@ -546,13 +546,13 @@ checking to see if it's already been equated, issue a warning. goto loop; } - sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes + sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes sy->svalue = eval; - if (list_flag) // Put value in listing + if (list_flag) // Put value in listing listvalue(eval); - at_eol(); // Must be at EOL now + at_eol(); // Must be at EOL now goto loop; } diff --git a/riscasm.c b/riscasm.c index e55a986..5292555 100644 --- a/riscasm.c +++ b/riscasm.c @@ -161,8 +161,6 @@ int GetRegister(WORD rattr) // Evaluate what's in the global "tok" buffer if (expr(r_expr, &eval, &eattr, &esym) != OK) - // Hmm, the evaluator should report the error to us... -// return MalformedOpcode(0x00); return ERROR; if ((challoc - ch_size) < 4) diff --git a/token.c b/token.c index 4039c8e..6ba200c 100644 --- a/token.c +++ b/token.c @@ -1008,12 +1008,12 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); if (c & STSYM) { - if (stuffnull) // Terminate old symbol from previous pass + if (stuffnull) // Terminate old symbol from previous pass *nullspot = EOS; - v = 0; // Assume no DOT attrib follows symbol + v = 0; // Assume no DOT attrib follows symbol stuffnull = 1; - p = nullspot = ln++; // Nullspot -> start of this symbol + p = nullspot = ln++; // Nullspot -> start of this symbol // Find end of symbol (and compute its length) for(j=1; (int)chrtab[*ln]&CTSYM; j++) @@ -1023,8 +1023,8 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); // symbol or keyword: if (*ln == '.') { - *ln++ = EOS; // Terminate symbol - stuffnull = 0; // And never try it again + *ln++ = EOS; // Terminate symbol + stuffnull = 0; // And never try it again // Character following the `.' must have a DOT attribute, and // the chararacter after THAT one must not have a start-symbol @@ -1085,7 +1085,6 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); case 120: // time case 121: // date j = -1; -// break; } // If not tokenized keyword OR token was not found @@ -1093,8 +1092,8 @@ if (verb_flag) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n"); { *tk++ = SYMBOL; //#warning -//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit system, -//this will cause all kinds of mischief. +//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit +//system, this will cause all kinds of mischief. #if 0 *tk++ = (TOKEN)nullspot; #else @@ -1493,11 +1492,8 @@ goteol: //int d_goto(void) int d_goto(WORD unused) { -// char * sym; // Label to search for -// LONG * defln; // Macro definition strings - char * s1; // Temps for string comparison + char * s1; // Temps for string comparison char * s2; -// IMACRO * imacro; // Macro invocation block // Setup for the search if (*tok != SYMBOL) diff --git a/version.h b/version.h index b49b4ae..284abe9 100644 --- a/version.h +++ b/version.h @@ -13,6 +13,6 @@ #define MAJOR 1 // Major version number #define MINOR 3 // Minor version number -#define PATCH 0 // Patch release number +#define PATCH 1 // Patch release number #endif // __VERSION_H__ -- 2.37.2