]> Shamusworld >> Repos - rmac/blobdiff - object.c
Fix a small buglet in the last patch. :-)
[rmac] / object.c
index 395526e0ff1259c18753d2268255ab941571634d..0b7df7ed8ecc77b1d7bb2eb1ad9ad26b6319821b 100644 (file)
--- a/object.c
+++ b/object.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for all Atari computers
 // OBJECT.C - Writing Object Files
-// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -124,7 +124,8 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag)
                w |= AL_EXTERN | AL_GLOBAL;     // Common symbol
                w &= ~AL_BSS;           // They're not BSS in Alcyon object files
        }
-       else if (w1 & DEFINED)
+
+       if (w1 & DEFINED)
        {
                if (globflag)           // Export the symbol
                        w |= AL_GLOBAL;
@@ -172,14 +173,16 @@ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
        {
                z = 0x02000000;                                 // Set equated flag
        }
-       else
+
+       // If a symbol is both EQUd and flagged as TBD then we let
+       // the later take precedence. Otherwise the linker will not even
+       // bother trying to relocate the address during link time
+
+       switch (w1 & TDB)
        {
-               switch (w1 & TDB)
-               {
-               case TEXT: z = 0x04000000; break;       // Set TEXT segment flag
-               case DATA: z = 0x06000000; break;       // Set DATA segment flag
-               case BSS : z = 0x08000000; break;       // Set BSS segment flag
-               }
+       case TEXT: z = 0x04000000; break;       // Set TEXT segment flag
+       case DATA: z = 0x06000000; break;       // Set DATA segment flag
+       case BSS : z = 0x08000000; break;       // Set BSS segment flag
        }
 
        if (globflag)
@@ -218,12 +221,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
 
        register WORD w1 = sym->sattr;
 
-       if (w1 & COMMON)
-       {
-               //w |= AL_EXTERN | AL_GLOBAL;   // common symbol
-               //w &= ~AL_BSS;         // they're not BSS in Alcyon object files
-       }
-       else if (w1 & DEFINED)
+       if (w1 & DEFINED)
        {
                if (globflag)           // Export the symbol
                        st_info |= 16;   //STB_GLOBAL (1<<4)
@@ -331,7 +329,9 @@ int WriteObject(int fd)
 
        // Write requested object file...
        if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0)))
-    {
+       {
+               ch_size = 0;
+
                // Force BSD format (if it was ALCYON format)
                obj_format = BSD;
 
@@ -429,6 +429,8 @@ int WriteObject(int fd)
        }
        else if (obj_format == ALCYON)
        {
+               ch_size = 0;
+
                if (verb_flag)
                {
                        if (prg_flag)
@@ -439,6 +441,7 @@ int WriteObject(int fd)
 
                // Assign index numbers to the symbols, get # of symbols (we assume
                // that all symbols can potentially be extended, hence the x28)
+               // (To clarify: 28 bytes is the size of an extended symbol)
                uint32_t symbolMaxSize = sy_assign(NULL, NULL) * 28;
 
                // Alloc memory for header + text + data, symbol and relocation
@@ -811,13 +814,52 @@ for(int j=0; j<i; j++)
                else
                        WriteP56();
 
-               // Write all the things |o/
+               // Write all the things \o/
                unused = write(fd, buf, chptr - buf);
 
                if (buf)
                        free(buf);
        }
+       else if (obj_format == RAW)
+       {
+               if (!org68k_active)
+               {
+                       return error("cannot output absolute binary without a starting address (.org or command line)");
+               }
+
+               // Alloc memory for text + data construction.
+               tds = sect[TEXT].sloc + sect[DATA].sloc;
+               buf = malloc(tds);
+               chptr = buf;
+
+               // Construct text and data segments; fixup relocatable longs;
+               // finally write the text + data
 
+               p = buf;
+               objImage = buf;                                 // Set global object image pointer
+
+               for (i = TEXT; i <= DATA; i++)
+               {
+                       for (cp = sect[i].sfcode; cp != NULL; cp = cp->chnext)
+                       {
+                               memcpy(p, cp->chptr, cp->ch_size);
+                               p += cp->ch_size;
+                       }
+               }
+
+               if (MarkABSImage(buf, tds, sect[TEXT].sloc, TEXT) != OK)  // Do TEXT relocation table
+               {
+                       return ERROR;
+               }
+               if (MarkABSImage(buf, tds, sect[TEXT].sloc, DATA) != OK) // Do DATA relocation table
+               {
+                       return ERROR;
+               }
+
+               // Write out the header + text & data + symbol table (if any)
+               unused = write(fd, buf, tds);
+
+       }
        return 0;
 }