as.om (18086B)
1 func setup_machdep_x86(c: *compiler); 2 3 struct fixup { 4 kind: int; 5 next: *fixup; 6 label: *label; 7 ptr: *byte; 8 fill: int; 9 at: int; 10 } 11 12 struct label { 13 fix: *fixup; 14 at: int; 15 fixed: int; 16 } 17 18 struct chunk { 19 next: *chunk; 20 buf: *byte; 21 fill: int; 22 cap: int; 23 } 24 25 struct section { 26 next: *section; 27 name: *byte; 28 start: int; 29 end: int; 30 index: int; 31 name_offset: int; 32 type: int; 33 link: int; 34 entsize: int; 35 } 36 37 struct assembler { 38 a: *alloc; 39 out: *file; 40 lineout: *file; 41 at: int; 42 text: *chunk; 43 text_end: *chunk; 44 bits32: int; 45 symbols: *symbol; 46 sections: *section; 47 num_sections: int; 48 lines_out: *file; 49 filename: *byte; 50 lineno: int; 51 prevfilename: *byte; 52 prevlineno: int; 53 blobs: *ablob; 54 } 55 56 struct ablob { 57 left: *ablob; 58 right: *ablob; 59 label: *label; 60 s: *byte; 61 slen: int; 62 } 63 64 struct symbol { 65 next: *symbol; 66 name: *byte; 67 label: *label; 68 name_offset: int; 69 } 70 71 enum { 72 FIXUP_DISP32 = 0, 73 FIXUP_ARM_B = 1, 74 FIXUP_ARM_ADR = 2, 75 FIXUP_RISCV_J = 3, 76 FIXUP_RISCV_AUIPC = 4, 77 } 78 79 func setup_assembler(a: *alloc): *assembler { 80 var c: *assembler; 81 c = alloc(a, sizeof(*c)) as *assembler; 82 c.a = a; 83 c.out = nil; 84 c.at = 160; // elf header + program header + multiboot header 85 c.text = nil; 86 c.text_end = nil; 87 c.bits32 = 0; 88 c.symbols = nil; 89 c.num_sections = 0; 90 add_section(c, "", SHT_NULL); 91 add_section(c, ".text", SHT_PROGBITS); 92 return c; 93 } 94 95 func add_section(c: *assembler, name: *byte, type: int) { 96 var s: *section; 97 var n: *section; 98 var end: int; 99 100 end = c.at; 101 102 emit_align(c, 16, 0); 103 104 s = alloc(c.a, sizeof(*s)) as *section; 105 106 s.next = nil; 107 s.name = name; 108 s.start = c.at; 109 s.end = c.at; 110 s.index = c.num_sections; 111 s.type = type; 112 s.link = 0; 113 s.entsize = 0; 114 115 n = c.sections; 116 if n { 117 loop { 118 if !n.next { 119 break; 120 } 121 n = n.next; 122 } 123 n.end = end; 124 n.next = s; 125 } else { 126 c.sections = s; 127 } 128 129 c.num_sections = c.num_sections + 1; 130 } 131 132 func find_section(c: *assembler, name: *byte): *section { 133 var n: *section; 134 n = c.sections; 135 loop { 136 if !n { 137 break; 138 } 139 140 if strcmp(n.name, name) == 0 { 141 break; 142 } 143 144 n = n.next; 145 } 146 return n; 147 } 148 149 func putchar(c: *assembler, ch: int) { 150 fputc(c.out, ch); 151 } 152 153 func open_output(c: *assembler, filename: *byte) { 154 var fd: int; 155 156 if (c.out) { 157 die("multiple output files"); 158 } 159 160 unlink(filename); 161 162 fd = open(filename, O_CREAT | O_WRONLY, (7 << 6) + (7 << 3) +7); 163 if (fd < 0) { 164 die("failed to open output"); 165 } 166 167 c.out = fopen(fd, c.a); 168 c.out.noflush = 1; 169 } 170 171 // Create a new label 172 func mklabel(c: *assembler): *label { 173 var l: *label; 174 175 l = alloc(c.a, sizeof(*l)) as *label; 176 177 l.fix = nil; 178 l.at = 0; 179 l.fixed = 0; 180 181 return l; 182 } 183 184 // Reserve size in the output buffer 185 func reserve(c: *assembler, n: int) { 186 var m: *byte; 187 var b: *chunk; 188 189 if (c.text_end && c.text_end.cap - c.text_end.fill >= n) { 190 return; 191 } 192 193 if (n < 4096) { 194 n = 4096; 195 } 196 197 m = alloc(c.a, n); 198 b = alloc(c.a, sizeof(*b)) as *chunk; 199 200 b.buf = m; 201 b.fill = 0; 202 b.cap = n; 203 b.next = nil; 204 205 if (c.text_end) { 206 c.text_end.next = b; 207 c.text_end = b; 208 } else { 209 c.text = b; 210 c.text_end = b; 211 } 212 } 213 214 func emit_hook(c: *assembler) { 215 if !c.lines_out { 216 c.prevlineno = c.lineno; 217 c.prevfilename = c.filename; 218 } 219 220 if ( 221 c.lineno == c.prevlineno 222 && ( 223 c.filename == c.prevfilename 224 || (c.filename && c.prevfilename && !strcmp(c.filename, c.prevfilename)) 225 ) 226 ) { 227 return; 228 } 229 230 fputh(c.lines_out, c.at + 0x100000); 231 fputs(c.lines_out, "\t"); 232 if c.filename { 233 fputs(c.lines_out, c.filename); 234 } 235 fputs(c.lines_out, ":"); 236 fputd(c.lines_out, c.lineno); 237 fputs(c.lines_out, "\n"); 238 239 c.prevlineno = c.lineno; 240 c.prevfilename = c.filename; 241 } 242 243 // Add a single byte to the output 244 func emit(c: *assembler, x: int) { 245 emit_hook(c); 246 reserve(c, 1); 247 c.text_end.buf[c.text_end.fill] = x as byte; 248 c.text_end.fill = c.text_end.fill + 1; 249 c.at = c.at + 1; 250 } 251 252 func fixup(c: *assembler, f: *fixup) { 253 var disp: int; 254 var x: int; 255 var here: *byte; 256 var rd: int; 257 258 rd = 16; 259 if f.kind == FIXUP_DISP32 { 260 if f.fill < 4 { 261 die("truncated fixup"); 262 } 263 264 here = &f.ptr[-4]; 265 266 disp = f.label.at - f.at; 267 268 here[0] = disp as byte; 269 here[1] = (disp >> 8) as byte; 270 here[2] = (disp >> 16) as byte; 271 here[3] = (disp >> 24) as byte; 272 } else if f.kind == FIXUP_ARM_B { 273 if f.fill < 4 { 274 die("truncated fixup"); 275 } 276 277 disp = f.label.at - (f.at - 4); 278 if disp < -(1 << 25) || disp >= (1 << 25) { 279 die("fixup overflow"); 280 } 281 282 x = (5 << 26) + ((disp >> 2) & ((1 << 26) - 1)); 283 284 here = &f.ptr[-4]; 285 here[0] = x as byte; 286 here[1] = (x >> 8) as byte; 287 here[2] = (x >> 16) as byte; 288 here[3] = (x >> 24) as byte; 289 } else if f.kind == FIXUP_ARM_ADR { 290 if f.fill < 8 { 291 die("truncated fixup"); 292 } 293 here = &f.ptr[-8]; 294 295 disp = f.label.at - (f.at - 8); 296 if disp >= -(1 << 21) && disp < (1 << 21) && 0 { 297 x = ((disp & 3) << 29) + (1 << 28) + (((disp >> 2) & ((1 << 19) - 1)) << 5) + rd; 298 here[0] = x as byte; 299 here[1] = (x >> 8) as byte; 300 here[2] = (x >> 16) as byte; 301 here[3] = (x >> 24) as byte; 302 303 x = 0xd503201f; 304 here[4] = x as byte; 305 here[5] = (x >> 8) as byte; 306 here[6] = (x >> 16) as byte; 307 here[7] = (x >> 24) as byte; 308 } else if disp >= -(1 << 33) && disp < (1 << 33) { 309 disp = (f.label.at & -4096) - ((f.at - 8) & -4096); 310 x = (1 << 31) + (((disp >> 12) & 3) << 29) + (1 << 28) + (((disp >> 14) & ((1 << 19) - 1)) << 5) + rd; 311 here[0] = x as byte; 312 here[1] = (x >> 8) as byte; 313 here[2] = (x >> 16) as byte; 314 here[3] = (x >> 24) as byte; 315 316 disp = f.label.at; 317 x = (0x122 << 23) + ((disp & 0xfff) << 10) + (rd << 5) + rd; 318 here[4] = x as byte; 319 here[5] = (x >> 8) as byte; 320 here[6] = (x >> 16) as byte; 321 here[7] = (x >> 24) as byte; 322 } else { 323 die("fixup overflow"); 324 } 325 } else if f.kind == FIXUP_RISCV_AUIPC { 326 here = &f.ptr[-8]; 327 disp = f.label.at - (f.at - 8); 328 329 if disp >= -(1 << 31) && disp < (1 << 31) { 330 rd = ((here[5] as int & 15) << 1) + (here[4] as int >> 7); 331 332 x = (disp << 20) + (rd << 15) + (rd << 7) + 0b0010011; 333 here[4] = x as byte; 334 here[5] = (x >> 8) as byte; 335 here[6] = (x >> 16) as byte; 336 here[7] = (x >> 24) as byte; 337 338 if disp & 2048 { 339 disp = disp + 2048; 340 } 341 342 x = (disp & -4096) + (rd << 7) + 0b0010111; 343 here[0] = x as byte; 344 here[1] = (x >> 8) as byte; 345 here[2] = (x >> 16) as byte; 346 here[3] = (x >> 24) as byte; 347 } else { 348 die("fixup overflow"); 349 } 350 } else if f.kind == FIXUP_RISCV_J { 351 here = &f.ptr[-8]; 352 disp = f.label.at - (f.at - 8); 353 354 if disp >= -(1 << 19) && disp < (1 << 19) && 0 { 355 x = (((disp >> 20) & 0b1) << 31) 356 + (((disp >> 1) & 0b1111111111) << 21) 357 + (((disp >> 11) & 0b1) << 20) 358 + (((disp >> 12) & 0b11111111) << 12) 359 + 0b1101111; 360 here[0] = x as byte; 361 here[1] = (x >> 8) as byte; 362 here[2] = (x >> 16) as byte; 363 here[3] = (x >> 24) as byte; 364 } else if disp >= -(1 << 31) && disp < (1 << 31) { 365 rd = 31; 366 367 x = (disp << 20) + (rd << 15) + 0b1100111; 368 here[4] = x as byte; 369 here[5] = (x >> 8) as byte; 370 here[6] = (x >> 16) as byte; 371 here[7] = (x >> 24) as byte; 372 373 if disp & 2048 { 374 disp = disp + 2048; 375 } 376 377 x = (disp & -4096) + (rd << 7) + 0b0010111; 378 here[0] = x as byte; 379 here[1] = (x >> 8) as byte; 380 here[2] = (x >> 16) as byte; 381 here[3] = (x >> 24) as byte; 382 } else { 383 die("fixup overflow"); 384 } 385 } else { 386 die("invalid fixup"); 387 } 388 } 389 390 // Add an new fixup for the current position 391 func addfixup(c: *assembler, l: *label, kind: int) { 392 var f: *fixup; 393 f = alloc(c.a, sizeof(*f)) as *fixup; 394 f.label = l; 395 f.kind = kind; 396 f.next = l.fix; 397 f.ptr = &c.text_end.buf[c.text_end.fill]; 398 f.fill = c.text_end.fill; 399 f.at = c.at; 400 l.fix = f; 401 if (l.fixed) { 402 fixup(c, f); 403 } 404 } 405 406 // Fix references to a label to the current position 407 func fixup_label(c: *assembler, l: *label) { 408 var f: *fixup; 409 410 if (l.fixed) { 411 die("already fixed"); 412 } 413 414 l.at = c.at; 415 l.fixed = 1; 416 417 f = l.fix; 418 loop { 419 if (!f) { 420 break; 421 } 422 fixup(c, f); 423 f = f.next; 424 } 425 } 426 427 func as_blob(c: *assembler, s: *byte, slen: int): *label { 428 var b: *ablob; 429 var link: **ablob; 430 var dir: int; 431 432 link = &c.blobs; 433 loop { 434 b = *link; 435 if !b { 436 break; 437 } 438 439 if b.slen < slen { 440 dir = memcmp(b.s, s, b.slen); 441 if dir == 0 { 442 dir = -1; 443 } 444 } else if b.slen > slen { 445 dir = memcmp(b.s, s, slen); 446 if dir == 0 { 447 dir = 1; 448 } 449 } else { 450 dir = memcmp(b.s, s, slen); 451 } 452 453 if dir == 0 { 454 return b.label; 455 } else if dir > 0 { 456 link = &b.left; 457 } else { // dir < 0 458 link = &b.right; 459 } 460 } 461 462 b = alloc(c.a, sizeof(*b)) as *ablob; 463 464 b.label = mklabel(c); 465 b.s = alloc(c.a, slen); 466 b.slen = slen; 467 468 memcpy(b.s, s, slen); 469 470 *link = b; 471 472 return b.label; 473 } 474 475 func emit_blobs(c: *assembler, b: *ablob) { 476 var i: int; 477 478 if !b { 479 return; 480 } 481 482 emit_blobs(c, b.left); 483 484 fixup_label(c, b.label); 485 486 i = 0; 487 loop { 488 if i == b.slen { 489 break; 490 } 491 492 as_emit(c, b.s[i] as int); 493 494 i = i + 1; 495 } 496 497 emit_blobs(c, b.right); 498 } 499 500 func add_symbol(c: *assembler, name: *byte, l: *label) { 501 var s: *symbol; 502 503 s = alloc(c.a, sizeof(*s)) as *symbol; 504 505 s.next = c.symbols; 506 s.name = name; 507 s.label = l; 508 509 c.symbols = s; 510 } 511 512 func emit_strtab_str(c: *assembler, s: *byte): int { 513 var i: int; 514 515 i = 0; 516 loop { 517 as_emit(c, s[i] as int); 518 519 if !s[i] { 520 break; 521 } 522 523 i = i + 1; 524 } 525 526 return i + 1; 527 } 528 529 enum { 530 SHT_NULL = 0, 531 SHT_PROGBITS = 1, 532 SHT_SYMTAB = 2, 533 SHT_STRTAB = 3, 534 } 535 536 func emit_sections(c: *assembler): int { 537 var at: int; 538 var s: *section; 539 var y: *symbol; 540 var n: int; 541 var here: int; 542 543 add_symbol(c, "", nil); 544 545 s = find_section(c, ""); 546 s.start = 0; 547 s.end = 0; 548 549 here = c.at; 550 551 emit_align(c, 4096, 0); 552 553 add_section(c, ".rodata", SHT_PROGBITS); 554 555 s = find_section(c, ".text"); 556 s.end = here; 557 558 emit_blobs(c, c.blobs); 559 560 emit_align(c, 4096, 0); 561 562 add_section(c, ".strtab", SHT_STRTAB); 563 564 y = c.symbols; 565 loop { 566 if !y { 567 break; 568 } 569 570 y.name_offset = n; 571 n = n + emit_strtab_str(c, y.name); 572 573 y = y.next; 574 } 575 576 add_section(c, ".symtab", SHT_SYMTAB); 577 578 y = c.symbols; 579 loop { 580 if !y { 581 break; 582 } 583 584 // name 585 n = y.name_offset; 586 as_emit(c, n); 587 as_emit(c, n >> 8); 588 as_emit(c, n >> 16); 589 as_emit(c, n >> 24); 590 591 // info 592 if y.label { 593 n = 0x12; 594 } else { 595 n = 0; 596 } 597 as_emit(c, n); 598 599 // other 600 as_emit(c, 0); 601 602 // section 603 if y.label { 604 n = 1; 605 } else { 606 n = 0; 607 } 608 as_emit(c, n); 609 as_emit(c, n >> 8); 610 611 // addr 612 if y.label { 613 n = y.label.at + 0x100000; 614 } else { 615 n = 0; 616 } 617 as_emit(c, n); 618 as_emit(c, n >> 8); 619 as_emit(c, n >> 16); 620 as_emit(c, n >> 24); 621 as_emit(c, n >> 32); 622 as_emit(c, n >> 40); 623 as_emit(c, n >> 48); 624 as_emit(c, n >> 56); 625 626 // size 627 as_emit(c, 0); 628 as_emit(c, 0); 629 as_emit(c, 0); 630 as_emit(c, 0); 631 as_emit(c, 0); 632 as_emit(c, 0); 633 as_emit(c, 0); 634 as_emit(c, 0); 635 636 y = y.next; 637 } 638 639 s = find_section(c, ".strtab"); 640 n = s.index; 641 642 s = find_section(c, ".symtab"); 643 s.link = n; 644 s.entsize = 0x18; 645 646 add_section(c, ".shstrtab", SHT_STRTAB); 647 648 s = c.sections; 649 n = 0; 650 loop { 651 if !s { 652 break; 653 } 654 655 s.name_offset = n; 656 n = n + emit_strtab_str(c, s.name); 657 658 s = s.next; 659 } 660 661 s = find_section(c, ".shstrtab"); 662 s.end = c.at; 663 664 emit_align(c, 16, 0); 665 666 at = c.at; 667 668 s = c.sections; 669 loop { 670 if !s { 671 break; 672 } 673 674 // Name 675 n = s.name_offset; 676 as_emit(c, n); 677 as_emit(c, n >> 8); 678 as_emit(c, n >> 16); 679 as_emit(c, n >> 24); 680 681 // Type 682 n = s.type; 683 as_emit(c, n); 684 as_emit(c, n >> 8); 685 as_emit(c, n >> 16); 686 as_emit(c, n >> 24); 687 688 // Flags 689 if strcmp(s.name, ".text") == 0 { 690 n = 6; 691 } else if strcmp(s.name, ".rodata") == 0 { 692 n = 2; 693 } else { 694 n = 0; 695 } 696 as_emit(c, n); 697 as_emit(c, n >> 8); 698 as_emit(c, n >> 16); 699 as_emit(c, n >> 24); 700 as_emit(c, n >> 32); 701 as_emit(c, n >> 40); 702 as_emit(c, n >> 48); 703 as_emit(c, n >> 56); 704 705 // Addr 706 if s.start == s.end { 707 n = 0; 708 } else { 709 n = s.start + 0x100000; 710 } 711 as_emit(c, n); 712 as_emit(c, n >> 8); 713 as_emit(c, n >> 16); 714 as_emit(c, n >> 24); 715 as_emit(c, n >> 32); 716 as_emit(c, n >> 40); 717 as_emit(c, n >> 48); 718 as_emit(c, n >> 56); 719 720 // Offset 721 n = s.start; 722 as_emit(c, n); 723 as_emit(c, n >> 8); 724 as_emit(c, n >> 16); 725 as_emit(c, n >> 24); 726 as_emit(c, n >> 32); 727 as_emit(c, n >> 40); 728 as_emit(c, n >> 48); 729 as_emit(c, n >> 56); 730 731 // Size 732 n = s.end - s.start; 733 as_emit(c, n); 734 as_emit(c, n >> 8); 735 as_emit(c, n >> 16); 736 as_emit(c, n >> 24); 737 as_emit(c, n >> 32); 738 as_emit(c, n >> 40); 739 as_emit(c, n >> 48); 740 as_emit(c, n >> 56); 741 742 // Link 743 n = s.link; 744 as_emit(c, n); 745 as_emit(c, n >> 8); 746 as_emit(c, n >> 16); 747 as_emit(c, n >> 24); 748 749 // Info 750 if s.type == SHT_SYMTAB { 751 n = 1; 752 } else { 753 n = 0; 754 } 755 as_emit(c, n); 756 as_emit(c, n >> 8); 757 as_emit(c, n >> 16); 758 as_emit(c, n >> 24); 759 760 // align 761 as_emit(c, 1); 762 as_emit(c, 0); 763 as_emit(c, 0); 764 as_emit(c, 0); 765 as_emit(c, 0); 766 as_emit(c, 0); 767 as_emit(c, 0); 768 as_emit(c, 0); 769 770 // entsize 771 n = s.entsize; 772 as_emit(c, n); 773 as_emit(c, n >> 8); 774 as_emit(c, n >> 16); 775 as_emit(c, n >> 24); 776 as_emit(c, n >> 32); 777 as_emit(c, n >> 40); 778 as_emit(c, n >> 48); 779 as_emit(c, n >> 56); 780 781 s = s.next; 782 } 783 784 return at; 785 } 786 787 func writeout(c: *assembler, machine: int, start: *label, kstart: *label) { 788 var b: *chunk; 789 var i: int; 790 var text_size: int; 791 var text_end: int; 792 var load_addr: int; 793 var entry: int; 794 var kentry: int; 795 var mb_magic: int; 796 var mb_flags: int; 797 var mb_checksum: int; 798 var mb_addr: int; 799 var s: *section; 800 var shoff: int; 801 802 if (!c.out) { 803 die("output not opened"); 804 } 805 806 load_addr = 0x100000; 807 808 if (!start || !start.fixed) { 809 if !kstart { 810 die("_start is not defined"); 811 } 812 } else { 813 entry = load_addr + start.at; 814 } 815 816 mb_magic = 0x1badb002; 817 mb_flags = 0x00010003; 818 mb_checksum = -(mb_magic + mb_flags); 819 mb_addr = load_addr + 120; 820 821 if (kstart && kstart.fixed) { 822 kentry = load_addr + kstart.at; 823 } else { 824 mb_magic = 0; 825 kentry = 0; 826 } 827 828 shoff = emit_sections(c as *assembler); 829 830 text_size = c.at; 831 text_end = load_addr + text_size; 832 833 // magic 834 putchar(c, 0x7f); 835 putchar(c, 'E'); 836 putchar(c, 'L'); 837 putchar(c, 'F'); 838 839 // class 840 putchar(c, 2); 841 842 // endian 843 putchar(c, 1); 844 845 // version 846 putchar(c, 1); 847 848 // abi 849 putchar(c, 0); 850 851 // abi version 852 putchar(c, 0); 853 854 // padding 855 putchar(c, 0); 856 putchar(c, 0); 857 putchar(c, 0); 858 putchar(c, 0); 859 putchar(c, 0); 860 putchar(c, 0); 861 putchar(c, 0); 862 863 // type 864 putchar(c, 2); 865 putchar(c, 0); 866 867 // machine 868 putchar(c, machine); 869 putchar(c, 0); 870 871 // version 872 putchar(c, 1); 873 putchar(c, 0); 874 putchar(c, 0); 875 putchar(c, 0); 876 877 // entry point 878 putchar(c, entry); 879 putchar(c, entry >> 8); 880 putchar(c, entry >> 16); 881 putchar(c, entry >> 24); 882 putchar(c, 0); 883 putchar(c, 0); 884 putchar(c, 0); 885 putchar(c, 0); 886 887 // phoff 888 putchar(c, 64); 889 putchar(c, 0); 890 putchar(c, 0); 891 putchar(c, 0); 892 putchar(c, 0); 893 putchar(c, 0); 894 putchar(c, 0); 895 putchar(c, 0); 896 897 // shoff 898 putchar(c, shoff); 899 putchar(c, shoff >> 8); 900 putchar(c, shoff >> 16); 901 putchar(c, shoff >> 24); 902 putchar(c, shoff >> 32); 903 putchar(c, shoff >> 40); 904 putchar(c, shoff >> 48); 905 putchar(c, shoff >> 56); 906 907 // flags 908 putchar(c, 0); 909 putchar(c, 0); 910 putchar(c, 0); 911 putchar(c, 0); 912 913 // ehsize 914 putchar(c, 64); 915 putchar(c, 0); 916 917 // phentsize 918 putchar(c, 56); 919 putchar(c, 0); 920 921 // phnum 922 putchar(c, 1); 923 putchar(c, 0); 924 925 // shentsize 926 putchar(c, 64); 927 putchar(c, 0); 928 929 // shnum 930 putchar(c, c.num_sections); 931 putchar(c, c.num_sections >> 8); 932 933 s = find_section(c, ".shstrtab"); 934 935 // shstrndx 936 putchar(c, s.index); 937 putchar(c, s.index >> 8); 938 939 // phdr[0].type 940 putchar(c, 1); 941 putchar(c, 0); 942 putchar(c, 0); 943 putchar(c, 0); 944 945 // phdr[0].flags 946 putchar(c, 5); 947 putchar(c, 0); 948 putchar(c, 0); 949 putchar(c, 0); 950 951 // phdr[0].offset 952 putchar(c, 0); 953 putchar(c, 0); 954 putchar(c, 0); 955 putchar(c, 0); 956 putchar(c, 0); 957 putchar(c, 0); 958 putchar(c, 0); 959 putchar(c, 0); 960 961 // phdr[0].vaddr 962 putchar(c, 0); 963 putchar(c, 0); 964 putchar(c, 0x10); 965 putchar(c, 0); 966 putchar(c, 0); 967 putchar(c, 0); 968 putchar(c, 0); 969 putchar(c, 0); 970 971 // phdr[0].paddr 972 putchar(c, 0); 973 putchar(c, 0); 974 putchar(c, 0); 975 putchar(c, 0); 976 putchar(c, 0); 977 putchar(c, 0); 978 putchar(c, 0); 979 putchar(c, 0); 980 981 // phdr[0].filesize 982 putchar(c, text_size); 983 putchar(c, text_size >> 8); 984 putchar(c, text_size >> 16); 985 putchar(c, text_size >> 24); 986 putchar(c, 0); 987 putchar(c, 0); 988 putchar(c, 0); 989 putchar(c, 0); 990 991 // phdr[0].memsize 992 putchar(c, text_size); 993 putchar(c, text_size >> 8); 994 putchar(c, text_size >> 16); 995 putchar(c, text_size >> 24); 996 putchar(c, 0); 997 putchar(c, 0); 998 putchar(c, 0); 999 putchar(c, 0); 1000 1001 // phdr[0].align 1002 putchar(c, 0); 1003 putchar(c, 0); 1004 putchar(c, 0); 1005 putchar(c, 0); 1006 putchar(c, 0); 1007 putchar(c, 0); 1008 putchar(c, 0); 1009 putchar(c, 0); 1010 1011 // multiboot magic 1012 putchar(c, mb_magic); 1013 putchar(c, mb_magic >> 8); 1014 putchar(c, mb_magic >> 16); 1015 putchar(c, mb_magic >> 24); 1016 1017 // multiboot flags 1018 putchar(c, mb_flags); 1019 putchar(c, mb_flags >> 8); 1020 putchar(c, mb_flags >> 16); 1021 putchar(c, mb_flags >> 24); 1022 1023 // multboot checksum 1024 putchar(c, mb_checksum); 1025 putchar(c, mb_checksum >> 8); 1026 putchar(c, mb_checksum >> 16); 1027 putchar(c, mb_checksum >> 24); 1028 1029 // multiboot header_addr 1030 putchar(c, mb_addr); 1031 putchar(c, mb_addr >> 8); 1032 putchar(c, mb_addr >> 16); 1033 putchar(c, mb_addr >> 24); 1034 1035 // multiboot load_addr 1036 putchar(c, load_addr); 1037 putchar(c, load_addr >> 8); 1038 putchar(c, load_addr >> 16); 1039 putchar(c, load_addr >> 24); 1040 1041 // multiboot load_end_addr 1042 putchar(c, text_end); 1043 putchar(c, text_end >> 8); 1044 putchar(c, text_end >> 16); 1045 putchar(c, text_end >> 24); 1046 1047 // multiboot bss_end_addr 1048 putchar(c, 0); 1049 putchar(c, 0); 1050 putchar(c, 0); 1051 putchar(c, 0); 1052 1053 // entry_addr 1054 putchar(c, kentry); 1055 putchar(c, kentry >> 8); 1056 putchar(c, kentry >> 16); 1057 putchar(c, kentry >> 24); 1058 1059 // nop sled 1060 putchar(c, 0); 1061 putchar(c, 0); 1062 putchar(c, 0); 1063 putchar(c, 0); 1064 putchar(c, 0); 1065 putchar(c, 0); 1066 putchar(c, 0); 1067 putchar(c, 0); 1068 1069 b = c.text; 1070 loop { 1071 if (!b) { 1072 break; 1073 } 1074 i = 0; 1075 loop { 1076 if (i >= b.fill) { 1077 break; 1078 } 1079 putchar(c, b.buf[i] as int); 1080 i = i + 1; 1081 } 1082 b = b.next; 1083 } 1084 1085 fflush(c.out); 1086 1087 if c.lines_out { 1088 fflush(c.lines_out); 1089 } 1090 } 1091 1092 func as_emit(a: *assembler, b: int) { 1093 emit(a, b); 1094 } 1095 1096 func emit_align(c: *assembler, n: int, b: int) { 1097 var pad: int; 1098 1099 pad = c.at & (n - 1); 1100 1101 if pad == 0 { 1102 return; 1103 } 1104 1105 loop { 1106 if pad == n { 1107 break; 1108 } 1109 1110 as_emit(c, b); 1111 1112 pad = pad + 1; 1113 } 1114 } 1115