| author | |
| committer | |
| log | 81e7d8505c086a93accb74e9f1a84abb8ff7cf24 |
| tree | 9f4a8814448537da53d2eeab838672401a024eb5 |
| parent | 77836e08a2384450b5e7933094511b61e3c22140 |
Helper functions such as `commands.sectionName`, etc. should really
belong in `std.macho.section_64` extern struct.6 files changed, 86 insertions(+), 117 deletions(-)
lib/std/macho.zig+52-8| ... | @@ -1,3 +1,5 @@ | ... | @@ -1,3 +1,5 @@ |
| 1 | const std = @import("std"); | ||
| 2 | |||
| 1 | pub const mach_header = extern struct { | 3 | pub const mach_header = extern struct { |
| 2 | magic: u32, | 4 | magic: u32, |
| 3 | cputype: cpu_type_t, | 5 | cputype: cpu_type_t, |
| ... | @@ -9,14 +11,14 @@ pub const mach_header = extern struct { | ... | @@ -9,14 +11,14 @@ pub const mach_header = extern struct { |
| 9 | }; | 11 | }; |
| 10 | 12 | ||
| 11 | pub const mach_header_64 = extern struct { | 13 | pub const mach_header_64 = extern struct { |
| 12 | magic: u32, | 14 | magic: u32 = MH_MAGIC_64, |
| 13 | cputype: cpu_type_t, | 15 | cputype: cpu_type_t = 0, |
| 14 | cpusubtype: cpu_subtype_t, | 16 | cpusubtype: cpu_subtype_t = 0, |
| 15 | filetype: u32, | 17 | filetype: u32 = 0, |
| 16 | ncmds: u32, | 18 | ncmds: u32 = 0, |
| 17 | sizeofcmds: u32, | 19 | sizeofcmds: u32 = 0, |
| 18 | flags: u32, | 20 | flags: u32 = 0, |
| 19 | reserved: u32, | 21 | reserved: u32 = 0, |
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | pub const fat_header = extern struct { | 24 | pub const fat_header = extern struct { |
| ... | @@ -630,6 +632,10 @@ pub const segment_command_64 = extern struct { | ... | @@ -630,6 +632,10 @@ pub const segment_command_64 = extern struct { |
| 630 | /// number of sections in segment | 632 | /// number of sections in segment |
| 631 | nsects: u32 = 0, | 633 | nsects: u32 = 0, |
| 632 | flags: u32 = 0, | 634 | flags: u32 = 0, |
| 635 | |||
| 636 | pub fn segName(seg: segment_command_64) []const u8 { | ||
| 637 | return parseName(&seg.segname); | ||
| 638 | } | ||
| 633 | }; | 639 | }; |
| 634 | 640 | ||
| 635 | /// A segment is made up of zero or more sections. Non-MH_OBJECT files have | 641 | /// A segment is made up of zero or more sections. Non-MH_OBJECT files have |
| ... | @@ -728,8 +734,46 @@ pub const section_64 = extern struct { | ... | @@ -728,8 +734,46 @@ pub const section_64 = extern struct { |
| 728 | 734 | ||
| 729 | /// reserved | 735 | /// reserved |
| 730 | reserved3: u32 = 0, | 736 | reserved3: u32 = 0, |
| 737 | |||
| 738 | pub fn sectName(sect: section_64) []const u8 { | ||
| 739 | return parseName(&sect.sectname); | ||
| 740 | } | ||
| 741 | |||
| 742 | pub fn segName(sect: section_64) []const u8 { | ||
| 743 | return parseName(&sect.segname); | ||
| 744 | } | ||
| 745 | |||
| 746 | pub fn type_(sect: section_64) u8 { | ||
| 747 | return @truncate(u8, sect.flags & 0xff); | ||
| 748 | } | ||
| 749 | |||
| 750 | pub fn attrs(sect: section_64) u32 { | ||
| 751 | return sect.flags & 0xffffff00; | ||
| 752 | } | ||
| 753 | |||
| 754 | pub fn isCode(sect: section_64) bool { | ||
| 755 | const attr = sect.attrs(); | ||
| 756 | return attr & S_ATTR_PURE_INSTRUCTIONS != 0 or attr & S_ATTR_SOME_INSTRUCTIONS != 0; | ||
| 757 | } | ||
| 758 | |||
| 759 | pub fn isDebug(sect: section_64) bool { | ||
| 760 | return sect.attrs() & S_ATTR_DEBUG != 0; | ||
| 761 | } | ||
| 762 | |||
| 763 | pub fn isDontDeadStrip(sect: section_64) bool { | ||
| 764 | return sect.attrs() & S_ATTR_NO_DEAD_STRIP != 0; | ||
| 765 | } | ||
| 766 | |||
| 767 | pub fn isDontDeadStripIfReferencesLive(sect: section_64) bool { | ||
| 768 | return sect.attrs() & S_ATTR_LIVE_SUPPORT != 0; | ||
| 769 | } | ||
| 731 | }; | 770 | }; |
| 732 | 771 | ||
| 772 | fn parseName(name: *const [16]u8) []const u8 { | ||
| 773 | const len = std.mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len; | ||
| 774 | return name[0..len]; | ||
| 775 | } | ||
| 776 | |||
| 733 | pub const nlist = extern struct { | 777 | pub const nlist = extern struct { |
| 734 | n_strx: u32, | 778 | n_strx: u32, |
| 735 | n_type: u8, | 779 | n_type: u8, |
src/link/MachO.zig+23-30| ... | @@ -1324,10 +1324,10 @@ pub const MatchingSection = struct { | ... | @@ -1324,10 +1324,10 @@ pub const MatchingSection = struct { |
| 1324 | }; | 1324 | }; |
| 1325 | 1325 | ||
| 1326 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { | 1326 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { |
| 1327 | const segname = commands.segmentName(sect); | 1327 | const segname = sect.segName(); |
| 1328 | const sectname = commands.sectionName(sect); | 1328 | const sectname = sect.sectName(); |
| 1329 | const res: ?MatchingSection = blk: { | 1329 | const res: ?MatchingSection = blk: { |
| 1330 | switch (commands.sectionType(sect)) { | 1330 | switch (sect.type_()) { |
| 1331 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | 1331 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 1332 | if (self.text_const_section_index == null) { | 1332 | if (self.text_const_section_index == null) { |
| 1333 | self.text_const_section_index = try self.initSection( | 1333 | self.text_const_section_index = try self.initSection( |
| ... | @@ -1579,7 +1579,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1579,7 +1579,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1579 | }; | 1579 | }; |
| 1580 | }, | 1580 | }, |
| 1581 | macho.S_REGULAR => { | 1581 | macho.S_REGULAR => { |
| 1582 | if (commands.sectionIsCode(sect)) { | 1582 | if (sect.isCode()) { |
| 1583 | if (self.text_section_index == null) { | 1583 | if (self.text_section_index == null) { |
| 1584 | self.text_section_index = try self.initSection( | 1584 | self.text_section_index = try self.initSection( |
| 1585 | self.text_segment_cmd_index.?, | 1585 | self.text_segment_cmd_index.?, |
| ... | @@ -1599,7 +1599,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1599,7 +1599,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1599 | .sect = self.text_section_index.?, | 1599 | .sect = self.text_section_index.?, |
| 1600 | }; | 1600 | }; |
| 1601 | } | 1601 | } |
| 1602 | if (commands.sectionIsDebug(sect)) { | 1602 | if (sect.isDebug()) { |
| 1603 | // TODO debug attributes | 1603 | // TODO debug attributes |
| 1604 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { | 1604 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| 1605 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ | 1605 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| ... | @@ -1889,10 +1889,7 @@ fn allocateLocals(self: *MachO) !void { | ... | @@ -1889,10 +1889,7 @@ fn allocateLocals(self: *MachO) !void { |
| 1889 | const sect = seg.sections.items[match.sect]; | 1889 | const sect = seg.sections.items[match.sect]; |
| 1890 | var base_vaddr = sect.addr; | 1890 | var base_vaddr = sect.addr; |
| 1891 | 1891 | ||
| 1892 | log.debug("allocating local symbols in {s},{s}", .{ | 1892 | log.debug("allocating local symbols in {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 1893 | commands.segmentName(sect), | ||
| 1894 | commands.sectionName(sect), | ||
| 1895 | }); | ||
| 1896 | 1893 | ||
| 1897 | while (true) { | 1894 | while (true) { |
| 1898 | const alignment = try math.powi(u32, 2, atom.alignment); | 1895 | const alignment = try math.powi(u32, 2, atom.alignment); |
| ... | @@ -1987,7 +1984,7 @@ fn writeAllAtoms(self: *MachO) !void { | ... | @@ -1987,7 +1984,7 @@ fn writeAllAtoms(self: *MachO) !void { |
| 1987 | defer buffer.deinit(); | 1984 | defer buffer.deinit(); |
| 1988 | try buffer.ensureTotalCapacity(try math.cast(usize, sect.size)); | 1985 | try buffer.ensureTotalCapacity(try math.cast(usize, sect.size)); |
| 1989 | 1986 | ||
| 1990 | log.debug("writing atoms in {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); | 1987 | log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 1991 | 1988 | ||
| 1992 | while (atom.prev) |prev| { | 1989 | while (atom.prev) |prev| { |
| 1993 | atom = prev; | 1990 | atom = prev; |
| ... | @@ -2035,7 +2032,7 @@ fn writeAtoms(self: *MachO) !void { | ... | @@ -2035,7 +2032,7 @@ fn writeAtoms(self: *MachO) !void { |
| 2035 | const sect = seg.sections.items[match.sect]; | 2032 | const sect = seg.sections.items[match.sect]; |
| 2036 | var atom: *Atom = entry.value_ptr.*; | 2033 | var atom: *Atom = entry.value_ptr.*; |
| 2037 | 2034 | ||
| 2038 | log.debug("writing atoms in {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); | 2035 | log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 2039 | 2036 | ||
| 2040 | while (atom.prev) |prev| { | 2037 | while (atom.prev) |prev| { |
| 2041 | atom = prev; | 2038 | atom = prev; |
| ... | @@ -3005,7 +3002,7 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { | ... | @@ -3005,7 +3002,7 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { |
| 3005 | }; | 3002 | }; |
| 3006 | } | 3003 | } |
| 3007 | 3004 | ||
| 3008 | log.debug("{s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); | 3005 | log.debug("{s},{s}", .{ sect.segName(), sect.sectName() }); |
| 3009 | 3006 | ||
| 3010 | while (true) { | 3007 | while (true) { |
| 3011 | const alignment = try math.powi(u32, 2, atom.alignment); | 3008 | const alignment = try math.powi(u32, 2, atom.alignment); |
| ... | @@ -3049,8 +3046,8 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { | ... | @@ -3049,8 +3046,8 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { |
| 3049 | const seg = &self.load_commands.items[match.seg].Segment; | 3046 | const seg = &self.load_commands.items[match.seg].Segment; |
| 3050 | const sect = &seg.sections.items[match.sect]; | 3047 | const sect = &seg.sections.items[match.sect]; |
| 3051 | log.debug("{s},{s} => size: 0x{x}, alignment: 0x{x}", .{ | 3048 | log.debug("{s},{s} => size: 0x{x}, alignment: 0x{x}", .{ |
| 3052 | commands.segmentName(sect.*), | 3049 | sect.segName(), |
| 3053 | commands.sectionName(sect.*), | 3050 | sect.sectName(), |
| 3054 | metadata.size, | 3051 | metadata.size, |
| 3055 | metadata.alignment, | 3052 | metadata.alignment, |
| 3056 | }); | 3053 | }); |
| ... | @@ -4507,8 +4504,8 @@ fn initSection( | ... | @@ -4507,8 +4504,8 @@ fn initSection( |
| 4507 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; | 4504 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; |
| 4508 | const off = self.findFreeSpace(segment_id, alignment_pow_2, padding); | 4505 | const off = self.findFreeSpace(segment_id, alignment_pow_2, padding); |
| 4509 | log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{ | 4506 | log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{ |
| 4510 | commands.segmentName(sect), | 4507 | sect.segName(), |
| 4511 | commands.sectionName(sect), | 4508 | sect.sectName(), |
| 4512 | off, | 4509 | off, |
| 4513 | off + size, | 4510 | off + size, |
| 4514 | }); | 4511 | }); |
| ... | @@ -4596,8 +4593,8 @@ fn growSegment(self: *MachO, seg_id: u16, new_size: u64) !void { | ... | @@ -4596,8 +4593,8 @@ fn growSegment(self: *MachO, seg_id: u16, new_size: u64) !void { |
| 4596 | moved_sect.addr += offset_amt; | 4593 | moved_sect.addr += offset_amt; |
| 4597 | 4594 | ||
| 4598 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | 4595 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| 4599 | commands.segmentName(moved_sect.*), | 4596 | moved_sect.segName(), |
| 4600 | commands.sectionName(moved_sect.*), | 4597 | moved_sect.sectName(), |
| 4601 | moved_sect.offset, | 4598 | moved_sect.offset, |
| 4602 | moved_sect.offset + moved_sect.size, | 4599 | moved_sect.offset + moved_sect.size, |
| 4603 | moved_sect.addr, | 4600 | moved_sect.addr, |
| ... | @@ -4670,8 +4667,8 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { | ... | @@ -4670,8 +4667,8 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { |
| 4670 | moved_sect.addr += offset_amt; | 4667 | moved_sect.addr += offset_amt; |
| 4671 | 4668 | ||
| 4672 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | 4669 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| 4673 | commands.segmentName(moved_sect.*), | 4670 | moved_sect.segName(), |
| 4674 | commands.sectionName(moved_sect.*), | 4671 | moved_sect.sectName(), |
| 4675 | moved_sect.offset, | 4672 | moved_sect.offset, |
| 4676 | moved_sect.offset + moved_sect.size, | 4673 | moved_sect.offset + moved_sect.size, |
| 4677 | moved_sect.addr, | 4674 | moved_sect.addr, |
| ... | @@ -5784,9 +5781,8 @@ fn writeLoadCommands(self: *MachO) !void { | ... | @@ -5784,9 +5781,8 @@ fn writeLoadCommands(self: *MachO) !void { |
| 5784 | 5781 | ||
| 5785 | /// Writes Mach-O file header. | 5782 | /// Writes Mach-O file header. |
| 5786 | fn writeHeader(self: *MachO) !void { | 5783 | fn writeHeader(self: *MachO) !void { |
| 5787 | var header = commands.emptyHeader(.{ | 5784 | var header: macho.mach_header_64 = .{}; |
| 5788 | .flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL, | 5785 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| 5789 | }); | ||
| 5790 | 5786 | ||
| 5791 | switch (self.base.options.target.cpu.arch) { | 5787 | switch (self.base.options.target.cpu.arch) { |
| 5792 | .aarch64 => { | 5788 | .aarch64 => { |
| ... | @@ -5961,10 +5957,7 @@ fn snapshotState(self: *MachO) !void { | ... | @@ -5961,10 +5957,7 @@ fn snapshotState(self: *MachO) !void { |
| 5961 | for (self.section_ordinals.keys()) |key| { | 5957 | for (self.section_ordinals.keys()) |key| { |
| 5962 | const seg = self.load_commands.items[key.seg].Segment; | 5958 | const seg = self.load_commands.items[key.seg].Segment; |
| 5963 | const sect = seg.sections.items[key.sect]; | 5959 | const sect = seg.sections.items[key.sect]; |
| 5964 | const sect_name = try std.fmt.allocPrint(arena, "{s},{s}", .{ | 5960 | const sect_name = try std.fmt.allocPrint(arena, "{s},{s}", .{ sect.segName(), sect.sectName() }); |
| 5965 | commands.segmentName(sect), | ||
| 5966 | commands.sectionName(sect), | ||
| 5967 | }); | ||
| 5968 | try nodes.append(.{ | 5961 | try nodes.append(.{ |
| 5969 | .address = sect.addr, | 5962 | .address = sect.addr, |
| 5970 | .tag = .section_start, | 5963 | .tag = .section_start, |
| ... | @@ -6037,7 +6030,7 @@ fn snapshotState(self: *MachO) !void { | ... | @@ -6037,7 +6030,7 @@ fn snapshotState(self: *MachO) !void { |
| 6037 | const match = self.section_ordinals.keys()[source_sym.n_sect - 1]; | 6030 | const match = self.section_ordinals.keys()[source_sym.n_sect - 1]; |
| 6038 | const match_seg = self.load_commands.items[match.seg].Segment; | 6031 | const match_seg = self.load_commands.items[match.seg].Segment; |
| 6039 | const match_sect = match_seg.sections.items[match.sect]; | 6032 | const match_sect = match_seg.sections.items[match.sect]; |
| 6040 | break :is_tlv commands.sectionType(match_sect) == macho.S_THREAD_LOCAL_VARIABLES; | 6033 | break :is_tlv match_sect.type_() == macho.S_THREAD_LOCAL_VARIABLES; |
| 6041 | }; | 6034 | }; |
| 6042 | if (is_tlv) { | 6035 | if (is_tlv) { |
| 6043 | const match_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 6036 | const match_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| ... | @@ -6206,8 +6199,8 @@ fn logSectionOrdinals(self: MachO) void { | ... | @@ -6206,8 +6199,8 @@ fn logSectionOrdinals(self: MachO) void { |
| 6206 | i + 1, | 6199 | i + 1, |
| 6207 | match.seg, | 6200 | match.seg, |
| 6208 | match.sect, | 6201 | match.sect, |
| 6209 | commands.segmentName(sect), | 6202 | sect.segName(), |
| 6210 | commands.sectionName(sect), | 6203 | sect.sectName(), |
| 6211 | }); | 6204 | }); |
| 6212 | } | 6205 | } |
| 6213 | } | 6206 | } |
src/link/MachO/Atom.zig+2-3| ... | @@ -4,7 +4,6 @@ const std = @import("std"); | ... | @@ -4,7 +4,6 @@ const std = @import("std"); |
| 4 | const build_options = @import("build_options"); | 4 | const build_options = @import("build_options"); |
| 5 | const aarch64 = @import("../../arch/aarch64/bits.zig"); | 5 | const aarch64 = @import("../../arch/aarch64/bits.zig"); |
| 6 | const assert = std.debug.assert; | 6 | const assert = std.debug.assert; |
| 7 | const commands = @import("commands.zig"); | ||
| 8 | const log = std.log.scoped(.link); | 7 | const log = std.log.scoped(.link); |
| 9 | const macho = std.macho; | 8 | const macho = std.macho; |
| 10 | const math = std.math; | 9 | const math = std.math; |
| ... | @@ -492,7 +491,7 @@ fn addPtrBindingOrRebase( | ... | @@ -492,7 +491,7 @@ fn addPtrBindingOrRebase( |
| 492 | const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; | 491 | const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; |
| 493 | const seg = context.macho_file.load_commands.items[match.seg].Segment; | 492 | const seg = context.macho_file.load_commands.items[match.seg].Segment; |
| 494 | const sect = seg.sections.items[match.sect]; | 493 | const sect = seg.sections.items[match.sect]; |
| 495 | const sect_type = commands.sectionType(sect); | 494 | const sect_type = sect.type_(); |
| 496 | 495 | ||
| 497 | const should_rebase = rebase: { | 496 | const should_rebase = rebase: { |
| 498 | if (rel.r_length != 3) break :rebase false; | 497 | if (rel.r_length != 3) break :rebase false; |
| ... | @@ -707,7 +706,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { | ... | @@ -707,7 +706,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { |
| 707 | const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; | 706 | const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; |
| 708 | const seg = macho_file.load_commands.items[match.seg].Segment; | 707 | const seg = macho_file.load_commands.items[match.seg].Segment; |
| 709 | const sect = seg.sections.items[match.sect]; | 708 | const sect = seg.sections.items[match.sect]; |
| 710 | break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES; | 709 | break :is_tlv sect.type_() == macho.S_THREAD_LOCAL_VARIABLES; |
| 711 | }; | 710 | }; |
| 712 | if (is_tlv) { | 711 | if (is_tlv) { |
| 713 | // For TLV relocations, the value specified as a relocation is the displacement from the | 712 | // For TLV relocations, the value specified as a relocation is the displacement from the |
src/link/MachO/DebugSymbols.zig+4-5| ... | @@ -241,8 +241,8 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme | ... | @@ -241,8 +241,8 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme |
| 241 | assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand | 241 | assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand |
| 242 | 242 | ||
| 243 | log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ | 243 | log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ |
| 244 | commands.segmentName(sect), | 244 | sect.segName(), |
| 245 | commands.sectionName(sect), | 245 | sect.sectName(), |
| 246 | off, | 246 | off, |
| 247 | off + size, | 247 | off + size, |
| 248 | }); | 248 | }); |
| ... | @@ -670,9 +670,8 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: Allocator) !void { | ... | @@ -670,9 +670,8 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: Allocator) !void { |
| 670 | } | 670 | } |
| 671 | 671 | ||
| 672 | fn writeHeader(self: *DebugSymbols) !void { | 672 | fn writeHeader(self: *DebugSymbols) !void { |
| 673 | var header = commands.emptyHeader(.{ | 673 | var header: macho.mach_header_64 = .{}; |
| 674 | .filetype = macho.MH_DSYM, | 674 | header.filetype = macho.MH_DSYM; |
| 675 | }); | ||
| 676 | 675 | ||
| 677 | switch (self.base.base.options.target.cpu.arch) { | 676 | switch (self.base.base.options.target.cpu.arch) { |
| 678 | .aarch64 => { | 677 | .aarch64 => { |
src/link/MachO/Object.zig+5-11| ... | @@ -11,14 +11,11 @@ const macho = std.macho; | ... | @@ -11,14 +11,11 @@ const macho = std.macho; |
| 11 | const math = std.math; | 11 | const math = std.math; |
| 12 | const mem = std.mem; | 12 | const mem = std.mem; |
| 13 | const sort = std.sort; | 13 | const sort = std.sort; |
| 14 | const commands = @import("commands.zig"); | ||
| 15 | const segmentName = commands.segmentName; | ||
| 16 | const sectionName = commands.sectionName; | ||
| 17 | const trace = @import("../../tracy.zig").trace; | 14 | const trace = @import("../../tracy.zig").trace; |
| 18 | 15 | ||
| 19 | const Allocator = mem.Allocator; | 16 | const Allocator = mem.Allocator; |
| 20 | const Atom = @import("Atom.zig"); | 17 | const Atom = @import("Atom.zig"); |
| 21 | const LoadCommand = commands.LoadCommand; | 18 | const LoadCommand = @import("commands.zig").LoadCommand; |
| 22 | const MachO = @import("../MachO.zig"); | 19 | const MachO = @import("../MachO.zig"); |
| 23 | 20 | ||
| 24 | file: fs.File, | 21 | file: fs.File, |
| ... | @@ -278,8 +275,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v | ... | @@ -278,8 +275,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v |
| 278 | var seg = cmd.Segment; | 275 | var seg = cmd.Segment; |
| 279 | for (seg.sections.items) |*sect, j| { | 276 | for (seg.sections.items) |*sect, j| { |
| 280 | const index = @intCast(u16, j); | 277 | const index = @intCast(u16, j); |
| 281 | const segname = segmentName(sect.*); | 278 | const segname = sect.segName(); |
| 282 | const sectname = sectionName(sect.*); | 279 | const sectname = sect.sectName(); |
| 283 | if (mem.eql(u8, segname, "__DWARF")) { | 280 | if (mem.eql(u8, segname, "__DWARF")) { |
| 284 | if (mem.eql(u8, sectname, "__debug_info")) { | 281 | if (mem.eql(u8, sectname, "__debug_info")) { |
| 285 | self.dwarf_debug_info_index = index; | 282 | self.dwarf_debug_info_index = index; |
| ... | @@ -424,10 +421,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! | ... | @@ -424,10 +421,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! |
| 424 | 421 | ||
| 425 | for (seg.sections.items) |sect, id| { | 422 | for (seg.sections.items) |sect, id| { |
| 426 | const sect_id = @intCast(u8, id); | 423 | const sect_id = @intCast(u8, id); |
| 427 | log.debug("putting section '{s},{s}' as an Atom", .{ | 424 | log.debug("putting section '{s},{s}' as an Atom", .{ sect.segName(), sect.sectName() }); |
| 428 | segmentName(sect), | ||
| 429 | sectionName(sect), | ||
| 430 | }); | ||
| 431 | 425 | ||
| 432 | // Get matching segment/section in the final artifact. | 426 | // Get matching segment/section in the final artifact. |
| 433 | const match = (try macho_file.getMatchingSection(sect)) orelse { | 427 | const match = (try macho_file.getMatchingSection(sect)) orelse { |
| ... | @@ -479,7 +473,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! | ... | @@ -479,7 +473,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! |
| 479 | const atom = try macho_file.createEmptyAtom(atom_local_sym_index, aligned_size, sect.@"align"); | 473 | const atom = try macho_file.createEmptyAtom(atom_local_sym_index, aligned_size, sect.@"align"); |
| 480 | 474 | ||
| 481 | const is_zerofill = blk: { | 475 | const is_zerofill = blk: { |
| 482 | const section_type = commands.sectionType(sect); | 476 | const section_type = sect.type_(); |
| 483 | break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL; | 477 | break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL; |
| 484 | }; | 478 | }; |
| 485 | if (!is_zerofill) { | 479 | if (!is_zerofill) { |
src/link/MachO/commands.zig-60| ... | @@ -12,28 +12,6 @@ const MachO = @import("../MachO.zig"); | ... | @@ -12,28 +12,6 @@ const MachO = @import("../MachO.zig"); |
| 12 | const makeStaticString = MachO.makeStaticString; | 12 | const makeStaticString = MachO.makeStaticString; |
| 13 | const padToIdeal = MachO.padToIdeal; | 13 | const padToIdeal = MachO.padToIdeal; |
| 14 | 14 | ||
| 15 | pub const HeaderArgs = struct { | ||
| 16 | magic: u32 = macho.MH_MAGIC_64, | ||
| 17 | cputype: macho.cpu_type_t = 0, | ||
| 18 | cpusubtype: macho.cpu_subtype_t = 0, | ||
| 19 | filetype: u32 = 0, | ||
| 20 | flags: u32 = 0, | ||
| 21 | reserved: u32 = 0, | ||
| 22 | }; | ||
| 23 | |||
| 24 | pub fn emptyHeader(args: HeaderArgs) macho.mach_header_64 { | ||
| 25 | return .{ | ||
| 26 | .magic = args.magic, | ||
| 27 | .cputype = args.cputype, | ||
| 28 | .cpusubtype = args.cpusubtype, | ||
| 29 | .filetype = args.filetype, | ||
| 30 | .ncmds = 0, | ||
| 31 | .sizeofcmds = 0, | ||
| 32 | .flags = args.flags, | ||
| 33 | .reserved = args.reserved, | ||
| 34 | }; | ||
| 35 | } | ||
| 36 | |||
| 37 | pub const LoadCommand = union(enum) { | 15 | pub const LoadCommand = union(enum) { |
| 38 | Segment: SegmentCommand, | 16 | Segment: SegmentCommand, |
| 39 | DyldInfoOnly: macho.dyld_info_command, | 17 | DyldInfoOnly: macho.dyld_info_command, |
| ... | @@ -357,44 +335,6 @@ pub fn createLoadDylibCommand( | ... | @@ -357,44 +335,6 @@ pub fn createLoadDylibCommand( |
| 357 | return dylib_cmd; | 335 | return dylib_cmd; |
| 358 | } | 336 | } |
| 359 | 337 | ||
| 360 | fn parseName(name: *const [16]u8) []const u8 { | ||
| 361 | const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len; | ||
| 362 | return name[0..len]; | ||
| 363 | } | ||
| 364 | |||
| 365 | pub fn segmentName(sect: macho.section_64) []const u8 { | ||
| 366 | return parseName(&sect.segname); | ||
| 367 | } | ||
| 368 | |||
| 369 | pub fn sectionName(sect: macho.section_64) []const u8 { | ||
| 370 | return parseName(&sect.sectname); | ||
| 371 | } | ||
| 372 | |||
| 373 | pub fn sectionType(sect: macho.section_64) u8 { | ||
| 374 | return @truncate(u8, sect.flags & 0xff); | ||
| 375 | } | ||
| 376 | |||
| 377 | pub fn sectionAttrs(sect: macho.section_64) u32 { | ||
| 378 | return sect.flags & 0xffffff00; | ||
| 379 | } | ||
| 380 | |||
| 381 | pub fn sectionIsCode(sect: macho.section_64) bool { | ||
| 382 | const attr = sectionAttrs(sect); | ||
| 383 | return attr & macho.S_ATTR_PURE_INSTRUCTIONS != 0 or attr & macho.S_ATTR_SOME_INSTRUCTIONS != 0; | ||
| 384 | } | ||
| 385 | |||
| 386 | pub fn sectionIsDebug(sect: macho.section_64) bool { | ||
| 387 | return sectionAttrs(sect) & macho.S_ATTR_DEBUG != 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | pub fn sectionIsDontDeadStrip(sect: macho.section_64) bool { | ||
| 391 | return sectionAttrs(sect) & macho.S_ATTR_NO_DEAD_STRIP != 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | pub fn sectionIsDontDeadStripIfReferencesLive(sect: macho.section_64) bool { | ||
| 395 | return sectionAttrs(sect) & macho.S_ATTR_LIVE_SUPPORT != 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | fn testRead(allocator: Allocator, buffer: []const u8, expected: anytype) !void { | 338 | fn testRead(allocator: Allocator, buffer: []const u8, expected: anytype) !void { |
| 399 | var stream = io.fixedBufferStream(buffer); | 339 | var stream = io.fixedBufferStream(buffer); |
| 400 | var given = try LoadCommand.read(allocator, stream.reader()); | 340 | var given = try LoadCommand.read(allocator, stream.reader()); |