]> Shamusworld >> Repos - rmac/blob - object.c
1608edeb09bc3a3ef41d486c76b92fa779b90828
[rmac] / object.c
1 //
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // OBJECT.C - Writing Object Files
4 // Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source Utilised with the Kind Permission of Landon Dyer
7 //
8
9 #include "object.h"
10 #include "sect.h"
11 #include "symbol.h"
12 #include "mark.h"
13 #include "error.h"
14 #include "risca.h"
15
16 LONG symsize = 0;                                           // Size of BSD symbol table
17 LONG strindx = 0x00000004;                                  // BSD string table index
18 char *strtable;                                             // Pointer to the symbol string table
19 char *objimage;                                             // Global object image pointer
20
21 //
22 // --- Add an entry to the BSD symbol table --------------------------------------------------------
23 //
24
25 char *constr_bsdsymtab(char *buf, SYM *sym, int globflag) {
26    LONG z;                                                  // Scratch long
27    WORD w1;                                                 // Scratch word
28    int w2;                                                  // Scratch long
29    
30    chptr = buf;                                             // Point to buffer for deposit longs
31    D_long(strindx);                                         // Deposit the symbol string index
32
33    w1 = sym->sattr;                                         // Obtain symbol attribute
34    w2 = sym->sattre;
35    z = 0;                                                   // Initialise resulting symbol flags
36    if(w1 & EQUATED) {                                       
37       z = 0x02000000;                                       // Set equated flag
38    } else {
39       switch(w1 & TDB) {
40          case TEXT: z = 0x04000000; break;                  // Set TEXT segment flag
41          case DATA: z = 0x06000000; break;                  // Set DATA segment flag
42          case BSS : z = 0x08000000; break;                  // Set BSS segment flag
43       }
44    }
45    if(globflag) z |= 0x01000000;                            // Set global flag if requested
46    D_long(z);                                               // Deposit symbol attribute
47
48    z = sym->svalue;                                         // Obtain symbol value
49    w1 &= DATA|BSS;                                          // Determine DATA or BSS flag
50    if(w1)                                                   
51       z += sect[TEXT].sloc;                                 // If DATA or BSS add TEXT segment size
52    if(w1 & BSS) 
53       z += sect[DATA].sloc;                                 // If BSS add DATA segment size
54    D_long(z);                                               // Deposit symbol value
55
56    strcpy(strtable + strindx, sym->sname);
57
58    strindx += strlen(sym->sname) + 1;                       // Incr string index incl null terminate
59    buf += 12;                                               // Increment buffer to next record
60    symsize += 12;                                           // Increment symbol table size
61
62    return(buf);
63 }
64
65 //
66 // --- Generate object file ------------------------------------------------------------------------
67 //
68
69 int object(WORD fd) {
70    LONG t;                                                  // Scratch long
71    LONG tds;                                                // TEXT & DATA segment size
72    int i;                                                   // Temporary int
73    CHUNK *cp;                                               // Chunk (for gather)
74    char *buf;                                               // Scratch area
75    char *p;                                                 // Temporary ptr
76    LONG ssize;                                              // Size of symbols
77    LONG trsize, drsize;                                     // Size of relocations
78
79    // Write requested object file...
80    switch(obj_format) {
81       case BSD:
82          ssize = ((LONG)sy_assign(NULL, NULL));             // Assign index numbers to the symbols
83          tds = sect[TEXT].sloc + sect[DATA].sloc;           // Get size of TEXT and DATA segment
84          buf = malloc(0x400000);                            // Allocate 4mb object file image memory
85          if(buf == NULL) {
86             error("cannot allocate object file memory (in BSD mode)");
87             return(ERROR);
88          }
89          memset(buf, 0, 0x400000);                          // Reset allocated memory
90          objimage = buf;                                    // Set global object image pointer
91          strtable = malloc(0x200000);                       // Allocate 2mb scratch buffer 
92          if(strtable == NULL) {
93             error("cannot allocate string table memory (in BSD mode)");
94             return(ERROR);
95          }
96          memset(strtable, 0, 0x200000);                     // Reset allocated memory
97
98          // Build object file header
99          chptr = buf;                                       // Base of header
100          t = 0x00000107;
101          D_long(t);                                         // Magic number
102          t = sect[TEXT].sloc;                               // TEXT size 
103          D_long(t);
104          t = sect[DATA].sloc;                               // DATA size 
105          D_long(t);
106          t = sect[BSS].sloc;                                // BSS size 
107          D_long(t);
108          t = 0x00000000;
109          D_long(t);                                         // Symbol size
110          D_long(t);                                         // First entry (0L)
111          D_long(t);                                         // TEXT relocation size
112          D_long(t);                                         // BSD relocation size
113
114          // Construct TEXT and DATA segments (without relocation changes)
115          p = buf + BSDHDRSIZE;
116          for(i = TEXT; i <= DATA; ++i)
117             for(cp = sect[i].sfcode; cp != NULL; cp = cp->chnext) {
118                copy(p, cp->chptr, cp->ch_size);
119                p += cp->ch_size;
120             }
121
122          // Do relocation tables (and make changes to segment data)
123          p = buf + (BSDHDRSIZE + tds);                      // Move obj image ptr to reloc info
124          trsize = bsdmarkimg(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table
125          chptr = buf + 24;                                  // Point to relocation hdr entry
126          D_long(trsize);                                    // Write the relocation table size
127          p = buf + (BSDHDRSIZE + tds + trsize);             // Move obj image ptr to reloc info
128          drsize = bsdmarkimg(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table
129          chptr = buf + 28;                                  // Point to relocation hdr entry
130          D_long(drsize);                                    // Write the relocation table size
131
132          p = buf + (BSDHDRSIZE + tds + trsize + drsize);    // Point to start of symbol table
133          sy_assign(p, constr_bsdsymtab);                    // Build symbol and string tables
134          chptr = buf + 16;                                  // Point to sym table size hdr entry
135          D_long(symsize);                                   // Write the symbol table size
136
137          // Point to string table
138          p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize);    
139
140          memcpy(p, strtable, strindx);                      // Copy string table to object image
141          if(buf) free(strtable);                            // Free allocated memory
142          chptr = p;                                         // Point to string table size long
143          D_long(strindx);                                   // Write string table size
144
145          // Write the BSD object file from the object image buffer
146          write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4);
147
148          if(buf) free(buf);                                 // Free allocated memory
149          break;
150    }
151
152    return(0);
153 }
154
155
156
157
158
159