authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-10 11:46:44+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-10 11:56:51+01:00
log81e7d8505c086a93accb74e9f1a84abb8ff7cf24
tree9f4a8814448537da53d2eeab838672401a024eb5
parent77836e08a2384450b5e7933094511b61e3c22140

macho: move helper functions to libstd

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 @@
1const std = @import("std");
2
1pub const mach_header = extern struct {3pub 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};
1012
11pub const mach_header_64 = extern struct {13pub 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};
2123
22pub const fat_header = extern struct {24pub 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 segment632 /// 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};
634640
635/// A segment is made up of zero or more sections. Non-MH_OBJECT files have641/// 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 {
728734
729 /// reserved735 /// 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};
732771
772fn 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
733pub const nlist = extern struct {777pub 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};
13251325
1326pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection {1326pub 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 attributes1603 // 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;
18911891
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 });
18961893
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));
19891986
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() });
19911988
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.*;
20372034
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() });
20392036
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 }
30073004
3008 log.debug("{s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) });3005 log.debug("{s},{s}", .{ sect.segName(), sect.sectName() });
30093006
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;
45974594
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;
46714668
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 {
57845781
5785/// Writes Mach-O file header.5782/// Writes Mach-O file header.
5786fn writeHeader(self: *MachO) !void {5783fn 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 });
57905786
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");
4const build_options = @import("build_options");4const build_options = @import("build_options");
5const aarch64 = @import("../../arch/aarch64/bits.zig");5const aarch64 = @import("../../arch/aarch64/bits.zig");
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const commands = @import("commands.zig");
8const log = std.log.scoped(.link);7const log = std.log.scoped(.link);
9const macho = std.macho;8const macho = std.macho;
10const math = std.math;9const 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_();
496495
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 the712 // 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 expand241 assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand
242242
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}
671671
672fn writeHeader(self: *DebugSymbols) !void {672fn 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 });
676675
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;
11const math = std.math;11const math = std.math;
12const mem = std.mem;12const mem = std.mem;
13const sort = std.sort;13const sort = std.sort;
14const commands = @import("commands.zig");
15const segmentName = commands.segmentName;
16const sectionName = commands.sectionName;
17const trace = @import("../../tracy.zig").trace;14const trace = @import("../../tracy.zig").trace;
1815
19const Allocator = mem.Allocator;16const Allocator = mem.Allocator;
20const Atom = @import("Atom.zig");17const Atom = @import("Atom.zig");
21const LoadCommand = commands.LoadCommand;18const LoadCommand = @import("commands.zig").LoadCommand;
22const MachO = @import("../MachO.zig");19const MachO = @import("../MachO.zig");
2320
24file: fs.File,21file: 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) !
424421
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 });
431425
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");
480474
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");
12const makeStaticString = MachO.makeStaticString;12const makeStaticString = MachO.makeStaticString;
13const padToIdeal = MachO.padToIdeal;13const padToIdeal = MachO.padToIdeal;
1414
15pub 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
24pub 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
37pub const LoadCommand = union(enum) {15pub 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}
359337
360fn 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
365pub fn segmentName(sect: macho.section_64) []const u8 {
366 return parseName(&sect.segname);
367}
368
369pub fn sectionName(sect: macho.section_64) []const u8 {
370 return parseName(&sect.sectname);
371}
372
373pub fn sectionType(sect: macho.section_64) u8 {
374 return @truncate(u8, sect.flags & 0xff);
375}
376
377pub fn sectionAttrs(sect: macho.section_64) u32 {
378 return sect.flags & 0xffffff00;
379}
380
381pub 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
386pub fn sectionIsDebug(sect: macho.section_64) bool {
387 return sectionAttrs(sect) & macho.S_ATTR_DEBUG != 0;
388}
389
390pub fn sectionIsDontDeadStrip(sect: macho.section_64) bool {
391 return sectionAttrs(sect) & macho.S_ATTR_NO_DEAD_STRIP != 0;
392}
393
394pub fn sectionIsDontDeadStripIfReferencesLive(sect: macho.section_64) bool {
395 return sectionAttrs(sect) & macho.S_ATTR_LIVE_SUPPORT != 0;
396}
397
398fn testRead(allocator: Allocator, buffer: []const u8, expected: anytype) !void {338fn 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());