1 #include "l.h" 2 3 #define Dbufslop 100 4 5 long 6 entryvalue(void) 7 { 8 char *a; 9 Sym *s; 10 11 a = INITENTRY; 12 if(*a >= '0' && *a <= '9') 13 return atolwhex(a); 14 s = lookup(a, 0); 15 if(s->type == 0) 16 return INITTEXT; 17 if(s->type != STEXT && s->type != SLEAF) 18 diag("entry not text: %s %d", s->name, s->type); 19 return s->value; 20 } 21 22 void 23 asmb(void) 24 { 25 Prog *p; 26 long v; 27 ulong *op1; 28 29 if(debug['v']) 30 Bprint(&bso, "%5.2f asmb\n", cputime()); 31 Bflush(&bso); 32 33 seek(cout, HEADR, 0); 34 pc = INITTEXT; 35 curp = firstp; 36 for(p = firstp; p != P; p = p->link) { 37 if(p->as == ATEXT) { 38 curtext = p; 39 autosize = p->to.offset + 4; 40 } 41 if(p->pc != pc) { 42 if(!debug['a']) 43 print("%P\n", curp); 44 diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME); 45 pc = p->pc; 46 } 47 curp = p; 48 asmins(p); 49 if(cbc < sizeof(and)) 50 cflush(); 51 if(debug['a']) { 52 Bprint(&bso, pcstr, pc); 53 for(op1 = and; op1 < andptr; op1++) 54 Bprint(&bso, " %.8lux", *op1); 55 Bprint(&bso, "\t%P\n", curp); 56 } 57 for(op1 = and; op1 < andptr; op1++) { 58 v = *op1; 59 cbp[0] = v; 60 cbp[1] = v>>8; 61 cbp[2] = v>>16; 62 cbp[3] = v>>24; 63 cbp += 4; 64 pc += 4; 65 cbc -= 4; 66 } 67 } 68 cflush(); 69 switch(HEADTYPE) { 70 default: 71 diag("unknown header type %d", HEADTYPE); 72 case 0: 73 seek(cout, rnd(HEADR+textsize, 8192), 0); 74 break; 75 case 1: 76 textsize = rnd(HEADR+textsize, 4096)-HEADR; 77 seek(cout, textsize+HEADR, 0); 78 break; 79 case 2: 80 seek(cout, HEADR+textsize, 0); 81 break; 82 case 3: 83 seek(cout, HEADR+rnd(textsize, INITRND), 0); 84 break; 85 case 4: 86 textsize = rnd(textsize, 4); 87 seek(cout, textsize+HEADR, 0); 88 break; 89 } 90 91 if(debug['v']) 92 Bprint(&bso, "%5.2f datblk\n", cputime()); 93 Bflush(&bso); 94 for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { 95 if(datsize-v > sizeof(buf)-Dbufslop) 96 datblk(v, sizeof(buf)-Dbufslop); 97 else 98 datblk(v, datsize-v); 99 } 100 101 symsize = 0; 102 lcsize = 0; 103 if(!debug['s']) { 104 if(debug['v']) 105 Bprint(&bso, "%5.2f sym\n", cputime()); 106 Bflush(&bso); 107 switch(HEADTYPE) { 108 default: 109 case 0: 110 seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); 111 break; 112 case 1: 113 seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); 114 break; 115 case 2: 116 seek(cout, HEADR+textsize+datsize, 0); 117 break; 118 case 3: 119 debug['s'] = 1; 120 break; 121 case 4: 122 debug['s'] = 1; 123 break; 124 } 125 if(!debug['s']) 126 asmsym(); 127 if(debug['v']) 128 Bprint(&bso, "%5.2f sp\n", cputime()); 129 Bflush(&bso); 130 if(!debug['s']) 131 asmlc(); 132 cflush(); 133 } 134 if(debug['v']) 135 Bprint(&bso, "%5.2f headr\n", cputime()); 136 Bflush(&bso); 137 seek(cout, 0L, 0); 138 switch(HEADTYPE) { 139 default: 140 case 0: /* garbage */ 141 lput(0x160L<<16); /* magic and sections */ 142 lput(0L); /* time and date */ 143 lput(rnd(HEADR+textsize, 4096)+datsize); 144 lput(symsize); /* nsyms */ 145 lput((0x38L<<16)|7L); /* size of optional hdr and flags */ 146 lput((0413<<16)|0437L); /* magic and version */ 147 lput(rnd(HEADR+textsize, 4096)); /* sizes */ 148 lput(datsize); 149 lput(bsssize); 150 lput(entryvalue()); /* va of entry */ 151 lput(INITTEXT-HEADR); /* va of base of text */ 152 lput(INITDAT); /* va of base of data */ 153 lput(INITDAT+datsize); /* va of base of bss */ 154 lput(~0L); /* gp reg mask */ 155 lput(0L); 156 lput(0L); 157 lput(0L); 158 lput(0L); 159 lput(~0L); /* gp value ?? */ 160 break; 161 case 1: /* unix coff */ 162 case 4: 163 /* 164 * file header 165 */ 166 if(HEADTYPE == 4) 167 lputl(0x00020161); /* 2 sections, magic */ 168 else 169 lputl(0x0002014c); /* 2 sections, magic */ 170 lputl(0); /* unix time stamp */ 171 lputl(0); /* symbol table */ 172 lputl(0); /* nsyms */ 173 lputl(0x00030020); /* flags, sizeof a.out header */ 174 /* 175 * a.out header 176 */ 177 lputl(0x10b); /* magic, version stamp */ 178 lputl(rnd(textsize, INITRND)); /* text sizes */ 179 lputl(datsize); /* data sizes */ 180 lputl(bsssize); /* bss sizes */ 181 lput(entryvalue()); /* va of entry */ 182 lputl(INITTEXT); /* text start */ 183 lputl(INITDAT); /* data start */ 184 lputl(0); /* tag entries */ 185 /* 186 * text section header 187 */ 188 s8put(".text"); 189 lputl(INITTEXT); /* pa */ 190 lputl(INITTEXT); /* va */ 191 lputl(textsize); /* text size */ 192 lputl(HEADR); /* file offset */ 193 lputl(0); /* relocation */ 194 lputl(0); /* line numbers */ 195 lputl(0); /* relocation, line numbers */ 196 lputl(0x20); /* flags text only */ 197 lputl(0); /* alignment */ 198 /* 199 * data section header 200 */ 201 s8put(".data"); 202 lputl(INITDAT); /* pa */ 203 lputl(INITDAT); /* va */ 204 lputl(datsize); /* data size */ 205 lputl(HEADR+textsize); /* file offset */ 206 lputl(0); /* relocation */ 207 lputl(0); /* line numbers */ 208 lputl(0); /* relocation, line numbers */ 209 lputl(0x40); /* flags data only */ 210 lputl(0); /* alignment */ 211 break; 212 213 case 2: /* plan9 */ 214 lput(4*12*12+7); /* magic */ 215 lput(textsize); /* sizes */ 216 lput(datsize); 217 lput(bsssize); 218 lput(symsize); /* nsyms */ 219 lput(entryvalue()); /* va of entry */ 220 lput(0); /* sp offsets */ 221 lput(lcsize); /* line offsets */ 222 break; 223 case 3: 224 /* msdos boot */ 225 break; 226 } 227 cflush(); 228 } 229 230 void 231 lput(long l) 232 { 233 234 CPUT(l>>24) 235 CPUT(l>>16) 236 CPUT(l>>8) 237 CPUT(l) 238 } 239 240 void 241 lputl(long l) 242 { 243 244 CPUT(l) 245 CPUT(l>>8) 246 CPUT(l>>16) 247 CPUT(l>>24) 248 } 249 250 void 251 s8put(char *n) 252 { 253 char name[8]; 254 int i; 255 256 strncpy(name, n, sizeof(name)); 257 for(i=0; i<sizeof(name); i++) 258 CPUT(name[i]) 259 } 260 261 void 262 cflush(void) 263 { 264 int n; 265 266 n = sizeof(buf.cbuf) - cbc; 267 if(n) 268 write(cout, buf.cbuf, n); 269 cbp = buf.cbuf; 270 cbc = sizeof(buf.cbuf); 271 } 272 273 void 274 datblk(long s, long n) 275 { 276 Prog *p; 277 char *cast; 278 long l, fl, j; 279 int i, c; 280 281 memset(buf.dbuf, 0, n+Dbufslop); 282 for(p = datap; p != P; p = p->link) { 283 curp = p; 284 l = p->from.sym->value + p->from.offset - s; 285 c = p->from.scale; 286 i = 0; 287 if(l < 0) { 288 if(l+c <= 0) 289 continue; 290 while(l < 0) { 291 l++; 292 i++; 293 } 294 } 295 if(l >= n) 296 continue; 297 for(j=l+(c-i)-1; j>=l; j--) 298 if(buf.dbuf[j]) { 299 print("%P\n", p); 300 diag("multiple initialization"); 301 break; 302 } 303 switch(p->to.type) { 304 case D_FCONST: 305 switch(c) { 306 default: 307 case 4: 308 fl = ieeedtof(&p->to.ieee); 309 cast = (char*)&fl; 310 if(debug['a'] && i == 0) { 311 Bprint(&bso, pcstr, l+s+INITDAT); 312 for(j=0; j<c; j++) 313 Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff); 314 Bprint(&bso, "\t%P\n", curp); 315 } 316 for(; i<c; i++) { 317 buf.dbuf[l] = cast[fnuxi4[i]]; 318 l++; 319 } 320 break; 321 case 8: 322 cast = (char*)&p->to.ieee; 323 if(debug['a'] && i == 0) { 324 Bprint(&bso, pcstr, l+s+INITDAT); 325 for(j=0; j<c; j++) 326 Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); 327 Bprint(&bso, "\t%P\n", curp); 328 } 329 for(; i<c; i++) { 330 buf.dbuf[l] = cast[fnuxi8[i]]; 331 l++; 332 } 333 break; 334 } 335 break; 336 337 case D_SCONST: 338 if(debug['a'] && i == 0) { 339 Bprint(&bso, pcstr, l+s+INITDAT); 340 for(j=0; j<c; j++) 341 Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); 342 Bprint(&bso, "\t%P\n", curp); 343 } 344 for(; i<c; i++) { 345 buf.dbuf[l] = p->to.scon[i]; 346 l++; 347 } 348 break; 349 default: 350 fl = p->to.offset; 351 if(p->to.type == D_ADDR) { 352 if(p->to.index != D_STATIC && p->to.index != D_EXTERN) 353 diag("DADDR type%P", p); 354 if(p->to.sym) { 355 fl += p->to.sym->value; 356 if(p->to.sym->type != STEXT && p->to.sym->type != SLEAF) 357 fl += INITDAT; 358 } 359 } 360 cast = (char*)&fl; 361 switch(c) { 362 default: 363 diag("bad nuxi %d %d\n%P", c, i, curp); 364 break; 365 case 1: 366 if(debug['a'] && i == 0) { 367 Bprint(&bso, pcstr, l+s+INITDAT); 368 for(j=0; j<c; j++) 369 Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff); 370 Bprint(&bso, "\t%P\n", curp); 371 } 372 for(; i<c; i++) { 373 buf.dbuf[l] = cast[inuxi1[i]]; 374 l++; 375 } 376 break; 377 case 2: 378 if(debug['a'] && i == 0) { 379 Bprint(&bso, pcstr, l+s+INITDAT); 380 for(j=0; j<c; j++) 381 Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff); 382 Bprint(&bso, "\t%P\n", curp); 383 } 384 for(; i<c; i++) { 385 buf.dbuf[l] = cast[inuxi2[i]]; 386 l++; 387 } 388 break; 389 case 4: 390 if(debug['a'] && i == 0) { 391 Bprint(&bso, pcstr, l+s+INITDAT); 392 for(j=0; j<c; j++) 393 Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff); 394 Bprint(&bso, "\t%P\n", curp); 395 } 396 for(; i<c; i++) { 397 buf.dbuf[l] = cast[inuxi4[i]]; 398 l++; 399 } 400 break; 401 } 402 break; 403 } 404 } 405 write(cout, buf.dbuf, n); 406 } 407 408 long 409 rnd(long v, long r) 410 { 411 long c; 412 413 if(r <= 0) 414 return v; 415 v += r - 1; 416 c = v % r; 417 if(c < 0) 418 c += r; 419 v -= c; 420 return v; 421 } 422