Fix silly mask bugs, added check for use of undefined register equates.
[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 "riscasm.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 //
23 // Add an entry to the BSD symbol table
24 //
25 char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
26 {
27         LONG z;                                                                 // Scratch long
28         WORD w1;                                                                // Scratch word
29         int w2;                                                                 // Scratch long
30
31         chptr = buf;                                                    // Point to buffer for deposit longs
32         D_long(strindx);                                                // Deposit the symbol string index
33
34         w1 = sym->sattr;                                                // Obtain symbol attribute
35         w2 = sym->sattre;
36         z = 0;                                                                  // Initialise resulting symbol flags
37
38         if (w1 & EQUATED)
39         {                                       
40                 z = 0x02000000;                                         // Set equated flag
41         }
42         else
43         {
44                 switch (w1 & TDB)
45                 {
46                 case TEXT: z = 0x04000000; break;       // Set TEXT segment flag
47                 case DATA: z = 0x06000000; break;       // Set DATA segment flag
48                 case BSS : z = 0x08000000; break;       // Set BSS segment flag
49                 }
50         }
51
52         if (globflag)
53                 z |= 0x01000000;                                        // Set global flag if requested
54
55         D_long(z);                                                              // Deposit symbol attribute
56
57         z = sym->svalue;                                                // Obtain symbol value
58         w1 &= DATA | BSS;                                               // Determine DATA or BSS flag
59
60         if (w1)                                                   
61                 z += sect[TEXT].sloc;                           // If DATA or BSS add TEXT segment size
62
63         if (w1 & BSS) 
64                 z += sect[DATA].sloc;                           // If BSS add DATA segment size
65
66         D_long(z);                                                              // Deposit symbol value
67
68         strcpy(strtable + strindx, sym->sname);
69
70         strindx += strlen(sym->sname) + 1;              // Incr string index incl null terminate
71         buf += 12;                                                              // Increment buffer to next record
72         symsize += 12;                                                  // Increment symbol table size
73
74         return buf;
75 }
76
77
78 //
79 // Generate object file
80 //
81 int object(WORD fd)
82 {
83         LONG t;                                                                 // Scratch long
84         LONG tds;                                                               // TEXT & DATA segment size
85         int i;                                                                  // Temporary int
86         CHUNK * cp;                                                             // Chunk (for gather)
87         char * buf;                                                             // Scratch area
88         char * p;                                                               // Temporary ptr
89         LONG ssize;                                                             // Size of symbols
90         LONG trsize, drsize;                                    // Size of relocations
91
92         // Write requested object file...
93         switch (obj_format)
94         {
95         case BSD:
96                 ssize = ((LONG)sy_assign(NULL, NULL));          // Assign index numbers to the symbols
97                 tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
98                 buf = malloc(0x600000);                                         // Allocate 6mb object file image memory
99
100                 if (buf == NULL)
101                 {
102                         error("cannot allocate object file memory (in BSD mode)");
103                         return ERROR;
104                 }
105
106                 memset(buf, 0, 0x600000);                                       // Reset allocated memory
107                 objimage = buf;                                                         // Set global object image pointer
108                 strtable = malloc(0x200000);                            // Allocate 2mb scratch buffer 
109
110                 if (strtable == NULL)
111                 {
112                         error("cannot allocate string table memory (in BSD mode)");
113                         return ERROR;
114                 }
115
116                 memset(strtable, 0, 0x200000);                          // Reset allocated memory
117
118                 // Build object file header
119                 chptr = buf;                                                            // Base of header
120                 t = 0x00000107;
121                 D_long(t);                                                                      // Magic number
122                 t = sect[TEXT].sloc;                                            // TEXT size 
123                 D_long(t);
124                 t = sect[DATA].sloc;                                            // DATA size 
125                 D_long(t);
126                 t = sect[BSS].sloc;                                                     // BSS size 
127                 D_long(t);
128                 t = 0x00000000;
129                 D_long(t);                                                                      // Symbol size
130                 D_long(t);                                                                      // First entry (0L)
131                 D_long(t);                                                                      // TEXT relocation size
132                 D_long(t);                                                                      // BSD relocation size
133
134                 // Construct TEXT and DATA segments (without relocation changes)
135                 p = buf + BSDHDRSIZE;
136
137                 for(i=TEXT; i<=DATA; ++i)
138                 {
139                         for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
140                         {
141                                 copy(p, cp->chptr, cp->ch_size);
142                                 p += cp->ch_size;
143                         }
144                 }
145
146                 // Do relocation tables (and make changes to segment data)
147                 p = buf + (BSDHDRSIZE + tds);                           // Move obj image ptr to reloc info
148                 trsize = bsdmarkimg(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table
149                 chptr = buf + 24;                                                       // Point to relocation hdr entry
150                 D_long(trsize);                                                         // Write the relocation table size
151                 p = buf + (BSDHDRSIZE + tds + trsize);          // Move obj image ptr to reloc info
152                 drsize = bsdmarkimg(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table
153                 chptr = buf + 28;                                                       // Point to relocation hdr entry
154                 D_long(drsize);                                                         // Write the relocation table size
155
156                 p = buf + (BSDHDRSIZE + tds + trsize + drsize);// Point to start of symbol table
157                 sy_assign(p, constr_bsdsymtab);                         // Build symbol and string tables
158                 chptr = buf + 16;                                                       // Point to sym table size hdr entry
159                 D_long(symsize);                                                        // Write the symbol table size
160
161                 // Point to string table
162                 p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize);    
163
164                 memcpy(p, strtable, strindx);                           // Copy string table to object image
165
166                 if (buf)
167                         free(strtable);                                                 // Free allocated memory
168
169                 chptr = p;                                                                      // Point to string table size long
170                 D_long(strindx);                                                        // Write string table size
171
172                 // Write the BSD object file from the object image buffer
173                 write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4);
174
175                 if (buf)
176                         free(buf);                                                              // Free allocated memory
177
178                 break;
179         }
180
181         return 0;
182 }