Pristine Ack-5.5
[Ack-5.5.git] / util / ceg / ce_back / obj_back / output.c
1 #include <system.h>
2 #include <alloc.h>
3 #include <out.h>
4 #include "mach.h"
5 #include "back.h"
6
7 static reduce_name_table();
8 static convert_outname();
9
10 static int nrelo;
11
12 output_back()
13 /* Dump the tables.
14  * Notice : entries in the symbol_table are converted.
15  */
16
17 {
18         struct outhead header;
19         struct outsect sect;
20         long    ntext = text - text_area, 
21                 ndata = data - data_area,
22                 nchar;
23
24         nrelo = relo - reloc_info;
25
26         reduce_name_table();
27
28         nchar = string - string_area;
29         header.oh_magic = O_MAGIC;
30         header.oh_stamp = 0;
31         header.oh_flags = HF_LINK;
32         header.oh_nsect = 4;
33         header.oh_nrelo = nrelo;
34         header.oh_nname = nname;
35         header.oh_nemit = ntext + ndata;
36         header.oh_nchar = nchar;
37
38         wr_ohead( &header);
39
40         sect.os_base = 20;
41         sect.os_size = ntext;
42         sect.os_foff = OFF_EMIT( header);
43         sect.os_flen = ntext;
44         sect.os_lign = 1;
45
46         wr_sect( &sect, 1);
47
48         sect.os_base = 20 + ntext;
49         sect.os_size = 0;
50         sect.os_foff = OFF_EMIT( header) + ntext;
51         sect.os_flen = 0;
52         sect.os_lign = 1;
53
54         wr_sect( &sect, 1);
55
56         sect.os_base = 20 + ntext;
57         sect.os_size = ndata;
58         sect.os_foff = OFF_EMIT( header) + ntext;
59         sect.os_flen = ndata;
60         sect.os_lign = 1;
61
62         wr_sect( &sect, 1);
63
64         sect.os_base = 20 + ntext + ndata;
65         sect.os_size = nbss;
66         sect.os_foff = OFF_EMIT( header) + ntext + ndata;
67         sect.os_flen = 0;
68         sect.os_lign = 1;
69
70         wr_sect( &sect, 1);
71
72         wr_outsect( 0);
73         wr_emit( text_area, ntext);
74         wr_outsect( 2);
75         wr_emit( data_area, ndata);
76
77         wr_relo( reloc_info, nrelo);
78
79         convert_outname( &header);        
80         wr_name( symbol_table, nname);
81
82         wr_string( string_area, nchar);
83 }
84
85 static
86 reduce_name_table()
87 {
88         /*
89          * Reduce the name table size. This is done by first marking
90          * the name-table entries that are needed for relocation, then
91          * removing the entries that are compiler-generated and not
92          * needed for relocation, while remembering how many entries were
93          * removed at each point, and then updating the relocation info.
94          * After that, the string table is reduced.
95          */
96
97 #define S_NEEDED S_MOD
98 #define removable(nm)   (!(nm->on_type & (S_NEEDED|S_STB)) && *(nm->on_foff+string_area) == GENLAB)
99
100         register int *diff_index =
101                 (int *) Malloc((unsigned)(nname + 1) * sizeof(int));
102         register struct outrelo *rp = reloc_info;
103         register struct outname *np;
104         register int i;
105         char *new_str;
106         register char *p, *q;
107
108         *diff_index++ = 0;
109         for (i = 0; i < nrelo; i++) {
110                 if (symbol_table[rp->or_nami].on_valu == -1 ||
111                     (symbol_table[rp->or_nami].on_type & S_COM)) {
112                         symbol_table[rp->or_nami].on_type |= S_NEEDED;
113                 }
114                 rp++;
115         }
116
117         for (i = 0, np = symbol_table; i < nname; i++, np++) {
118                 diff_index[i] = diff_index[i-1];
119                 if (removable(np)) {
120                         diff_index[i]++;
121                 }
122                 if ((np->on_type & S_TYP) == S_CRS) {
123                         struct outname *n = &symbol_table[(int) np->on_valu];
124                         if (! (n->on_type & S_COM)) {
125                                 np->on_type &= ~S_TYP;
126                                 np->on_type |= (n->on_type & S_TYP);
127                                 np->on_valu = n->on_valu;
128                         }
129                 }
130         }
131
132         rp = reloc_info;
133         for (i = 0; i < nrelo; i++) {
134                 symbol_table[rp->or_nami].on_type &= ~S_NEEDED;
135                 rp->or_nami -= diff_index[rp->or_nami];
136                 rp++;
137         }
138         for (i = 0, np = symbol_table; i < nname; i++, np++) {
139                 if ((np->on_type & S_TYP) == S_CRS) {
140                         np->on_valu -= diff_index[(int) np->on_valu];
141                 }
142                 if (diff_index[i] && diff_index[i] == diff_index[i-1]) {
143                         symbol_table[i - diff_index[i]] = *np;
144                 }
145         }
146         nname -= diff_index[nname - 1];
147
148         free((char *)(diff_index-1));
149
150         new_str = q = Malloc((unsigned)(string - string_area));
151         for (i = 0, np = symbol_table; i < nname; i++, np++) {
152                 p = np->on_foff + string_area;
153                 np->on_foff = q - new_str;
154                 while (*q++ = *p) p++;
155         }
156         free(string_area);
157         string_area = new_str;
158         string = q;
159         for (i = 0, np = symbol_table; i < nname; i++, np++) {
160                 if ((np->on_type & S_TYP) == S_CRS) {
161                         /* replace by reference to string */
162                         np->on_valu = symbol_table[(int) np->on_valu].on_foff;
163                 }
164         }
165 }
166
167 wr_fatal()
168 {
169         fprint( STDERR, "write failed\n");
170         sys_stop(S_ABORT);
171 }
172
173
174 static
175 convert_outname( header)
176 struct outhead *header;
177 {
178         int i;
179         register struct outname *np;
180         register long l = OFF_CHAR(*header);
181
182         for (i = 0, np = symbol_table; i < nname; i++, np++) {
183                 np->on_foff += l;
184                 if ((np->on_type & S_TYP) == S_CRS) {
185                         np->on_valu += l;
186                 }
187         }
188 }