| ... | @@ -65,6 +65,9 @@ stub_helper_section_index: ?u16 = null, | ... | @@ -65,6 +65,9 @@ stub_helper_section_index: ?u16 = null, |
| 65 | text_const_section_index: ?u16 = null, | 65 | text_const_section_index: ?u16 = null, |
| 66 | cstring_section_index: ?u16 = null, | 66 | cstring_section_index: ?u16 = null, |
| 67 | ustring_section_index: ?u16 = null, | 67 | ustring_section_index: ?u16 = null, |
| | 68 | gcc_except_tab_section_index: ?u16 = null, |
| | 69 | unwind_info_section_index: ?u16 = null, |
| | 70 | eh_frame_section_index: ?u16 = null, |
| 68 | | 71 | |
| 69 | // __DATA_CONST segment sections | 72 | // __DATA_CONST segment sections |
| 70 | got_section_index: ?u16 = null, | 73 | got_section_index: ?u16 = null, |
| ... | @@ -435,19 +438,17 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -435,19 +438,17 @@ fn updateMetadata(self: *Zld) !void { |
| 435 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 438 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 436 | | 439 | |
| 437 | // Create missing metadata | 440 | // Create missing metadata |
| 438 | for (object_seg.sections.items) |source_sect, sect_id| { | 441 | for (object.sections.items) |sect, sect_id| { |
| 439 | if (sect_id == object.text_section_index.?) continue; | 442 | const segname = sect.segname(); |
| 440 | const segname = parseName(&source_sect.segname); | 443 | const sectname = sect.sectname(); |
| 441 | const sectname = parseName(&source_sect.sectname); | | |
| 442 | const flags = source_sect.flags; | | |
| 443 | | 444 | |
| 444 | switch (flags) { | 445 | switch (sect.sectionType()) { |
| 445 | macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS => { | 446 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { |
| 446 | if (self.text_section_index != null) continue; | 447 | if (self.text_const_section_index != null) continue; |
| 447 | | 448 | |
| 448 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); | 449 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 449 | try text_seg.addSection(self.allocator, .{ | 450 | try text_seg.addSection(self.allocator, .{ |
| 450 | .sectname = makeStaticString("__text"), | 451 | .sectname = makeStaticString("__const"), |
| 451 | .segname = makeStaticString("__TEXT"), | 452 | .segname = makeStaticString("__TEXT"), |
| 452 | .addr = 0, | 453 | .addr = 0, |
| 453 | .size = 0, | 454 | .size = 0, |
| ... | @@ -455,70 +456,12 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -455,70 +456,12 @@ fn updateMetadata(self: *Zld) !void { |
| 455 | .@"align" = 0, | 456 | .@"align" = 0, |
| 456 | .reloff = 0, | 457 | .reloff = 0, |
| 457 | .nreloc = 0, | 458 | .nreloc = 0, |
| 458 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 459 | .flags = macho.S_REGULAR, |
| 459 | .reserved1 = 0, | 460 | .reserved1 = 0, |
| 460 | .reserved2 = 0, | 461 | .reserved2 = 0, |
| 461 | .reserved3 = 0, | 462 | .reserved3 = 0, |
| 462 | }); | 463 | }); |
| 463 | }, | 464 | continue; |
| 464 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | | |
| 465 | if (mem.eql(u8, segname, "__TEXT")) { | | |
| 466 | if (mem.eql(u8, sectname, "__ustring")) { | | |
| 467 | if (self.ustring_section_index != null) continue; | | |
| 468 | | | |
| 469 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 470 | try text_seg.addSection(self.allocator, .{ | | |
| 471 | .sectname = makeStaticString("__ustring"), | | |
| 472 | .segname = makeStaticString("__TEXT"), | | |
| 473 | .addr = 0, | | |
| 474 | .size = 0, | | |
| 475 | .offset = 0, | | |
| 476 | .@"align" = 0, | | |
| 477 | .reloff = 0, | | |
| 478 | .nreloc = 0, | | |
| 479 | .flags = macho.S_REGULAR, | | |
| 480 | .reserved1 = 0, | | |
| 481 | .reserved2 = 0, | | |
| 482 | .reserved3 = 0, | | |
| 483 | }); | | |
| 484 | } else { | | |
| 485 | if (self.text_const_section_index != null) continue; | | |
| 486 | | | |
| 487 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 488 | try text_seg.addSection(self.allocator, .{ | | |
| 489 | .sectname = makeStaticString("__const"), | | |
| 490 | .segname = makeStaticString("__TEXT"), | | |
| 491 | .addr = 0, | | |
| 492 | .size = 0, | | |
| 493 | .offset = 0, | | |
| 494 | .@"align" = 0, | | |
| 495 | .reloff = 0, | | |
| 496 | .nreloc = 0, | | |
| 497 | .flags = macho.S_REGULAR, | | |
| 498 | .reserved1 = 0, | | |
| 499 | .reserved2 = 0, | | |
| 500 | .reserved3 = 0, | | |
| 501 | }); | | |
| 502 | } | | |
| 503 | } else if (mem.eql(u8, segname, "__DATA") or mem.eql(u8, segname, "__DATA_CONST")) { | | |
| 504 | if (self.data_const_section_index != null) continue; | | |
| 505 | | | |
| 506 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 507 | try data_const_seg.addSection(self.allocator, .{ | | |
| 508 | .sectname = makeStaticString("__const"), | | |
| 509 | .segname = makeStaticString("__DATA_CONST"), | | |
| 510 | .addr = 0, | | |
| 511 | .size = 0, | | |
| 512 | .offset = 0, | | |
| 513 | .@"align" = 0, | | |
| 514 | .reloff = 0, | | |
| 515 | .nreloc = 0, | | |
| 516 | .flags = macho.S_REGULAR, | | |
| 517 | .reserved1 = 0, | | |
| 518 | .reserved2 = 0, | | |
| 519 | .reserved3 = 0, | | |
| 520 | }); | | |
| 521 | } | | |
| 522 | }, | 465 | }, |
| 523 | macho.S_CSTRING_LITERALS => { | 466 | macho.S_CSTRING_LITERALS => { |
| 524 | if (self.cstring_section_index != null) continue; | 467 | if (self.cstring_section_index != null) continue; |
| ... | @@ -538,6 +481,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -538,6 +481,7 @@ fn updateMetadata(self: *Zld) !void { |
| 538 | .reserved2 = 0, | 481 | .reserved2 = 0, |
| 539 | .reserved3 = 0, | 482 | .reserved3 = 0, |
| 540 | }); | 483 | }); |
| | 484 | continue; |
| 541 | }, | 485 | }, |
| 542 | macho.S_MOD_INIT_FUNC_POINTERS => { | 486 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| 543 | if (self.mod_init_func_section_index != null) continue; | 487 | if (self.mod_init_func_section_index != null) continue; |
| ... | @@ -557,6 +501,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -557,6 +501,7 @@ fn updateMetadata(self: *Zld) !void { |
| 557 | .reserved2 = 0, | 501 | .reserved2 = 0, |
| 558 | .reserved3 = 0, | 502 | .reserved3 = 0, |
| 559 | }); | 503 | }); |
| | 504 | continue; |
| 560 | }, | 505 | }, |
| 561 | macho.S_MOD_TERM_FUNC_POINTERS => { | 506 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| 562 | if (self.mod_term_func_section_index != null) continue; | 507 | if (self.mod_term_func_section_index != null) continue; |
| ... | @@ -576,6 +521,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -576,6 +521,7 @@ fn updateMetadata(self: *Zld) !void { |
| 576 | .reserved2 = 0, | 521 | .reserved2 = 0, |
| 577 | .reserved3 = 0, | 522 | .reserved3 = 0, |
| 578 | }); | 523 | }); |
| | 524 | continue; |
| 579 | }, | 525 | }, |
| 580 | macho.S_ZEROFILL => { | 526 | macho.S_ZEROFILL => { |
| 581 | if (mem.eql(u8, sectname, "__common")) { | 527 | if (mem.eql(u8, sectname, "__common")) { |
| ... | @@ -615,6 +561,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -615,6 +561,7 @@ fn updateMetadata(self: *Zld) !void { |
| 615 | .reserved3 = 0, | 561 | .reserved3 = 0, |
| 616 | }); | 562 | }); |
| 617 | } | 563 | } |
| | 564 | continue; |
| 618 | }, | 565 | }, |
| 619 | macho.S_THREAD_LOCAL_VARIABLES => { | 566 | macho.S_THREAD_LOCAL_VARIABLES => { |
| 620 | if (self.tlv_section_index != null) continue; | 567 | if (self.tlv_section_index != null) continue; |
| ... | @@ -634,6 +581,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -634,6 +581,7 @@ fn updateMetadata(self: *Zld) !void { |
| 634 | .reserved2 = 0, | 581 | .reserved2 = 0, |
| 635 | .reserved3 = 0, | 582 | .reserved3 = 0, |
| 636 | }); | 583 | }); |
| | 584 | continue; |
| 637 | }, | 585 | }, |
| 638 | macho.S_THREAD_LOCAL_REGULAR => { | 586 | macho.S_THREAD_LOCAL_REGULAR => { |
| 639 | if (self.tlv_data_section_index != null) continue; | 587 | if (self.tlv_data_section_index != null) continue; |
| ... | @@ -653,6 +601,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -653,6 +601,7 @@ fn updateMetadata(self: *Zld) !void { |
| 653 | .reserved2 = 0, | 601 | .reserved2 = 0, |
| 654 | .reserved3 = 0, | 602 | .reserved3 = 0, |
| 655 | }); | 603 | }); |
| | 604 | continue; |
| 656 | }, | 605 | }, |
| 657 | macho.S_THREAD_LOCAL_ZEROFILL => { | 606 | macho.S_THREAD_LOCAL_ZEROFILL => { |
| 658 | if (self.tlv_bss_section_index != null) continue; | 607 | if (self.tlv_bss_section_index != null) continue; |
| ... | @@ -672,58 +621,240 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -672,58 +621,240 @@ fn updateMetadata(self: *Zld) !void { |
| 672 | .reserved2 = 0, | 621 | .reserved2 = 0, |
| 673 | .reserved3 = 0, | 622 | .reserved3 = 0, |
| 674 | }); | 623 | }); |
| 675 | }, | | |
| 676 | macho.S_COALESCED | | | |
| 677 | macho.S_ATTR_NO_TOC | | | |
| 678 | macho.S_ATTR_STRIP_STATIC_SYMS | | | |
| 679 | macho.S_ATTR_LIVE_SUPPORT => { | | |
| 680 | log.debug("TODO __eh_frame section: type 0x{x}, name '{s},{s}'", .{ | | |
| 681 | flags, segname, sectname, | | |
| 682 | }); | | |
| 683 | continue; | 624 | continue; |
| 684 | }, | 625 | }, |
| 685 | macho.S_REGULAR | macho.S_ATTR_DEBUG => { | 626 | macho.S_COALESCED => { |
| 686 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { | 627 | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { |
| 687 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ | 628 | // TODO I believe __eh_frame is currently part of __unwind_info section |
| 688 | flags, segname, sectname, | 629 | // in the latest ld64 output. |
| | 630 | if (self.eh_frame_section_index != null) continue; |
| | 631 | |
| | 632 | self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 633 | try text_seg.addSection(self.allocator, .{ |
| | 634 | .sectname = makeStaticString("__eh_frame"), |
| | 635 | .segname = makeStaticString("__TEXT"), |
| | 636 | .addr = 0, |
| | 637 | .size = 0, |
| | 638 | .offset = 0, |
| | 639 | .@"align" = 0, |
| | 640 | .reloff = 0, |
| | 641 | .nreloc = 0, |
| | 642 | .flags = macho.S_REGULAR, |
| | 643 | .reserved1 = 0, |
| | 644 | .reserved2 = 0, |
| | 645 | .reserved3 = 0, |
| 689 | }); | 646 | }); |
| | 647 | continue; |
| 690 | } | 648 | } |
| | 649 | |
| | 650 | // TODO audit this: is this the right mapping? |
| | 651 | if (self.data_const_section_index != null) continue; |
| | 652 | |
| | 653 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 654 | try data_const_seg.addSection(self.allocator, .{ |
| | 655 | .sectname = makeStaticString("__const"), |
| | 656 | .segname = makeStaticString("__DATA_CONST"), |
| | 657 | .addr = 0, |
| | 658 | .size = 0, |
| | 659 | .offset = 0, |
| | 660 | .@"align" = 0, |
| | 661 | .reloff = 0, |
| | 662 | .nreloc = 0, |
| | 663 | .flags = macho.S_REGULAR, |
| | 664 | .reserved1 = 0, |
| | 665 | .reserved2 = 0, |
| | 666 | .reserved3 = 0, |
| | 667 | }); |
| 691 | continue; | 668 | continue; |
| 692 | }, | 669 | }, |
| 693 | else => { | 670 | macho.S_REGULAR => { |
| | 671 | if (sect.isCode()) { |
| | 672 | if (self.text_section_index != null) continue; |
| | 673 | |
| | 674 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 675 | try text_seg.addSection(self.allocator, .{ |
| | 676 | .sectname = makeStaticString("__text"), |
| | 677 | .segname = makeStaticString("__TEXT"), |
| | 678 | .addr = 0, |
| | 679 | .size = 0, |
| | 680 | .offset = 0, |
| | 681 | .@"align" = 0, |
| | 682 | .reloff = 0, |
| | 683 | .nreloc = 0, |
| | 684 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| | 685 | .reserved1 = 0, |
| | 686 | .reserved2 = 0, |
| | 687 | .reserved3 = 0, |
| | 688 | }); |
| | 689 | continue; |
| | 690 | } |
| | 691 | |
| | 692 | if (sect.isDebug()) { |
| | 693 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| | 694 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| | 695 | sect.flags(), segname, sectname, |
| | 696 | }); |
| | 697 | } |
| | 698 | continue; |
| | 699 | } |
| | 700 | |
| | 701 | if (mem.eql(u8, segname, "__TEXT")) { |
| | 702 | if (mem.eql(u8, sectname, "__ustring")) { |
| | 703 | if (self.ustring_section_index != null) continue; |
| | 704 | |
| | 705 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 706 | try text_seg.addSection(self.allocator, .{ |
| | 707 | .sectname = makeStaticString("__ustring"), |
| | 708 | .segname = makeStaticString("__TEXT"), |
| | 709 | .addr = 0, |
| | 710 | .size = 0, |
| | 711 | .offset = 0, |
| | 712 | .@"align" = 0, |
| | 713 | .reloff = 0, |
| | 714 | .nreloc = 0, |
| | 715 | .flags = macho.S_REGULAR, |
| | 716 | .reserved1 = 0, |
| | 717 | .reserved2 = 0, |
| | 718 | .reserved3 = 0, |
| | 719 | }); |
| | 720 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { |
| | 721 | if (self.gcc_except_tab_section_index != null) continue; |
| | 722 | |
| | 723 | self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 724 | try text_seg.addSection(self.allocator, .{ |
| | 725 | .sectname = makeStaticString("__gcc_except_tab"), |
| | 726 | .segname = makeStaticString("__TEXT"), |
| | 727 | .addr = 0, |
| | 728 | .size = 0, |
| | 729 | .offset = 0, |
| | 730 | .@"align" = 0, |
| | 731 | .reloff = 0, |
| | 732 | .nreloc = 0, |
| | 733 | .flags = macho.S_REGULAR, |
| | 734 | .reserved1 = 0, |
| | 735 | .reserved2 = 0, |
| | 736 | .reserved3 = 0, |
| | 737 | }); |
| | 738 | } else { |
| | 739 | if (self.text_const_section_index != null) continue; |
| | 740 | |
| | 741 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 742 | try text_seg.addSection(self.allocator, .{ |
| | 743 | .sectname = makeStaticString("__const"), |
| | 744 | .segname = makeStaticString("__TEXT"), |
| | 745 | .addr = 0, |
| | 746 | .size = 0, |
| | 747 | .offset = 0, |
| | 748 | .@"align" = 0, |
| | 749 | .reloff = 0, |
| | 750 | .nreloc = 0, |
| | 751 | .flags = macho.S_REGULAR, |
| | 752 | .reserved1 = 0, |
| | 753 | .reserved2 = 0, |
| | 754 | .reserved3 = 0, |
| | 755 | }); |
| | 756 | } |
| | 757 | continue; |
| | 758 | } |
| | 759 | |
| | 760 | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| | 761 | if (self.data_const_section_index != null) continue; |
| | 762 | |
| | 763 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 764 | try data_const_seg.addSection(self.allocator, .{ |
| | 765 | .sectname = makeStaticString("__const"), |
| | 766 | .segname = makeStaticString("__DATA_CONST"), |
| | 767 | .addr = 0, |
| | 768 | .size = 0, |
| | 769 | .offset = 0, |
| | 770 | .@"align" = 0, |
| | 771 | .reloff = 0, |
| | 772 | .nreloc = 0, |
| | 773 | .flags = macho.S_REGULAR, |
| | 774 | .reserved1 = 0, |
| | 775 | .reserved2 = 0, |
| | 776 | .reserved3 = 0, |
| | 777 | }); |
| | 778 | continue; |
| | 779 | } |
| | 780 | |
| | 781 | if (mem.eql(u8, segname, "__DATA")) { |
| | 782 | if (mem.eql(u8, sectname, "__const")) { |
| | 783 | if (self.data_const_section_index != null) continue; |
| | 784 | |
| | 785 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 786 | try data_const_seg.addSection(self.allocator, .{ |
| | 787 | .sectname = makeStaticString("__const"), |
| | 788 | .segname = makeStaticString("__DATA_CONST"), |
| | 789 | .addr = 0, |
| | 790 | .size = 0, |
| | 791 | .offset = 0, |
| | 792 | .@"align" = 0, |
| | 793 | .reloff = 0, |
| | 794 | .nreloc = 0, |
| | 795 | .flags = macho.S_REGULAR, |
| | 796 | .reserved1 = 0, |
| | 797 | .reserved2 = 0, |
| | 798 | .reserved3 = 0, |
| | 799 | }); |
| | 800 | } else { |
| | 801 | if (self.data_section_index != null) continue; |
| | 802 | |
| | 803 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 804 | try data_seg.addSection(self.allocator, .{ |
| | 805 | .sectname = makeStaticString("__data"), |
| | 806 | .segname = makeStaticString("__DATA"), |
| | 807 | .addr = 0, |
| | 808 | .size = 0, |
| | 809 | .offset = 0, |
| | 810 | .@"align" = 0, |
| | 811 | .reloff = 0, |
| | 812 | .nreloc = 0, |
| | 813 | .flags = macho.S_REGULAR, |
| | 814 | .reserved1 = 0, |
| | 815 | .reserved2 = 0, |
| | 816 | .reserved3 = 0, |
| | 817 | }); |
| | 818 | } |
| | 819 | |
| | 820 | continue; |
| | 821 | } |
| | 822 | |
| 694 | if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { | 823 | if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { |
| 695 | log.debug("TODO LLVM bitcode section: type 0x{x}, name '{s},{s}'", .{ | 824 | log.debug("TODO LLVM asm section: type 0x{x}, name '{s},{s}'", .{ |
| 696 | flags, segname, sectname, | 825 | sect.flags(), segname, sectname, |
| 697 | }); | 826 | }); |
| 698 | continue; | 827 | continue; |
| 699 | } | 828 | } |
| 700 | log.err("unhandled section type 0x{x} for '{s},{s}'", .{ flags, segname, sectname }); | | |
| 701 | return error.UnhandledSection; | | |
| 702 | }, | 829 | }, |
| | 830 | else => {}, |
| 703 | } | 831 | } |
| | 832 | |
| | 833 | log.err("{s}: unhandled section type 0x{x} for '{s},{s}'", .{ |
| | 834 | object.name.?, |
| | 835 | sect.flags(), |
| | 836 | segname, |
| | 837 | sectname, |
| | 838 | }); |
| | 839 | return error.UnhandledSection; |
| 704 | } | 840 | } |
| 705 | | 841 | |
| 706 | // Find ideal section alignment. | 842 | // Find ideal section alignment. |
| 707 | for (object_seg.sections.items) |source_sect| { | 843 | for (object.sections.items) |sect| { |
| 708 | if (self.getMatchingSection(source_sect)) |res| { | 844 | if (self.getMatchingSection(sect)) |res| { |
| 709 | const target_seg = &self.load_commands.items[res.seg].Segment; | 845 | const target_seg = &self.load_commands.items[res.seg].Segment; |
| 710 | const target_sect = &target_seg.sections.items[res.sect]; | 846 | const target_sect = &target_seg.sections.items[res.sect]; |
| 711 | target_sect.@"align" = math.max(target_sect.@"align", source_sect.@"align"); | 847 | target_sect.@"align" = math.max(target_sect.@"align", sect.inner.@"align"); |
| 712 | } | 848 | } |
| 713 | } | 849 | } |
| 714 | | 850 | |
| 715 | // Update section mappings | 851 | // Update section mappings |
| 716 | for (object_seg.sections.items) |source_sect, sect_id| { | 852 | for (object.sections.items) |sect, sect_id| { |
| 717 | const source_sect_id = @intCast(u16, sect_id); | 853 | if (self.getMatchingSection(sect)) |res| { |
| 718 | if (self.getMatchingSection(source_sect)) |res| { | 854 | try self.mapAndUpdateSections(object, @intCast(u16, sect_id), res.seg, res.sect); |
| 719 | try self.mapAndUpdateSections(object, source_sect_id, res.seg, res.sect); | | |
| 720 | continue; | 855 | continue; |
| 721 | } | 856 | } |
| 722 | | 857 | log.debug("section '{s},{s}' will be unmapped", .{ sect.segname(), sect.sectname() }); |
| 723 | log.debug("section '{s},{s}' will be unmapped", .{ | | |
| 724 | parseName(&source_sect.segname), | | |
| 725 | parseName(&source_sect.sectname), | | |
| 726 | }); | | |
| 727 | } | 858 | } |
| 728 | } | 859 | } |
| 729 | | 860 | |
| ... | @@ -819,13 +950,13 @@ const MatchingSection = struct { | ... | @@ -819,13 +950,13 @@ const MatchingSection = struct { |
| 819 | sect: u16, | 950 | sect: u16, |
| 820 | }; | 951 | }; |
| 821 | | 952 | |
| 822 | fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | 953 | fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 823 | const segname = parseName(&section.segname); | 954 | const segname = sect.segname(); |
| 824 | const sectname = parseName(&section.sectname); | 955 | const sectname = sect.sectname(); |
| 825 | | 956 | |
| 826 | const res: ?MatchingSection = blk: { | 957 | const res: ?MatchingSection = blk: { |
| 827 | switch (section.flags) { | 958 | switch (sect.sectionType()) { |
| 828 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | 959 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { |
| 829 | break :blk .{ | 960 | break :blk .{ |
| 830 | .seg = self.text_segment_cmd_index.?, | 961 | .seg = self.text_segment_cmd_index.?, |
| 831 | .sect = self.text_const_section_index.?, | 962 | .sect = self.text_const_section_index.?, |
| ... | @@ -855,11 +986,12 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -855,11 +986,12 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 855 | .seg = self.data_segment_cmd_index.?, | 986 | .seg = self.data_segment_cmd_index.?, |
| 856 | .sect = self.common_section_index.?, | 987 | .sect = self.common_section_index.?, |
| 857 | }; | 988 | }; |
| | 989 | } else { |
| | 990 | break :blk .{ |
| | 991 | .seg = self.data_segment_cmd_index.?, |
| | 992 | .sect = self.bss_section_index.?, |
| | 993 | }; |
| 858 | } | 994 | } |
| 859 | break :blk .{ | | |
| 860 | .seg = self.data_segment_cmd_index.?, | | |
| 861 | .sect = self.bss_section_index.?, | | |
| 862 | }; | | |
| 863 | }, | 995 | }, |
| 864 | macho.S_THREAD_LOCAL_VARIABLES => { | 996 | macho.S_THREAD_LOCAL_VARIABLES => { |
| 865 | break :blk .{ | 997 | break :blk .{ |
| ... | @@ -879,31 +1011,57 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -879,31 +1011,57 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 879 | .sect = self.tlv_bss_section_index.?, | 1011 | .sect = self.tlv_bss_section_index.?, |
| 880 | }; | 1012 | }; |
| 881 | }, | 1013 | }, |
| 882 | macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS => { | 1014 | macho.S_COALESCED => { |
| | 1015 | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { |
| | 1016 | break :blk .{ |
| | 1017 | .seg = self.text_segment_cmd_index.?, |
| | 1018 | .sect = self.eh_frame_section_index.?, |
| | 1019 | }; |
| | 1020 | } |
| | 1021 | |
| 883 | break :blk .{ | 1022 | break :blk .{ |
| 884 | .seg = self.text_segment_cmd_index.?, | 1023 | .seg = self.data_const_segment_cmd_index.?, |
| 885 | .sect = self.text_section_index.?, | 1024 | .sect = self.data_const_section_index.?, |
| 886 | }; | 1025 | }; |
| 887 | }, | 1026 | }, |
| 888 | macho.S_REGULAR => { | 1027 | macho.S_REGULAR => { |
| | 1028 | if (sect.isCode()) { |
| | 1029 | break :blk .{ |
| | 1030 | .seg = self.text_segment_cmd_index.?, |
| | 1031 | .sect = self.text_section_index.?, |
| | 1032 | }; |
| | 1033 | } |
| | 1034 | if (sect.isDebug()) { |
| | 1035 | // TODO debug attributes |
| | 1036 | break :blk null; |
| | 1037 | } |
| | 1038 | |
| 889 | if (mem.eql(u8, segname, "__TEXT")) { | 1039 | if (mem.eql(u8, segname, "__TEXT")) { |
| 890 | if (mem.eql(u8, sectname, "__ustring")) { | 1040 | if (mem.eql(u8, sectname, "__ustring")) { |
| 891 | break :blk .{ | 1041 | break :blk .{ |
| 892 | .seg = self.text_segment_cmd_index.?, | 1042 | .seg = self.text_segment_cmd_index.?, |
| 893 | .sect = self.ustring_section_index.?, | 1043 | .sect = self.ustring_section_index.?, |
| 894 | }; | 1044 | }; |
| | 1045 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { |
| | 1046 | break :blk .{ |
| | 1047 | .seg = self.text_segment_cmd_index.?, |
| | 1048 | .sect = self.gcc_except_tab_section_index.?, |
| | 1049 | }; |
| | 1050 | } else { |
| | 1051 | break :blk .{ |
| | 1052 | .seg = self.text_segment_cmd_index.?, |
| | 1053 | .sect = self.text_const_section_index.?, |
| | 1054 | }; |
| 895 | } | 1055 | } |
| 896 | break :blk .{ | | |
| 897 | .seg = self.text_segment_cmd_index.?, | | |
| 898 | .sect = self.text_const_section_index.?, | | |
| 899 | }; | | |
| 900 | } | 1056 | } |
| | 1057 | |
| 901 | if (mem.eql(u8, segname, "__DATA_CONST")) { | 1058 | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| 902 | break :blk .{ | 1059 | break :blk .{ |
| 903 | .seg = self.data_const_segment_cmd_index.?, | 1060 | .seg = self.data_const_segment_cmd_index.?, |
| 904 | .sect = self.data_const_section_index.?, | 1061 | .sect = self.data_const_section_index.?, |
| 905 | }; | 1062 | }; |
| 906 | } | 1063 | } |
| | 1064 | |
| 907 | if (mem.eql(u8, segname, "__DATA")) { | 1065 | if (mem.eql(u8, segname, "__DATA")) { |
| 908 | if (mem.eql(u8, sectname, "__const")) { | 1066 | if (mem.eql(u8, sectname, "__const")) { |
| 909 | break :blk .{ | 1067 | break :blk .{ |
| ... | @@ -916,11 +1074,10 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -916,11 +1074,10 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 916 | .sect = self.data_section_index.?, | 1074 | .sect = self.data_section_index.?, |
| 917 | }; | 1075 | }; |
| 918 | } | 1076 | } |
| | 1077 | |
| 919 | break :blk null; | 1078 | break :blk null; |
| 920 | }, | 1079 | }, |
| 921 | else => { | 1080 | else => break :blk null, |
| 922 | break :blk null; | | |
| 923 | }, | | |
| 924 | } | 1081 | } |
| 925 | }; | 1082 | }; |
| 926 | | 1083 | |
| ... | @@ -946,9 +1103,11 @@ fn sortSections(self: *Zld) !void { | ... | @@ -946,9 +1103,11 @@ fn sortSections(self: *Zld) !void { |
| 946 | &self.text_section_index, | 1103 | &self.text_section_index, |
| 947 | &self.stubs_section_index, | 1104 | &self.stubs_section_index, |
| 948 | &self.stub_helper_section_index, | 1105 | &self.stub_helper_section_index, |
| 949 | &self.text_const_section_index, | 1106 | &self.gcc_except_tab_section_index, |
| 950 | &self.cstring_section_index, | 1107 | &self.cstring_section_index, |
| 951 | &self.ustring_section_index, | 1108 | &self.ustring_section_index, |
| | 1109 | &self.text_const_section_index, |
| | 1110 | &self.eh_frame_section_index, |
| 952 | }; | 1111 | }; |
| 953 | for (indices) |maybe_index| { | 1112 | for (indices) |maybe_index| { |
| 954 | const new_index: u16 = if (maybe_index.*) |index| blk: { | 1113 | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| ... | @@ -1733,7 +1892,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1733,7 +1892,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1733 | for (relocs) |rel| { | 1892 | for (relocs) |rel| { |
| 1734 | switch (rel.@"type") { | 1893 | switch (rel.@"type") { |
| 1735 | .unsigned => continue, | 1894 | .unsigned => continue, |
| 1736 | .got_page, .got_page_off, .got_load, .got => { | 1895 | .got_page, .got_page_off, .got_load, .got, .pointer_to_got => { |
| 1737 | const sym = rel.target.symbol.getTopmostAlias(); | 1896 | const sym = rel.target.symbol.getTopmostAlias(); |
| 1738 | if (sym.got_index != null) continue; | 1897 | if (sym.got_index != null) continue; |
| 1739 | | 1898 | |
| ... | @@ -1751,9 +1910,6 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1751,9 +1910,6 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1751 | | 1910 | |
| 1752 | if (sym.stubs_index != null) continue; | 1911 | if (sym.stubs_index != null) continue; |
| 1753 | if (sym.@"type" != .proxy) continue; | 1912 | if (sym.@"type" != .proxy) continue; |
| 1754 | // if (sym.cast(Symbol.Regular)) |reg| { | | |
| 1755 | // if (!reg.weak_ref) continue; | | |
| 1756 | // } | | |
| 1757 | | 1913 | |
| 1758 | const index = @intCast(u32, self.stubs.items.len); | 1914 | const index = @intCast(u32, self.stubs.items.len); |
| 1759 | sym.stubs_index = index; | 1915 | sym.stubs_index = index; |
| ... | @@ -1864,11 +2020,19 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { | ... | @@ -1864,11 +2020,19 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1864 | }); | 2020 | }); |
| 1865 | } | 2021 | } |
| 1866 | }, | 2022 | }, |
| 1867 | .got_page, .got_page_off, .got_load, .got => { | 2023 | .got_page, .got_page_off, .got_load, .got, .pointer_to_got => { |
| 1868 | const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 2024 | const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1869 | const got = dc_seg.sections.items[self.got_section_index.?]; | 2025 | const got = dc_seg.sections.items[self.got_section_index.?]; |
| 1870 | const final = rel.target.symbol.getTopmostAlias(); | 2026 | const final = rel.target.symbol.getTopmostAlias(); |
| 1871 | args.target_addr = got.addr + final.got_index.? * @sizeOf(u64); | 2027 | const got_index = final.got_index orelse { |
| | 2028 | // TODO remove this when we can link against TAPI files. |
| | 2029 | log.err("undefined reference to symbol '{s}'", .{final.name}); |
| | 2030 | log.err(" | referenced in {s}", .{ |
| | 2031 | rel.target.symbol.cast(Symbol.Unresolved).?.file.name.?, |
| | 2032 | }); |
| | 2033 | return error.UndefinedSymbolReference; |
| | 2034 | }; |
| | 2035 | args.target_addr = got.addr + got_index * @sizeOf(u64); |
| 1872 | }, | 2036 | }, |
| 1873 | else => |tt| { | 2037 | else => |tt| { |
| 1874 | if (tt == .signed and rel.target == .section) { | 2038 | if (tt == .signed and rel.target == .section) { |
| ... | @@ -1934,7 +2098,15 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T | ... | @@ -1934,7 +2098,15 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T |
| 1934 | log.debug(" | symbol stub '{s}'", .{sym.name}); | 2098 | log.debug(" | symbol stub '{s}'", .{sym.name}); |
| 1935 | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 2099 | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1936 | const stubs = segment.sections.items[self.stubs_section_index.?]; | 2100 | const stubs = segment.sections.items[self.stubs_section_index.?]; |
| 1937 | break :blk stubs.addr + proxy.base.stubs_index.? * stubs.reserved2; | 2101 | const stubs_index = proxy.base.stubs_index orelse { |
| | 2102 | // TODO remove this when we can link against TAPI files. |
| | 2103 | log.err("undefined reference to symbol '{s}'", .{final.name}); |
| | 2104 | log.err(" | referenced in {s}", .{ |
| | 2105 | sym.cast(Symbol.Unresolved).?.file.name.?, |
| | 2106 | }); |
| | 2107 | return error.UndefinedSymbolReference; |
| | 2108 | }; |
| | 2109 | break :blk stubs.addr + stubs_index * stubs.reserved2; |
| 1938 | } else { | 2110 | } else { |
| 1939 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym.name}); | 2111 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym.name}); |
| 1940 | return error.FailedToResolveRelocationTarget; | 2112 | return error.FailedToResolveRelocationTarget; |