]> Shamusworld >> Repos - rmac/blobdiff - object.c
Version bump for last commit; now at v2.0.21.
[rmac] / object.c
index f100e4ae18fd1a95a8c9fc3e903231fd3c7f614a..fe107434f9c835538a4bbe8dce2a4233d5f1a413 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
 //
@@ -173,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)
@@ -222,7 +224,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
        if (w1 & DEFINED)
        {
                if (globflag)           // Export the symbol
-                       st_info |= 16;   //STB_GLOBAL (1<<4)
+                       st_info |= 16;  // STB_GLOBAL (1<<4)
        }
        else if (w1 & (GLOBAL | REFERENCED))
                st_info |= 16;
@@ -230,7 +232,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
        D_byte(st_info);
        D_byte(0);                              // st_other
 
-       uint16_t st_shndx = 0xFFF1;     // Assume absolute (equated) number
+       uint16_t st_shndx = SHN_ABS;    // Assume absolute (equated) number
 
        if (w1 & TEXT)
                st_shndx = elfHdrNum[ES_TEXT];
@@ -238,8 +240,13 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
                st_shndx = elfHdrNum[ES_DATA];
        else if (w1 & BSS)
                st_shndx = elfHdrNum[ES_BSS];
-       else if (globflag)
-               st_shndx = 0;           // Global, not absolute
+       else if (globflag && !(w1 & DEFINED) && (w1 & REFERENCED))
+       {
+               st_shndx = SHN_UNDEF;
+       }                                      // If the symbol is global then probably we
+                                    // don't need to do anything (probably)
+                                    // since we set STB_GLOBAL in st_info above.
+                                    // Unless we need to set it to SHN_COMMON?
 
        D_word(st_shndx);
 
@@ -327,7 +334,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;
 
@@ -425,6 +434,8 @@ int WriteObject(int fd)
        }
        else if (obj_format == ALCYON)
        {
+               ch_size = 0;
+
                if (verb_flag)
                {
                        if (prg_flag)
@@ -435,6 +446,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
@@ -807,13 +819,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;
 }