7 /* Unportable code. Written for SUN, meant to be run on a SUN.
10 Read above comment ...
13 extern File *B_out_file;
18 static struct exec u_header;
20 static long ntext, ndata, nrelo, nchar;
22 long B_base_address[SEGBSS+1];
24 static int trsize=0, drsize=0;
26 static struct relocation_info *u_reloc;
28 static reduce_name_table(), putbuf(), put_stringtablesize();
29 static convert_name(), convert_reloc(), init_unixheader();
34 register struct nlist *u_name;
35 register struct outrelo *rp;
38 * Convert relocation data structures. This also requires
39 * some re-ordering, as SUN .o format needs has text relocation
40 * structures in front of the data relocation structures, whereas in
41 * ACK they can be in any order.
44 nrelo = relo - reloc_info;
45 u_reloc = (struct relocation_info *)
46 Malloc((unsigned)nrelo*sizeof(struct relocation_info));
49 for (i = nrelo; i > 0; i--, rp++) {
50 if ( ( rp->or_sect-S_MIN) == SEGTXT &&
51 convert_reloc( rp, u_reloc)) {
57 for (i = nrelo; i > 0; i--, rp++) {
58 if ( ( rp->or_sect-S_MIN) != SEGTXT &&
59 convert_reloc( rp, u_reloc)) {
65 nrelo = trsize + drsize;
72 putbuf( (char *) &u_header, sizeof(struct exec));
73 putbuf( (char *) text_area, ntext);
74 putbuf( (char *) data_area, ndata);
75 putbuf((char *) u_reloc, sizeof(struct relocation_info)*nrelo);
78 u_name = (struct nlist *)
79 Malloc((unsigned)nname * sizeof(struct nlist));
81 for (i = 0; i < nname ; i++) { /* The segment names can be omitted */
82 convert_name( &symbol_table[i], u_name++);
85 putbuf((char *) u_name, sizeof(struct nlist)*nname);
88 /* print( "size string_area %d\n", nchar); */
90 put_stringtablesize( nchar + 4);
91 putbuf((char *) string_area, nchar);
98 * Reduce the name table size. This is done by first marking
99 * the name-table entries that are needed for relocation, then
100 * removing the entries that are compiler-generated and not
101 * needed for relocation, while remembering how many entries were
102 * removed at each point, and then updating the relocation info.
103 * After that, the string table is reduced.
106 #define S_NEEDED S_MOD
107 #define removable(nm) (!(nm->on_type & (S_NEEDED|S_STB)) && *(nm->on_foff+string_area) == GENLAB)
109 register int *diff_index =
110 (int *) Malloc((unsigned)(nname + 1) * sizeof(int));
112 register struct outname *np;
114 register char *p, *q;
115 register struct relocation_info *rp;
119 for (i = nrelo; i > 0; i--, rp++) {
121 symbol_table[rp->r_symbolnum].on_type |= S_NEEDED;
126 for (i = 0; i < nname; i++, np++) {
127 int old_diff_index = diff_index[i-1];
130 diff_index[i] = old_diff_index + 1;
133 diff_index[i] = old_diff_index;
135 if ((np->on_type & S_TYP) == S_CRS) {
136 struct outname *n = &symbol_table[(int) np->on_valu];
137 if (! (n->on_type & S_COM)) {
138 np->on_type &= ~S_TYP;
139 np->on_type |= (n->on_type & S_TYP);
140 np->on_valu = n->on_valu;
146 for (i = nrelo; i > 0; i--, rp++) {
148 symbol_table[rp->r_symbolnum].on_type &= ~S_NEEDED;
149 rp->r_symbolnum -= diff_index[rp->r_symbolnum];
153 for (i = 0, np = symbol_table; i < nname; i++, np++) {
154 if ((np->on_type & S_TYP) == S_CRS) {
155 np->on_valu -= diff_index[(int) np->on_valu];
157 if (diff_index[i] && diff_index[i] == diff_index[i-1]) {
158 symbol_table[i - diff_index[i]] = *np;
162 nname -= diff_index[nname - 1];
163 free((char *)(diff_index-1));
165 new_str = q = Malloc((unsigned)(string - string_area));
167 for (i = nname; i > 0; i--, np++) {
168 p = np->on_foff + string_area;
169 np->on_foff = q - new_str;
170 while (*q++ = *p) p++;
173 string_area = new_str;
180 ntext = text - text_area;
181 ndata = data - data_area;
182 nchar = string - string_area;
184 u_header.a_magic = OMAGIC;
185 u_header.a_machtype = M_68020;
186 u_header.a_text = ntext;
187 u_header.a_data = ndata;
188 u_header.a_bss = nbss;
189 u_header.a_syms = nname * sizeof(struct nlist);
190 u_header.a_entry = 0;
191 u_header.a_trsize = trsize * sizeof(struct relocation_info);
192 u_header.a_drsize = drsize * sizeof(struct relocation_info);
193 /* print( "header %o %d %d %d %d %d %d %d\n",
194 u_header.a_magic, u_header.a_text, u_header.a_data,
195 u_header.a_bss, u_header.a_syms, u_header.a_entry,
196 u_header.a_trsize, u_header.a_drsize);
201 convert_reloc( a_relo, u_relo)
202 register struct outrelo *a_relo;
203 register struct relocation_info *u_relo;
207 *(((int *) u_relo)+1) = 0;
208 u_relo->r_address = a_relo->or_addr;
209 u_relo->r_symbolnum = a_relo->or_nami;
210 u_relo->r_pcrel = (a_relo->or_type & RELPC) >> 3;
211 u_relo->r_length = 2;
212 if ( symbol_table[ a_relo->or_nami].on_valu == -1 ||
213 (symbol_table[ a_relo->or_nami].on_type & S_COM))
214 u_relo->r_extern = 1;
215 if ( u_relo->r_extern == 0) {
216 switch ( (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN) {
217 case SEGTXT : u_relo->r_symbolnum = N_TEXT;
218 if (u_relo->r_pcrel &&
219 (a_relo->or_sect-S_MIN == SEGTXT))
222 case SEGCON : u_relo->r_symbolnum = N_DATA;
224 case SEGBSS : u_relo->r_symbolnum = N_BSS;
226 /* Shut up; this could actually happen on erroneous input
227 default : fprint( STDERR,
228 "convert_relo(): bad segment %d\n",
229 (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN);
236 #define n_mptr n_un.n_name
237 #define n_str n_un.n_strx
240 convert_name( a_name, u_name)
241 register struct outname *a_name;
242 register struct nlist *u_name;
244 /* print( "naam is %s\n", a_name->on_foff + string_area); */
246 u_name->n_str = a_name->on_foff + 4;
247 if (a_name->on_type & S_STB) u_name->n_type = a_name->on_type >> 8;
248 else u_name->n_type = 0;
249 if ((a_name->on_type & S_TYP) == S_CRS) {
251 a_name->on_type = S_COM;
253 if (a_name->on_valu != -1 && (! (a_name->on_type & S_COM))) {
254 switch((a_name->on_type & S_TYP) - S_MIN) {
256 u_name->n_type |= N_TEXT;
259 u_name->n_type |= N_DATA;
262 u_name->n_type |= N_BSS;
264 /* Shut up; this could actually happen on erroneous input
266 fprint(STDERR, "convert_name(): bad section %d\n",
267 (a_name->on_type & S_TYP) - S_MIN);
272 if ((a_name->on_type & S_TYP) == S_UND ||
273 (a_name->on_type & S_EXT)) u_name->n_type |= N_EXT;
274 u_name->n_other = '\0';
275 u_name->n_desc = a_name->on_desc;
276 if (a_name->on_type & S_COM)
277 u_name->n_value = a_name->on_valu;
278 else if ( a_name->on_valu != -1)
279 u_name->n_value = a_name->on_valu +
280 B_base_address[( a_name->on_type & S_TYP) - S_MIN];
286 put_stringtablesize( n)
289 putbuf( (char *)&n, 4L);
297 sys_write( B_out_file, buf, n);