From: Shamus Hammons Date: Sat, 16 Feb 2013 03:27:29 +0000 (-0600) Subject: Fixed subtle bug in section marking code. X-Git-Tag: 1.3.0~17 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=commitdiff_plain;h=9fb8931331db981c04e062a3ad36c0d79acb30ae;hp=627f87694bf2d7855b8e3cdafe1bf2693f1b60ad Fixed subtle bug in section marking code. Thanks to Linkvitch for helping find this one! Also, found and removed some more 'GPU in Main' cruft hiding out in sect.c. Gone! --- diff --git a/mark.c b/mark.c index 11fde4f..0ca98f0 100644 --- a/mark.c +++ b/mark.c @@ -17,7 +17,10 @@ MCHUNK * curmch; // Current mark chunk PTR markptr; // Deposit point in current mark chunk LONG mcalloc; // #bytes alloc'd to current mark chunk LONG mcused; // #bytes used in current mark chunk -WORD curfrom; // Current "from" section +uint16_t curfrom; // Current "from" section + + +//#define DEBUG_IMAGE_MARKING // @@ -38,8 +41,8 @@ void stopmark(void) { if (curmch) { - *markptr.wp = MCHEND; // Mark end of block - curmch->mcused = mcused; // Update #used in mark block + *markptr.wp = MCHEND; // Mark end of block + curmch->mcused = mcused; // Update #used in mark block } } @@ -47,36 +50,39 @@ void stopmark(void) // // Mark a word or longword relocatable // -int rmark(int from, LONG loc, int to, int size, SYM * symbol) +int rmark(uint16_t from, uint32_t loc, uint16_t to, uint16_t size, SYM * symbol) { - WORD w; +#ifdef DEBUG_IMAGE_MARKING +printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol); +#endif +// uint16_t w; if ((mcalloc - mcused) < MIN_MARK_MEM) amark(); - w = (WORD)(size | to); + uint16_t flags = (size | to); if (from != curfrom) - w |= MCHFROM; + flags |= MCHFROM; if (symbol != NULL) - w |= MSYMBOL; + flags |= MSYMBOL; mcused += sizeof(WORD) + sizeof(LONG); - *markptr.wp++ = w; + *markptr.wp++ = flags; *markptr.lp++ = loc; - if (w & MCHFROM) + if (flags & MCHFROM) { - *markptr.wp++ = (WORD)from; - curfrom = (WORD)from; + curfrom = from; + *markptr.wp++ = from; mcused += sizeof(WORD); } - if (w & MSYMBOL) + if (flags & MSYMBOL) { *markptr.sy++ = symbol; - mcused += sizeof(LONG); + mcused += sizeof(SYM *); } *markptr.wp = 0x0000; @@ -90,18 +96,19 @@ int rmark(int from, LONG loc, int to, int size, SYM * symbol) // int amark(void) { - MCHUNK * p; +// MCHUNK * p; // Alloc mark block header (and data) and set it up. // p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR); - p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR); + MCHUNK * p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR); p->mcnext = NULL; p->mcalloc = MARK_ALLOC_INCR; p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK)); if (curmch) - { // Link onto previous chunk - *markptr.wp++ = MCHEND; // Mark end of block + { + // Link onto previous chunk + *markptr.wp++ = MCHEND; // Mark end of block curmch->mcused = mcused; curmch->mcnext = p; } @@ -109,7 +116,7 @@ int amark(void) if (!firstmch) firstmch = p; - curmch = p; // Setup global vars + curmch = p; // Setup global vars markptr = p->mcptr; mcalloc = MARK_ALLOC_INCR; mcused = 0; @@ -121,53 +128,60 @@ int amark(void) // // Make mark image for BSD .o file // -LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) +uint32_t bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) { - MCHUNK * mch; // Mark chunk - PTR p; // Source point from within mark chunk - WORD from; // Section fixups are currently FROM - WORD w; // A word (temp) - LONG loc; // Location (temp) - SYM * symbol; // Symbols (temp) - char * wp; // Pointer into raw relocation info - char * dp; // Deposit point for RELMOD info - LONG diff; // Difference to relocate (RELMOD) - LONG raddr, rflag = 0; // BSD relocation address and flags - LONG rsize; // Relocation size - int validsegment = 0; // Valid segment being processed - - rsize = 0; // Initialise relocation size + MCHUNK * mch; // Mark chunk + PTR p; // Source point from within mark chunk + uint16_t from; // Section fixups are currently FROM + uint16_t w; // A word (temp) + uint32_t loc; // Location (temp) + SYM * symbol; // Symbols (temp) + uint8_t * wp; // Pointer into raw relocation info + uint8_t * dp; // Deposit point for RELMOD info + uint32_t diff; // Difference to relocate (RELMOD) + uint32_t raddr, rflag = 0; // BSD relocation address and flags + uint32_t rsize; // Relocation size + int validsegment = 0; // Valid segment being processed + +#ifdef DEBUG_IMAGE_MARKING +printf("bsdmarkimg():\n"); +#endif + // Initialise relocation size + rsize = 0; chptr = mp; - from = 0; - for(mch = firstmch; mch != NULL; mch = mch->mcnext) + + for(mch=firstmch; mch!=NULL; mch=mch->mcnext) { for(p=mch->mcptr;;) { - w = *p.wp++; // Next mark entry + w = *p.wp++; // Next mark entry if (w & MCHEND) - break; // End of mark chunk + break; // End of mark chunk // Get mark record symbol = NULL; - loc = *p.lp++; // Mark location + loc = *p.lp++; // Mark location if (w & MCHFROM) - { // Maybe change "from" section + { + // Maybe change "from" section from = *p.wp++; if (obj_format == BSD) { if (reqseg == TEXT) - { // Requested segment is TEXT + { + // Requested segment is TEXT if (from == TEXT) validsegment = 1; else validsegment = 0; } else - { // Requested segment is DATA + { + // Requested segment is DATA if (from == DATA) validsegment = 1; else @@ -176,20 +190,27 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) } } - if (w & MSYMBOL) // Maybe includes a symbol + if (w & MSYMBOL) // Maybe includes a symbol symbol = *p.sy++; if (obj_format == BSD) { - raddr = loc; // Set relocation address + raddr = loc; // Set relocation address if (validsegment) - D_long(raddr); // Write relocation address +#ifdef DEBUG_IMAGE_MARKING +{ +printf(" validsegment: raddr = $%08X\n", raddr); +#endif + D_long(raddr); // Write relocation address +#ifdef DEBUG_IMAGE_MARKING +} +#endif if (w & MPCREL) - rflag = 0x000000A0; // PC-relative fixup + rflag = 0x000000A0; // PC-relative fixup else - rflag = 0x00000040; // Absolute fixup + rflag = 0x00000040; // Absolute fixup if (w & MMOVEI) rflag |= 0x00000001; @@ -200,23 +221,26 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) if (from == DATA) loc += tsize; - wp = (char *)(mp + loc); + wp = (uint8_t *)(mp + loc); if (symbol) { // Deposit external reference if (obj_format == BSD) { - rflag |= 0x00000010; // Set external reloc flag bit - rflag |= (symbol->senv << 8); // Put symbol index in flags + rflag |= 0x00000010; // Set external reloc flag bit + rflag |= (symbol->senv << 8); // Put symbol index in flags if (symbol->sattre & RISCSYM) rflag |= 0x00000001; if (validsegment) { - D_long(rflag); // Write relocation flags - rsize += 8; // Increment relocation size +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(2): rflag = $%08X\n", rflag); +#endif + D_long(rflag); // Write relocation flags + rsize += 8; // Increment relocation size } } } @@ -224,7 +248,10 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) { if (obj_format == BSD) { - w &= TDB; // Set reloc flags to segment +#ifdef DEBUG_IMAGE_MARKING +printf(" w = $%04X\n", w); +#endif + w &= TDB; // Set reloc flags to segment switch (w) { @@ -235,8 +262,11 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) if (validsegment) { - D_long(rflag); // Write relocation flags - rsize += 8; // Increment relocation size +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(3): rflag = $%08X\n", rflag); +#endif + D_long(rflag); // Write relocation flags + rsize += 8; // Increment relocation size } w &= TDB; @@ -251,6 +281,9 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) diff |= ((LONG)(*dp++ & 0xFF)) << 8; diff |= (LONG)(*dp & 0xFF); DEBUG printf("diff=%ux ==> ", diff); +#ifdef DEBUG_IMAGE_MARKING +printf(" validsegment(4): diff = $%08X --> ", diff); +#endif if (rflag & 0x01) diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000); @@ -269,6 +302,9 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) *dp++ = (char)(diff >> 8); *dp = (char)diff; DEBUG printf("%ux\n", diff); +#ifdef DEBUG_IMAGE_MARKING +printf("$%08X\n", diff); +#endif } } } @@ -278,7 +314,14 @@ LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg) // Return relocation size if (obj_format == BSD) +#ifdef DEBUG_IMAGE_MARKING +{ +printf(" rsize = $%X\n", rsize); +#endif return rsize; +#ifdef DEBUG_IMAGE_MARKING +} +#endif return siz; } diff --git a/mark.h b/mark.h index 5e5fe35..d46639a 100644 --- a/mark.h +++ b/mark.h @@ -13,7 +13,7 @@ #include "sect.h" #define MARK_ALLOC_INCR 1024 // # bytes to alloc for more mark space -#define MIN_MARK_MEM (3*sizeof(WORD)+2*sizeof(LONG)) +#define MIN_MARK_MEM (3 * sizeof(WORD) + 2 * sizeof(LONG)) // Globals, Externals etc extern MCHUNK * firstmch; @@ -21,7 +21,8 @@ extern MCHUNK * firstmch; // Prototypes void init_mark(void); void stopmark(void); -int rmark(int, LONG, int, int, SYM *); +//int rmark(int, LONG, int, int, SYM *); +int rmark(uint16_t, uint32_t, uint16_t, uint16_t, SYM *); int amark(void); LONG bsdmarkimg(char *, LONG, LONG, int); diff --git a/risca.c b/risca.c index f5821f5..472e4f1 100644 --- a/risca.c +++ b/risca.c @@ -200,7 +200,6 @@ int GenerateRISCCode(int state) SYM * sy; int i, commaFound; TOKEN * t; - WORD tdb; WORD attrflg; int indexed; // Indexed register flag @@ -344,12 +343,13 @@ int GenerateRISCCode(int state) else { if (eattr & TDB) - rmark(cursect, sloc + 2, tdb, MLONG | MMOVEI, NULL); - } +//{ +//printf("risca: Doing rmark for RI_MOVEI (tdb=$%X)...\n", eattr & TDB); + rmark(cursect, sloc + 2, (eattr & TDB), (MLONG | MMOVEI), NULL); +//} + } -// val = eval; val = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000); -// tok++; // assuming a comma here? tsk tsk CHECK_COMMA; reg2 = GetRegister(FU_REGTWO); at_eol(); diff --git a/rmac.c b/rmac.c index 9afb10a..8dde4c6 100644 --- a/rmac.c +++ b/rmac.c @@ -300,6 +300,7 @@ int rmac_qsort(char * base, int n, int size, int (*compar)()) } +#if 0 // // Allocate memory; Panic and Quit if we Run Out // @@ -337,6 +338,7 @@ char * amem(LONG amount) return p; } +#endif // @@ -851,27 +853,19 @@ int get_endianess(void) // int main(int argc, char ** argv) { - int status; - int i; - perm_verb_flag = 0; // Clobber "permanent" verbose flag cmdlnexec = argv[0]; // Obtain executable name endian = get_endianess(); // Get processor endianess - for(i=0; i 1) { - status = process(argc - 1, argv + 1); - } - else - { - display_version(); - display_help(); + return process(argc - 1, argv + 1); } - return status; + display_version(); + display_help(); + + return 0; } diff --git a/sect.c b/sect.c index f797300..21591a0 100644 --- a/sect.c +++ b/sect.c @@ -38,8 +38,9 @@ LONG fchalloc; // # bytes alloc'd to fixup chunk LONG fchsize; // # bytes used in fixup chunk PTR fchptr; // Deposit point in fixup chunk buffer -unsigned fwdjump[MAXFWDJUMPS]; // forward jump check table -unsigned fwindex = 0; // forward jump index +// BOLLOCKS +//unsigned fwdjump[MAXFWDJUMPS]; // forward jump check table +//unsigned fwindex = 0; // forward jump index // Return a size (SIZB, SIZW, SIZL) or 0, depending on what kind of fixup is // associated with a location. @@ -269,6 +270,7 @@ int fixup(WORD attr, LONG loc, TOKEN * fexpr) CHUNK * cp; SECT * p; // Shamus: Expression lengths are voodoo ATM (varibale "i"). Need to fix this. +#warning "!!! fixup() is filled with VOODOO !!!" DEBUG printf("FIXUP@$%X: $%X\n", loc, attr); // Compute length of expression (could be faster); determine if it's the @@ -385,7 +387,9 @@ int ResolveAllFixups(void) ResolveFixups(TEXT); DEBUG printf("Resolving DATA sections...\n"); ResolveFixups(DATA); - + +//No, no we don't. +#if 0 // We need to do a final check of forward 'jump' destination addresses that // are external for(i=0; i 15)) { @@ -796,6 +799,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); } case FU_LONG: if ((w & 0x0F00) == FU_MOVEI) { +#if 0 address = loc + 4; if (eattr & DEFINED) @@ -845,27 +849,33 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); } } } } +#endif eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000); - flags = (MLONG|MMOVEI); + flags = (MLONG | MMOVEI); } else flags = MLONG; if (!(eattr & DEFINED)) { +//printf("Fixup (long): Symbol undefined. loc = $%X, long = $%X, flags = $%x\n", loc, eval, flags); rmark(sno, loc, 0, flags, esym); } else if (tdb) { +//printf("Fixup (long): TDB = $%X. loc =$%X, long = $%X, flags = $%x\n", tdb, loc, eval, flags); rmark(sno, loc, tdb, flags, NULL); } +//else +//printf("Fixup (long): TDB = $%X. loc =$%X, long = $%X, flags = $%x\n", tdb, loc, eval, flags); *locp++ = (char)(eval >> 24); *locp++ = (char)(eval >> 16); *locp++ = (char)(eval >> 8); *locp = (char)eval; break; + // Fixup a 3-bit "QUICK" reference in bits 9..1 // (range of 1..8) in a word. Really bits 1..3 in a byte. case FU_QUICK: @@ -880,6 +890,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); } *locp |= (eval & 7) << 1; break; + // Fix up 6502 funny branch case FU_6BRA: eval -= (loc + 1); @@ -889,6 +900,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); } *locp = (char)eval; break; + default: interror(4); // Bad fixup type // NOTREACHED @@ -904,3 +916,4 @@ range: return 0; } + diff --git a/sect.h b/sect.h index 7f09d6b..e571191 100644 --- a/sect.h +++ b/sect.h @@ -66,7 +66,7 @@ #define FU_MOVEI 0x0100 #define FU_JR 0x0200 -#define FU_MJR 0x0300 +//#define FU_MJR 0x0300 #define FU_REGONE 0x0400 #define FU_NUM15 0x0500 #define FU_NUM31 0x0600 @@ -120,9 +120,9 @@ MCHUNK { #define MCHEND 0x2000 // Indicates end of mark chunk #define MPCREL 0x1000 // Mark is PC-relative -#define MAXFWDJUMPS 1024 // Maximum forward jumps to check -extern unsigned fwdjump[MAXFWDJUMPS]; -extern unsigned fwindex; +//#define MAXFWDJUMPS 1024 // Maximum forward jumps to check +//extern unsigned fwdjump[MAXFWDJUMPS]; +//extern unsigned fwindex; // Globals, external etc extern LONG sloc;