| ... | @@ -442,6 +442,25 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -442,6 +442,25 @@ fn updateMetadata(self: *Zld) !void { |
| 442 | const flags = source_sect.flags; | 442 | const flags = source_sect.flags; |
| 443 | | 443 | |
| 444 | switch (flags) { | 444 | switch (flags) { |
| | 445 | macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS => { |
| | 446 | if (self.text_section_index != null) continue; |
| | 447 | |
| | 448 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 449 | try text_seg.addSection(self.allocator, .{ |
| | 450 | .sectname = makeStaticString("__text"), |
| | 451 | .segname = makeStaticString("__TEXT"), |
| | 452 | .addr = 0, |
| | 453 | .size = 0, |
| | 454 | .offset = 0, |
| | 455 | .@"align" = 0, |
| | 456 | .reloff = 0, |
| | 457 | .nreloc = 0, |
| | 458 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| | 459 | .reserved1 = 0, |
| | 460 | .reserved2 = 0, |
| | 461 | .reserved3 = 0, |
| | 462 | }); |
| | 463 | }, |
| 445 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | 464 | macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 446 | if (mem.eql(u8, segname, "__TEXT")) { | 465 | if (mem.eql(u8, segname, "__TEXT")) { |
| 447 | if (mem.eql(u8, sectname, "__ustring")) { | 466 | if (mem.eql(u8, sectname, "__ustring")) { |
| ... | @@ -481,8 +500,7 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -481,8 +500,7 @@ fn updateMetadata(self: *Zld) !void { |
| 481 | .reserved3 = 0, | 500 | .reserved3 = 0, |
| 482 | }); | 501 | }); |
| 483 | } | 502 | } |
| 484 | } else if (mem.eql(u8, segname, "__DATA")) { | 503 | } else if (mem.eql(u8, segname, "__DATA") or mem.eql(u8, segname, "__DATA_CONST")) { |
| 485 | if (!mem.eql(u8, sectname, "__const")) continue; | | |
| 486 | if (self.data_const_section_index != null) continue; | 504 | if (self.data_const_section_index != null) continue; |
| 487 | | 505 | |
| 488 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | 506 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| ... | @@ -503,7 +521,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -503,7 +521,6 @@ fn updateMetadata(self: *Zld) !void { |
| 503 | } | 521 | } |
| 504 | }, | 522 | }, |
| 505 | macho.S_CSTRING_LITERALS => { | 523 | macho.S_CSTRING_LITERALS => { |
| 506 | if (!mem.eql(u8, segname, "__TEXT")) continue; | | |
| 507 | if (self.cstring_section_index != null) continue; | 524 | if (self.cstring_section_index != null) continue; |
| 508 | | 525 | |
| 509 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); | 526 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); |
| ... | @@ -523,7 +540,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -523,7 +540,6 @@ fn updateMetadata(self: *Zld) !void { |
| 523 | }); | 540 | }); |
| 524 | }, | 541 | }, |
| 525 | macho.S_MOD_INIT_FUNC_POINTERS => { | 542 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| 526 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 527 | if (self.mod_init_func_section_index != null) continue; | 543 | if (self.mod_init_func_section_index != null) continue; |
| 528 | | 544 | |
| 529 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | 545 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| ... | @@ -543,7 +559,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -543,7 +559,6 @@ fn updateMetadata(self: *Zld) !void { |
| 543 | }); | 559 | }); |
| 544 | }, | 560 | }, |
| 545 | macho.S_MOD_TERM_FUNC_POINTERS => { | 561 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| 546 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 547 | if (self.mod_term_func_section_index != null) continue; | 562 | if (self.mod_term_func_section_index != null) continue; |
| 548 | | 563 | |
| 549 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | 564 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| ... | @@ -563,7 +578,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -563,7 +578,6 @@ fn updateMetadata(self: *Zld) !void { |
| 563 | }); | 578 | }); |
| 564 | }, | 579 | }, |
| 565 | macho.S_ZEROFILL => { | 580 | macho.S_ZEROFILL => { |
| 566 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 567 | if (mem.eql(u8, sectname, "__common")) { | 581 | if (mem.eql(u8, sectname, "__common")) { |
| 568 | if (self.common_section_index != null) continue; | 582 | if (self.common_section_index != null) continue; |
| 569 | | 583 | |
| ... | @@ -603,7 +617,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -603,7 +617,6 @@ fn updateMetadata(self: *Zld) !void { |
| 603 | } | 617 | } |
| 604 | }, | 618 | }, |
| 605 | macho.S_THREAD_LOCAL_VARIABLES => { | 619 | macho.S_THREAD_LOCAL_VARIABLES => { |
| 606 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 607 | if (self.tlv_section_index != null) continue; | 620 | if (self.tlv_section_index != null) continue; |
| 608 | | 621 | |
| 609 | self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); | 622 | self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); |
| ... | @@ -623,7 +636,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -623,7 +636,6 @@ fn updateMetadata(self: *Zld) !void { |
| 623 | }); | 636 | }); |
| 624 | }, | 637 | }, |
| 625 | macho.S_THREAD_LOCAL_REGULAR => { | 638 | macho.S_THREAD_LOCAL_REGULAR => { |
| 626 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 627 | if (self.tlv_data_section_index != null) continue; | 639 | if (self.tlv_data_section_index != null) continue; |
| 628 | | 640 | |
| 629 | self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); | 641 | self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); |
| ... | @@ -643,7 +655,6 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -643,7 +655,6 @@ fn updateMetadata(self: *Zld) !void { |
| 643 | }); | 655 | }); |
| 644 | }, | 656 | }, |
| 645 | macho.S_THREAD_LOCAL_ZEROFILL => { | 657 | macho.S_THREAD_LOCAL_ZEROFILL => { |
| 646 | if (!mem.eql(u8, segname, "__DATA")) continue; | | |
| 647 | if (self.tlv_bss_section_index != null) continue; | 658 | if (self.tlv_bss_section_index != null) continue; |
| 648 | | 659 | |
| 649 | self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); | 660 | self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| ... | @@ -662,8 +673,32 @@ fn updateMetadata(self: *Zld) !void { | ... | @@ -662,8 +673,32 @@ fn updateMetadata(self: *Zld) !void { |
| 662 | .reserved3 = 0, | 673 | .reserved3 = 0, |
| 663 | }); | 674 | }); |
| 664 | }, | 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; |
| | 684 | }, |
| | 685 | macho.S_REGULAR | macho.S_ATTR_DEBUG => { |
| | 686 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| | 687 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| | 688 | flags, segname, sectname, |
| | 689 | }); |
| | 690 | } |
| | 691 | continue; |
| | 692 | }, |
| 665 | else => { | 693 | else => { |
| 666 | log.debug("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); | 694 | 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}'", .{ |
| | 696 | flags, segname, sectname, |
| | 697 | }); |
| | 698 | continue; |
| | 699 | } |
| | 700 | log.err("unhandled section type 0x{x} for '{s},{s}'", .{ flags, segname, sectname }); |
| | 701 | return error.UnhandledSection; |
| 667 | }, | 702 | }, |
| 668 | } | 703 | } |
| 669 | } | 704 | } |
| ... | @@ -857,24 +892,29 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -857,24 +892,29 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 857 | .seg = self.text_segment_cmd_index.?, | 892 | .seg = self.text_segment_cmd_index.?, |
| 858 | .sect = self.ustring_section_index.?, | 893 | .sect = self.ustring_section_index.?, |
| 859 | }; | 894 | }; |
| 860 | } else { | | |
| 861 | break :blk .{ | | |
| 862 | .seg = self.text_segment_cmd_index.?, | | |
| 863 | .sect = self.text_const_section_index.?, | | |
| 864 | }; | | |
| 865 | } | 895 | } |
| 866 | } else if (mem.eql(u8, segname, "__DATA")) { | 896 | break :blk .{ |
| 867 | if (mem.eql(u8, sectname, "__data")) { | 897 | .seg = self.text_segment_cmd_index.?, |
| 868 | break :blk .{ | 898 | .sect = self.text_const_section_index.?, |
| 869 | .seg = self.data_segment_cmd_index.?, | 899 | }; |
| 870 | .sect = self.data_section_index.?, | 900 | } |
| 871 | }; | 901 | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| 872 | } else if (mem.eql(u8, sectname, "__const")) { | 902 | break :blk .{ |
| | 903 | .seg = self.data_const_segment_cmd_index.?, |
| | 904 | .sect = self.data_const_section_index.?, |
| | 905 | }; |
| | 906 | } |
| | 907 | if (mem.eql(u8, segname, "__DATA")) { |
| | 908 | if (mem.eql(u8, sectname, "__const")) { |
| 873 | break :blk .{ | 909 | break :blk .{ |
| 874 | .seg = self.data_const_segment_cmd_index.?, | 910 | .seg = self.data_const_segment_cmd_index.?, |
| 875 | .sect = self.data_const_section_index.?, | 911 | .sect = self.data_const_section_index.?, |
| 876 | }; | 912 | }; |
| 877 | } | 913 | } |
| | 914 | break :blk .{ |
| | 915 | .seg = self.data_segment_cmd_index.?, |
| | 916 | .sect = self.data_section_index.?, |
| | 917 | }; |
| 878 | } | 918 | } |
| 879 | break :blk null; | 919 | break :blk null; |
| 880 | }, | 920 | }, |
| ... | @@ -1901,7 +1941,12 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T | ... | @@ -1901,7 +1941,12 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T |
| 1901 | } | 1941 | } |
| 1902 | }, | 1942 | }, |
| 1903 | .section => |sect_id| { | 1943 | .section => |sect_id| { |
| | 1944 | log.debug(" | section offset", .{}); |
| 1904 | const source_sect = object.sections.items[sect_id]; | 1945 | const source_sect = object.sections.items[sect_id]; |
| | 1946 | log.debug(" | section '{s},{s}'", .{ |
| | 1947 | parseName(&source_sect.inner.segname), |
| | 1948 | parseName(&source_sect.inner.sectname), |
| | 1949 | }); |
| 1905 | const target_map = source_sect.target_map orelse unreachable; | 1950 | const target_map = source_sect.target_map orelse unreachable; |
| 1906 | const target_seg = self.load_commands.items[target_map.segment_id].Segment; | 1951 | const target_seg = self.load_commands.items[target_map.segment_id].Segment; |
| 1907 | const target_sect = target_seg.sections.items[target_map.section_id]; | 1952 | const target_sect = target_seg.sections.items[target_map.section_id]; |