]> Shamusworld >> Repos - rmac/blobdiff - object.c
Version bump for last commit. :-)
[rmac] / object.c
index 7545866fd8a9f10106aad0adf726715fb0f951d4..6dbf9c525aac300a44cf4127536c99f9c9f044db 100644 (file)
--- a/object.c
+++ b/object.c
@@ -1,7 +1,7 @@
 //
-// RMAC - Reboot's Macro Assembler for all Atari computers
+// RMAC - Renamed Macro Assembler for all Atari computers
 // OBJECT.C - Writing Object Files
-// Copyright (C) 199x Landon Dyer, 2011-2020 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2022 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -62,7 +62,6 @@ See left.             4 & 5   If these bits are set to 0 (PF_PRIVATE), the processes'
 static void WriteLOD(void);
 static void WriteP56(void);
 
-
 //
 // Add entry to symbol table (in ALCYON mode)
 // If 'globflag' is 1, make the symbol global
@@ -157,34 +156,73 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag)
        return buf;
 }
 
-
 //
 // Add an entry to the BSD symbol table
 //
+// From stab.def (https://sites.uclouvain.be/SystInfo/usr/include/bits/stab.def.html):
+/*
+_________________________________________________
+| 00 - 1F are not dbx stab symbols              |
+| In most cases, the low bit is the EXTernal bit|
+
+| 00 UNDEF  | 02 ABS    | 04 TEXT   | 06 DATA   |
+| 01  |EXT  | 03  |EXT  | 05  |EXT  | 07  |EXT  |
+
+| 08 BSS    | 0A INDR   | 0C FN_SEQ | 0E WEAKA  |
+| 09  |EXT  | 0B        | 0D WEAKU  | 0F WEAKT  |
+
+| 10 WEAKD  | 12 COMM   | 14 SETA   | 16 SETT   |
+| 11 WEAKB  | 13        | 15        | 17        |
+
+| 18 SETD   | 1A SETB   | 1C SETV   | 1E WARNING|
+| 19        | 1B        | 1D        | 1F FN     |
+*/
 uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
 {
        chptr = buf;                                            // Point to buffer for depositing longs
-       D_long(strindx);                                        // Deposit the symbol string index
+       if (sym->sname)
+       {
+               D_long(strindx);                                // Deposit the symbol string index
+       }
+    else
+       {
+               D_long(0);                                              // Deposit special NULL string index
+       }
 
        uint16_t w1 = sym->sattr;                       // Obtain symbol attributes
        uint32_t z = 0;                                         // Initialize resulting symbol flags
 
-       if (w1 & EQUATED)
+       if (sym->stype == DBGSYM)
        {
-               z = 0x02000000;                                 // Set equated flag
+               // Debug symbols hard-code the a.out symbol type in the st_type field
+               // and can include additional type-specific data in the a.out symbol
+               // "other" and "description" fields, both packed into this same dword.
+               z = sym->st_type << 24;
+               z |= sym->st_other << 16;
+               z |= sym->st_desc;
        }
        else
        {
+               // Translate rmac symbol attributes to an a.out symbol type.
+               if (w1 & EQUATED)
+               {
+                       z = 0x02000000;                                 // Set equated flag
+               }
+
+               // If a symbol is both EQUd and flagged as TBD then we let the latter
+               // take precedence. Otherwise the linker will not even bother trying to
+               // relocate the address during link time.
+
                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
                }
-       }
 
-       if (globflag)
-               z |= 0x01000000;                                // Set global flag if requested
+               if (globflag)
+                       z |= 0x01000000;                                // Set global flag if requested
+       }
 
        D_long(z);                                                      // Deposit symbol attribute
        z = sym->svalue;                                        // Obtain symbol value
@@ -196,15 +234,17 @@ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
                z += sect[DATA].sloc;                   // If BSS add DATA segment size
 
        D_long(z);                                                      // Deposit symbol value
-       strcpy(strtable + strindx, sym->sname);
-       strindx += strlen(sym->sname) + 1;      // Incr string index incl null terminate
+       if (sym->sname)
+       {
+               strcpy(strtable + strindx, sym->sname);
+               strindx += strlen(sym->sname) + 1;      // Incr string index incl null terminate
+       }
        buf += 12;                                                      // Increment buffer to next record
        symsize += 12;                                          // Increment symbol table size
 
        return buf;
 }
 
-
 //
 // Add entry to ELF symbol table; if `globflag' is 1, make the symbol global
 //
@@ -222,7 +262,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 +270,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 +278,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);
 
@@ -250,7 +295,6 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
        return buf + 0x10;
 }
 
-
 //
 // Helper function for ELF output
 //
@@ -271,7 +315,6 @@ int DepositELFSectionHeader(uint8_t * ptr, uint32_t name, uint32_t type, uint32_
        return 40;
 }
 
-
 //
 // Deposit an entry in the Section Header string table
 //
@@ -286,7 +329,6 @@ printf("DepositELFSHSTEntry: s = \"%s\"\n", s);
        return strSize + 1;
 }
 
-
 //
 // Deposit a symbol table entry in the ELF Symbol Table
 //
