Patch to fix lack of WORD sized symbol relocations by SainT.
authorShamus Hammons <jlhamm@acm.org>
Wed, 4 Oct 2017 16:25:45 +0000 (11:25 -0500)
committerShamus Hammons <jlhamm@acm.org>
Wed, 4 Oct 2017 16:25:45 +0000 (11:25 -0500)
Version now at 1.8.7.

mach.c
mark.c
version.h

diff --git a/mach.c b/mach.c
index 747300228ba04432e0cad285c2480562c4f2a32e..e01ea88599b6ab892f2364c3291f7aefa473927e 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -1251,7 +1251,6 @@ int m_br30(WORD inst, WORD siz)
 //
 int m_bfop(WORD inst, WORD siz)
 {
-
     if ((bfval1 > 31) || (bfval1 < 0))
         return error("bfxxx offset: immediate value must be between 0 and 31");
 
diff --git a/mark.c b/mark.c
index 7495c71c1eeecf571b26b7031dba32ae97495495..955fcab0c7a81d0535c4e06b625be8dab1fae07a 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -377,6 +377,12 @@ printf(" validsegment: raddr = $%08X\n", loc);
                        if (w & MMOVEI)
                                rflag |= 0x00000001;
 
+                       // This tells the linker to do a WORD relocation (otherwise it
+                       // defaults to doing a LONG, throwing things off for WORD sized
+                       // fixups)
+                       if (!(w & MLONG))
+                               rflag |= 0x00000002;
+
                        if (symbol != NULL)
                        {
                                // Deposit external reference
@@ -414,7 +420,7 @@ printf("  validsegment(3): rflag = $%08X\n", rflag);
                                        if (from == DATA)
                                                dp += tsize;
 
-                                       uint32_t diff = GETBE32(dp, 0);
+                                       uint32_t diff = (rflag & 0x02 ? GETBE16(dp, 0) : GETBE32(dp, 0));
                                        DEBUG printf("diff=%uX ==> ", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(4): diff = $%08X --> ", diff);
@@ -430,7 +436,21 @@ printf("  validsegment(4): diff = $%08X --> ", diff);
                                        if (rflag & 0x01)
                                                diff = WORDSWAP32(diff);
 
-                                       SETBE32(dp, 0, diff);
+                                       // Make sure to deposit the correct size payload
+                                       // N.B.: The braces around the SETBExx macros are needed
+                                       //       because the macro supplies its own set of braces,
+                                       //       thus leaving a naked semicolon afterwards to
+                                       //       screw up the if/else structure. This is the price
+                                       //       you pay when using macros pretending to be code.
+                                       if (rflag & 0x02)
+                                       {
+                                               SETBE16(dp, 0, diff);
+                                       }
+                                       else
+                                       {
+                                               SETBE32(dp, 0, diff);
+                                       }
+
                                        DEBUG printf("%uX\n", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("$%08X\n", diff);
index d5f4427d29478dba2a152b62f5982111d6d208f9..b5e0f1cb0ee3c7cc51e1ec7c267458536f03743f 100644 (file)
--- a/version.h
+++ b/version.h
@@ -15,7 +15,7 @@
 
 #define MAJOR   1              // Major version number
 #define MINOR   8              // Minor version number
-#define PATCH   6              // Patch release number
+#define PATCH   7              // Patch release number
 
 #endif // __VERSION_H__