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
19 extern int obj_format; // object file format to write
20 extern int prg_flag; // generate Atari ST direct executable
22 LONG symsize = 0; // Size of BSD symbol table
23 LONG strindx = 0x00000004; // BSD string table index
24 char * strtable; // Pointer to the symbol string table
25 char * objImage; // Global object image pointer
29 // Add an entry to the BSD symbol table
31 char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
33 chptr = buf; // Point to buffer for deposit longs
34 D_long(strindx); // Deposit the symbol string index
36 WORD w1 = sym->sattr; // Obtain symbol attribute
38 LONG z = 0; // Initialise resulting symbol flags
42 z = 0x02000000; // Set equated flag
48 case TEXT: z = 0x04000000; break; // Set TEXT segment flag
49 case DATA: z = 0x06000000; break; // Set DATA segment flag
50 case BSS : z = 0x08000000; break; // Set BSS segment flag
55 z |= 0x01000000; // Set global flag if requested
57 D_long(z); // Deposit symbol attribute
59 z = sym->svalue; // Obtain symbol value
60 w1 &= DATA | BSS; // Determine DATA or BSS flag
63 z += sect[TEXT].sloc; // If DATA or BSS add TEXT segment size
66 z += sect[DATA].sloc; // If BSS add DATA segment size
68 D_long(z); // Deposit symbol value
70 strcpy(strtable + strindx, sym->sname);
72 strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate
73 buf += 12; // Increment buffer to next record
74 symsize += 12; // Increment symbol table size
83 #define AL_DEFINED 0x8000
84 #define AL_EQUATED 0x4000
85 #define AL_GLOBAL 0x2000
86 #define AL_EQUREG 0x1000
87 #define AL_EXTERN 0x0800
88 #define AL_DATA 0x0400
89 #define AL_TEXT 0x0200
91 #define AL_FILE 0x0080
94 static WORD tdb_tab[] = {
96 AL_TEXT, /* TEXT segment based */
97 AL_DATA, 0, /* DATA segment based */
98 AL_BSS /* BSS segment based */
102 #define HDRSIZE 0x1C /* size of Alcyon header */
106 * Add entry to symbol table;
107 * if `globflag' is 1, make the symbol global;
108 * if in .PRG mode, adjust symbol values for fake link.
111 char * constr_symtab(register char * buf, SYM * sym, int globflag)
124 for(i=0; i<8 && *s; i++)
131 * Construct and deposit flag word
133 * o all symbols are AL_DEFINED
134 * o install T/D/B/A base
135 * o install 'equated'
136 * o commons (COMMON) are AL_EXTERN, but not BSS
137 * o exports (DEFINED) are AL_GLOBAL
138 * o imports (~DEFINED) are AL_EXTERN
142 w = AL_DEFINED | tdb_tab[w1 & TDB];
144 if (w1 & EQUATED) /* equated */
149 w |= AL_EXTERN | AL_GLOBAL; /* common symbol */
150 w &= ~AL_BSS; /* they're not BSS in Alcyon object files */
152 else if (w1 & DEFINED)
154 if (globflag) /* export the symbol */
157 else w |= AL_EXTERN; /* imported symbol */
164 if (prg_flag) /* relocate value in .PRG segment */
169 z += sect[TEXT].sloc;
172 z += sect[DATA].sloc;
175 *buf++ = z >> 24; /* deposit symbol value */
185 // Write an object file to the passed in file descriptor
186 // N.B.: Return value is ignored...
188 int WriteObject(int fd)
190 // LONG t; // Scratch long
191 LONG tds; // TEXT & DATA segment size
192 int i; // Temporary int
193 CHUNK * cp; // Chunk (for gather)
194 char * buf; // Scratch area
195 char * p; // Temporary ptr
196 LONG ssize; // Size of symbols
197 LONG trsize, drsize; // Size of relocations
198 long unused; // For supressing 'write' warnings
200 // Write requested object file...
204 ssize = ((LONG)sy_assign(NULL, NULL)); // Assign index numbers to the symbols
205 tds = sect[TEXT].sloc + sect[DATA].sloc; // Get size of TEXT and DATA segment
206 buf = malloc(0x600000); // Allocate 6mb object file image memory
210 error("cannot allocate object file memory (in BSD mode)");
214 memset(buf, 0, 0x600000); // Reset allocated memory
215 objImage = buf; // Set global object image pointer
216 strtable = malloc(0x200000); // Allocate 2mb scratch buffer
218 if (strtable == NULL)
220 error("cannot allocate string table memory (in BSD mode)");
224 memset(strtable, 0, 0x200000); // Reset allocated memory
226 // Build object file header
227 chptr = buf; // Base of header
228 D_long(0x00000107); // Magic number
229 D_long(sect[TEXT].sloc); // TEXT size
230 D_long(sect[DATA].sloc); // DATA size
231 D_long(sect[BSS].sloc); // BSS size
232 D_long(0x00000000); // Symbol size
233 D_long(0x00000000); // First entry (0L)
234 D_long(0x00000000); // TEXT relocation size
235 D_long(0x00000000); // BSD relocation size
237 // Construct TEXT and DATA segments (without relocation changes)
238 p = buf + BSDHDRSIZE;
240 for(i=TEXT; i<=DATA; ++i)
242 for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
244 memcpy(p, cp->chptr, cp->ch_size);
249 // Do relocation tables (and make changes to segment data)
250 p = buf + (BSDHDRSIZE + tds); // Move obj image ptr to reloc info
251 trsize = bsdmarkimg(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table
252 chptr = buf + 24; // Point to relocation hdr entry
253 D_long(trsize); // Write the relocation table size
254 p = buf + (BSDHDRSIZE + tds + trsize); // Move obj image ptr to reloc info
255 drsize = bsdmarkimg(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table
256 chptr = buf + 28; // Point to relocation hdr entry
257 D_long(drsize); // Write the relocation table size
259 p = buf + (BSDHDRSIZE + tds + trsize + drsize);// Point to start of symbol table
260 sy_assign(p, constr_bsdsymtab); // Build symbol and string tables
261 chptr = buf + 16; // Point to sym table size hdr entry
262 D_long(symsize); // Write the symbol table size
264 // Point to string table
265 p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize);
267 memcpy(p, strtable, strindx); // Copy string table to object image
270 free(strtable); // Free allocated memory
272 chptr = p; // Point to string table size long
273 D_long(strindx); // Write string table size
275 // Write the BSD object file from the object image buffer
276 unused = write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4);
279 free(buf); // Free allocated memory
285 * Compute size of symbol table;
286 * assign numbers to the symbols...
291 ssize = ((LONG)sy_assign(NULL, NULL)) * 14;
294 * Alloc memory for header+text+data, symbol and
295 * relocation information construction.
297 t = tds = sect[TEXT].sloc + sect[DATA].sloc;
302 buf = malloc((t + HDRSIZE) + HDRSIZE);
305 * Build object file header
306 * just before the text+data image
308 chptr = buf - HDRSIZE; /* -> base of header */
309 D_word(0x601a); /* magic number */
310 t = sect[TEXT].sloc; /* TEXT size */
312 t = sect[DATA].sloc; /* DATA size */
314 t = sect[BSS].sloc; /* BSS size */
316 D_long(ssize); /* symbol table size */
317 D_long(0); /* stack size (unused) */
318 D_long(0); /* entry point (unused) */
319 D_word(0); /* relocation information exists */
322 * Construct text and data segments;
323 * fixup relocatable longs in .PRG mode;
324 * finally write the header+text+data
328 for(i=TEXT; i<=DATA; i++)
330 for (cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
332 memcpy(p, cp->chptr, cp->ch_size);
338 markimg(buf, tds, sect[TEXT].sloc, 0);
340 write(fd, buf - HDRSIZE, tds + HDRSIZE);
343 * Construct and write symbol table
347 sy_assign(buf, constr_symtab);
348 write(fd, buf, ssize);
352 * Construct and write relocation information;
353 * the size of it changes if we're writing a RELMODed executable.
355 tds = markimg(buf, tds, sect[TEXT].sloc, 1);