Fixed word reversed fixup problem.
[rmac] / mark.c
diff --git a/mark.c b/mark.c
index 11fde4fa35f413215a9877fc9c3370d7bbd27ea2..3b3bd3ada80dd969415089218b95f5b0b59e6e5d 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -9,7 +9,7 @@
 #include "mark.h"
 #include "error.h"
 #include "object.h"
-#include "risca.h"
+#include "riscasm.h"
 
 
 MCHUNK * firstmch;             // First mark chunk
@@ -17,13 +17,16 @@ 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
 
 
 //
 // Initialize Marker
 //
-void init_mark(void)
+void InitMark(void)
 {
        firstmch = curmch = NULL;
        mcalloc = mcused = 0;
@@ -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,40 @@ 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);
+if (symbol)
+       printf("      symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
+#endif
 
        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 +97,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 +117,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 +129,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,23 +191,34 @@ 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
 
+// This flag tells the linker to WORD swap the LONG when doing the fixup.
                                if (w & MMOVEI)
+//{
+//printf("bsdmarkimg: ORing $01 to rflag (MMOVEI) [symbol=%s]...\n", symbol->sname);
                                        rflag |= 0x00000001;
+//}
                        }
 
                        // Compute mark position in relocation information;
@@ -200,23 +226,32 @@ 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
 
+// Looks like this is completely unnecessary (considering it does the wrong thing!)
+#if 0
                                        if (symbol->sattre & RISCSYM)
+{
+printf("bsdmarkimg: ORing $01 to rflag (RISCSYM) [symbol=%s]...\n", symbol->sname);
                                                rflag |= 0x00000001;
+}
+#endif
 
                                        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 +259,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 +273,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 +292,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 +313,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 +325,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;
 }