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