]> Shamusworld >> Repos - rmac/commitdiff
Fixed subtle bug in section marking code.
authorShamus Hammons <jlhamm@acm.org>
Sat, 16 Feb 2013 03:27:29 +0000 (21:27 -0600)
committerShamus Hammons <jlhamm@acm.org>
Sat, 16 Feb 2013 03:27:29 +0000 (21:27 -0600)
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
mark.h
risca.c
rmac.c
sect.c
sect.h

diff --git a/mark.c b/mark.c
index 11fde4fa35f413215a9877fc9c3370d7bbd27ea2..0ca98f0f033c2e8b6773a3dc3497b0b6507a6bf1 100644 (file)
--- 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 5e5fe358e1f29d79270a3dd11ef7e50c85cc9d08..d46639aae8ed6a5ca2524f1bf45cfb0a73f4502d 100644 (file)
--- 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 f5821f5849fed3064db363f88626efee395d1982..472e4f1e3d1da6b068b0f55959c01bebb53a6b60 100644 (file)
--- 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 9afb10a7cec5fe4714ce55e054cc30a062b16ced..8dde4c6d9a34925a534de81a25cd2c7fb8b8b8b4 100644 (file)
--- 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<MAXFWDJUMPS; i++)
-               fwdjump[i] = 0;
-
-       // Full command line passed
+       // If commands were passed in, process them
        if (argc > 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 f797300395474822bef6688f02c9fabfd8f9846a..21591a0219146b127a7321dbd07dcea4cab0ba1f 100644 (file)
--- 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<MAXFWDJUMPS; i++)
@@ -404,6 +408,7 @@ int ResolveAllFixups(void)
                                printf("%s\n", buf);
                }
        }
+#endif
 
        return 0;
 }
@@ -587,7 +592,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                break;
                        // Fixup one-byte value at locp + 1.
                        case FU_WBYTE:
-                               ++locp;
+                               locp++;
                                // FALLTHROUGH
                        // Fixup one-byte forward references
                        case FU_BYTE:
@@ -620,19 +625,16 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                        // the word could be unaligned in the section buffer, so we have to
                        // be careful.
                        case FU_WORD:
-                               if (((w & 0x0F00) == FU_JR) || ((w & 0x0F00) == FU_MJR))
+                               if ((w & 0x0F00) == FU_JR)// || ((w & 0x0F00) == FU_MJR))
                                {
                                        oaddr = *fup.lp++;
 
                                        if (oaddr)
-                                       {
                                                reg2 = (signed)((eval - (oaddr + 2)) / 2);// & 0x1F;
-                                       }
                                        else
-                                       {
                                                reg2 = (signed)((eval - (loc + 2)) / 2);// & 0x1F;
-                                       }
 
+#if 0
                                        if ((w & 0x0F00) == FU_MJR)
                                        {
                                                // Main code destination alignment checking here for
@@ -669,6 +671,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                        }
                                                }
                                        }
+#endif
 
                                        if ((reg2 < -16) || (reg2 > 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 7f09d6bff314908be0612582c849ffb0ece0d132..e5711911c96408f72cb226c3875081c0a77fcb95 100644 (file)
--- 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;