@@ -303,7 +345,6 @@ uint32_t DepositELFSymbol(uint8_t * ptr, uint32_t name, uint32_t addr, uint32_t
        return 16;
 }
 
-
 //
 // Write an object file to the passed in file descriptor
 // N.B.: Return value is ignored...
@@ -338,9 +379,9 @@ int WriteObject(int fd)
                        printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                }
 
-               sy_assign(NULL, NULL);                                          // Assign index numbers to the symbols
+               AssignSymbolNos(NULL, NULL);    // Assign index numbers to the symbols
                tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
-               buf = malloc(0x800000);                                         // Allocate 8MB object file image memory
+               buf = malloc(0x800000);                 // Allocate 8MB object file image memory
 
                if (buf == NULL)
                {
@@ -400,7 +441,7 @@ int WriteObject(int fd)
 
                // Point to start of symbol table
                p = buf + BSDHDRSIZE + tds + trsize + drsize;
-               sy_assign(p, AddBSDSymEntry);   // Build symbol and string tables
+               AssignSymbolNos(p, AddBSDSymEntry);     // Build symbol and string tables
                chptr = buf + 0x10;                             // Point to sym table size hdr entry
                D_long(symsize);                                // Write the symbol table size
 
@@ -440,7 +481,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;
+               uint32_t symbolMaxSize = AssignSymbolNos(NULL, NULL) * 28;
 
                // Alloc memory for header + text + data, symbol and relocation
                // information construction.
@@ -480,8 +521,8 @@ int WriteObject(int fd)
                // Construct symbol table and update the header entry, if necessary
                if (prg_flag > 1)
                {
-                       // sy_assign with AddSymEntry updates symsize (stays 0 otherwise)
-                       sy_assign(buf + HDRSIZE + tds, AddSymEntry);
+                       // AssignSymbolNos with AddSymEntry updates symsize (stays 0 otherwise)
+                       AssignSymbolNos(buf + HDRSIZE + tds, AddSymEntry);
                        chptr = buf + 0x0E;                     // Point to symbol table size entry
                        D_long(symsize);
 
@@ -737,7 +778,7 @@ for(int j=0; j<i; j++)
                        extraSyms++;
                }
 
-               int numSymbols = sy_assign_ELF(buf + elfSize, AddELFSymEntry);
+               int numSymbols = AssignSymbolNosELF(buf + elfSize, AddELFSymEntry);
                elfSize += numSymbols * 0x10;
 
                // String table
@@ -790,6 +831,11 @@ for(int j=0; j<i; j++)
                // Just write the object file
                m6502obj(fd);
        }
+       else if (obj_format == C64PRG)
+       {
+               // Just write the object file
+               m6502c64(fd);
+       }
        else if (obj_format == P56 || obj_format == LOD)
        {
                // Allocate 6MB object file image memory
@@ -798,8 +844,6 @@ for(int j=0; j<i; j++)
                if (buf == NULL)
                        return error("cannot allocate object file memory (in P56/LOD mode)");
 
-//             objImage = buf;                                 // Set global object image pointer
-
                memset(buf, 0, 0x600000);               // Clear allocated memory
 
                // Iterate through DSP ram buffers
@@ -820,9 +864,16 @@ for(int j=0; j<i; j++)
        }
        else if (obj_format == RAW)
        {
-               if (!org68k_active)
-               {
+               if (!org68k_active && used_architectures & (!(M6502 | M56001P | M56001X | M56001Y | M56001L)))
                        return error("cannot output absolute binary without a starting address (.org or command line)");
+
+               if (used_architectures & M6502)
+               {
+                       // Okay, this is not the best. But it'll have to do until we revamp things a bit with sections.
+                       // Basically we assume that if raw output is requested and 6502 mode was switched on, nobody
+                       // switched to other architectures. The combination doesn't make much sense anyway for now.
+                       m6502raw(fd);
+                       return 0;
                }
 
                // Alloc memory for text + data construction.
@@ -836,9 +887,9 @@ for(int j=0; j<i; j++)
                p = buf;
                objImage = buf;                                 // Set global object image pointer
 
-               for (i = TEXT; i <= DATA; i++)
+               for(i=TEXT; i<=DATA; i++)
                {
-                       for (cp = sect[i].sfcode; cp != NULL; cp = cp->chnext)
+                       for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
                        {
                                memcpy(p, cp->chptr, cp->ch_size);
                                p += cp->ch_size;
@@ -861,7 +912,6 @@ for(int j=0; j<i; j++)
        return 0;
 }
 
-
 static void WriteLOD(void)
 {
        D_printf("_START %s 0000 0000 0000 RMAC %01i.%01i.%01i\n\n", firstfname, MAJOR, MINOR, PATCH);
@@ -933,7 +983,6 @@ static void WriteLOD(void)
        D_printf("\n_END %.4X\n", dsp_orgmap[0].orgadr);
 }
 
-
 static void WriteP56(void)
 {
        for(DSP_ORG * l=&dsp_orgmap[0]; l<dsp_currentorg; l++)
@@ -999,4 +1048,3 @@ static void WriteP56(void)
                SETBE24(p_buf_len, chunk_size / 3);
        }
 }
-