From 9fb8931331db981c04e062a3ad36c0d79acb30ae Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Fri, 15 Feb 2013 21:27:29 -0600 Subject: [PATCH 1/1] 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! --- mark.c | 153 ++++++++++++++++++++++++++++++++++++-------------------- mark.h | 5 +- risca.c | 10 ++-- rmac.c | 22 +++----- sect.c | 33 ++++++++---- sect.h | 8 +-- 6 files changed, 141 insertions(+), 90 deletions(-) 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; -- 2.37.2