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