diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-12-10 11:46:44 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-12-10 11:56:51 +0100 |
| commit | 81e7d8505c086a93accb74e9f1a84abb8ff7cf24 (patch) | |
| tree | 9f4a8814448537da53d2eeab838672401a024eb5 /src | |
| parent | 77836e08a2384450b5e7933094511b61e3c22140 (diff) | |
| download | zig-81e7d8505c086a93accb74e9f1a84abb8ff7cf24.tar.gz zig-81e7d8505c086a93accb74e9f1a84abb8ff7cf24.zip | |
macho: move helper functions to libstd
Helper functions such as `commands.sectionName`, etc. should really
belong in `std.macho.section_64` extern struct.
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO.zig | 53 | ||||
| -rw-r--r-- | src/link/MachO/Atom.zig | 5 | ||||
| -rw-r--r-- | src/link/MachO/DebugSymbols.zig | 9 | ||||
| -rw-r--r-- | src/link/MachO/Object.zig | 16 | ||||
| -rw-r--r-- | src/link/MachO/commands.zig | 60 |
5 files changed, 34 insertions, 109 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 12562f8c5e..f255eaba47 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1324,10 +1324,10 @@ pub const MatchingSection = struct { }; pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { - const segname = commands.segmentName(sect); - const sectname = commands.sectionName(sect); + const segname = sect.segName(); + const sectname = sect.sectName(); const res: ?MatchingSection = blk: { - switch (commands.sectionType(sect)) { + switch (sect.type_()) { macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { if (self.text_const_section_index == null) { self.text_const_section_index = try self.initSection( @@ -1579,7 +1579,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio }; }, macho.S_REGULAR => { - if (commands.sectionIsCode(sect)) { + if (sect.isCode()) { if (self.text_section_index == null) { self.text_section_index = try self.initSection( self.text_segment_cmd_index.?, @@ -1599,7 +1599,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio .sect = self.text_section_index.?, }; } - if (commands.sectionIsDebug(sect)) { + if (sect.isDebug()) { // TODO debug attributes if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ @@ -1889,10 +1889,7 @@ fn allocateLocals(self: *MachO) !void { const sect = seg.sections.items[match.sect]; var base_vaddr = sect.addr; - log.debug("allocating local symbols in {s},{s}", .{ - commands.segmentName(sect), - commands.sectionName(sect), - }); + log.debug("allocating local symbols in {s},{s}", .{ sect.segName(), sect.sectName() }); while (true) { const alignment = try math.powi(u32, 2, atom.alignment); @@ -1987,7 +1984,7 @@ fn writeAllAtoms(self: *MachO) !void { defer buffer.deinit(); try buffer.ensureTotalCapacity(try math.cast(usize, sect.size)); - log.debug("writing atoms in {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); + log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() }); while (atom.prev) |prev| { atom = prev; @@ -2035,7 +2032,7 @@ fn writeAtoms(self: *MachO) !void { const sect = seg.sections.items[match.sect]; var atom: *Atom = entry.value_ptr.*; - log.debug("writing atoms in {s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); + log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() }); while (atom.prev) |prev| { atom = prev; @@ -3005,7 +3002,7 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { }; } - log.debug("{s},{s}", .{ commands.segmentName(sect), commands.sectionName(sect) }); + log.debug("{s},{s}", .{ sect.segName(), sect.sectName() }); while (true) { const alignment = try math.powi(u32, 2, atom.alignment); @@ -3049,8 +3046,8 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { const seg = &self.load_commands.items[match.seg].Segment; const sect = &seg.sections.items[match.sect]; log.debug("{s},{s} => size: 0x{x}, alignment: 0x{x}", .{ - commands.segmentName(sect.*), - commands.sectionName(sect.*), + sect.segName(), + sect.sectName(), metadata.size, metadata.alignment, }); @@ -4507,8 +4504,8 @@ fn initSection( const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; const off = self.findFreeSpace(segment_id, alignment_pow_2, padding); log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{ - commands.segmentName(sect), - commands.sectionName(sect), + sect.segName(), + sect.sectName(), off, off + size, }); @@ -4596,8 +4593,8 @@ fn growSegment(self: *MachO, seg_id: u16, new_size: u64) !void { moved_sect.addr += offset_amt; log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ - commands.segmentName(moved_sect.*), - commands.sectionName(moved_sect.*), + moved_sect.segName(), + moved_sect.sectName(), moved_sect.offset, moved_sect.offset + moved_sect.size, moved_sect.addr, @@ -4670,8 +4667,8 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { moved_sect.addr += offset_amt; log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ - commands.segmentName(moved_sect.*), - commands.sectionName(moved_sect.*), + moved_sect.segName(), + moved_sect.sectName(), moved_sect.offset, moved_sect.offset + moved_sect.size, moved_sect.addr, @@ -5784,9 +5781,8 @@ fn writeLoadCommands(self: *MachO) !void { /// Writes Mach-O file header. fn writeHeader(self: *MachO) !void { - var header = commands.emptyHeader(.{ - .flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL, - }); + var header: macho.mach_header_64 = .{}; + header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; switch (self.base.options.target.cpu.arch) { .aarch64 => { @@ -5961,10 +5957,7 @@ fn snapshotState(self: *MachO) !void { for (self.section_ordinals.keys()) |key| { const seg = self.load_commands.items[key.seg].Segment; const sect = seg.sections.items[key.sect]; - const sect_name = try std.fmt.allocPrint(arena, "{s},{s}", .{ - commands.segmentName(sect), - commands.sectionName(sect), - }); + const sect_name = try std.fmt.allocPrint(arena, "{s},{s}", .{ sect.segName(), sect.sectName() }); try nodes.append(.{ .address = sect.addr, .tag = .section_start, @@ -6037,7 +6030,7 @@ fn snapshotState(self: *MachO) !void { const match = self.section_ordinals.keys()[source_sym.n_sect - 1]; const match_seg = self.load_commands.items[match.seg].Segment; const match_sect = match_seg.sections.items[match.sect]; - break :is_tlv commands.sectionType(match_sect) == macho.S_THREAD_LOCAL_VARIABLES; + break :is_tlv match_sect.type_() == macho.S_THREAD_LOCAL_VARIABLES; }; if (is_tlv) { const match_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; @@ -6206,8 +6199,8 @@ fn logSectionOrdinals(self: MachO) void { i + 1, match.seg, match.sect, - commands.segmentName(sect), - commands.sectionName(sect), + sect.segName(), + sect.sectName(), }); } } diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 99693a7da3..c35b4d13ab 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -4,7 +4,6 @@ const std = @import("std"); const build_options = @import("build_options"); const aarch64 = @import("../../arch/aarch64/bits.zig"); const assert = std.debug.assert; -const commands = @import("commands.zig"); const log = std.log.scoped(.link); const macho = std.macho; const math = std.math; @@ -492,7 +491,7 @@ fn addPtrBindingOrRebase( const match = context.macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; const seg = context.macho_file.load_commands.items[match.seg].Segment; const sect = seg.sections.items[match.sect]; - const sect_type = commands.sectionType(sect); + const sect_type = sect.type_(); const should_rebase = rebase: { if (rel.r_length != 3) break :rebase false; @@ -707,7 +706,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { const match = macho_file.section_ordinals.keys()[source_sym.n_sect - 1]; const seg = macho_file.load_commands.items[match.seg].Segment; const sect = seg.sections.items[match.sect]; - break :is_tlv commands.sectionType(sect) == macho.S_THREAD_LOCAL_VARIABLES; + break :is_tlv sect.type_() == macho.S_THREAD_LOCAL_VARIABLES; }; if (is_tlv) { // For TLV relocations, the value specified as a relocation is the displacement from the diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig index 9724a1ae03..49e1462015 100644 --- a/src/link/MachO/DebugSymbols.zig +++ b/src/link/MachO/DebugSymbols.zig @@ -241,8 +241,8 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ - commands.segmentName(sect), - commands.sectionName(sect), + sect.segName(), + sect.sectName(), off, off + size, }); @@ -670,9 +670,8 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: Allocator) !void { } fn writeHeader(self: *DebugSymbols) !void { - var header = commands.emptyHeader(.{ - .filetype = macho.MH_DSYM, - }); + var header: macho.mach_header_64 = .{}; + header.filetype = macho.MH_DSYM; switch (self.base.base.options.target.cpu.arch) { .aarch64 => { diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 671019ff51..6647321944 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -11,14 +11,11 @@ const macho = std.macho; const math = std.math; const mem = std.mem; const sort = std.sort; -const commands = @import("commands.zig"); -const segmentName = commands.segmentName; -const sectionName = commands.sectionName; const trace = @import("../../tracy.zig").trace; const Allocator = mem.Allocator; const Atom = @import("Atom.zig"); -const LoadCommand = commands.LoadCommand; +const LoadCommand = @import("commands.zig").LoadCommand; const MachO = @import("../MachO.zig"); file: fs.File, @@ -278,8 +275,8 @@ pub fn readLoadCommands(self: *Object, allocator: Allocator, reader: anytype) !v var seg = cmd.Segment; for (seg.sections.items) |*sect, j| { const index = @intCast(u16, j); - const segname = segmentName(sect.*); - const sectname = sectionName(sect.*); + const segname = sect.segName(); + const sectname = sect.sectName(); if (mem.eql(u8, segname, "__DWARF")) { if (mem.eql(u8, sectname, "__debug_info")) { self.dwarf_debug_info_index = index; @@ -424,10 +421,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! for (seg.sections.items) |sect, id| { const sect_id = @intCast(u8, id); - log.debug("putting section '{s},{s}' as an Atom", .{ - segmentName(sect), - sectionName(sect), - }); + log.debug("putting section '{s},{s}' as an Atom", .{ sect.segName(), sect.sectName() }); // Get matching segment/section in the final artifact. const match = (try macho_file.getMatchingSection(sect)) orelse { @@ -479,7 +473,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! const atom = try macho_file.createEmptyAtom(atom_local_sym_index, aligned_size, sect.@"align"); const is_zerofill = blk: { - const section_type = commands.sectionType(sect); + const section_type = sect.type_(); break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL; }; if (!is_zerofill) { diff --git a/src/link/MachO/commands.zig b/src/link/MachO/commands.zig index 41ea52b9df..278be33f30 100644 --- a/src/link/MachO/commands.zig +++ b/src/link/MachO/commands.zig @@ -12,28 +12,6 @@ const MachO = @import("../MachO.zig"); const makeStaticString = MachO.makeStaticString; const padToIdeal = MachO.padToIdeal; -pub const HeaderArgs = struct { - magic: u32 = macho.MH_MAGIC_64, - cputype: macho.cpu_type_t = 0, - cpusubtype: macho.cpu_subtype_t = 0, - filetype: u32 = 0, - flags: u32 = 0, - reserved: u32 = 0, -}; - -pub fn emptyHeader(args: HeaderArgs) macho.mach_header_64 { - return .{ - .magic = args.magic, - .cputype = args.cputype, - .cpusubtype = args.cpusubtype, - .filetype = args.filetype, - .ncmds = 0, - .sizeofcmds = 0, - .flags = args.flags, - .reserved = args.reserved, - }; -} - pub const LoadCommand = union(enum) { Segment: SegmentCommand, DyldInfoOnly: macho.dyld_info_command, @@ -357,44 +335,6 @@ pub fn createLoadDylibCommand( return dylib_cmd; } -fn parseName(name: *const [16]u8) []const u8 { - const len = mem.indexOfScalar(u8, name, @as(u8, 0)) orelse name.len; - return name[0..len]; -} - -pub fn segmentName(sect: macho.section_64) []const u8 { - return parseName(§.segname); -} - -pub fn sectionName(sect: macho.section_64) []const u8 { - return parseName(§.sectname); -} - -pub fn sectionType(sect: macho.section_64) u8 { - return @truncate(u8, sect.flags & 0xff); -} - -pub fn sectionAttrs(sect: macho.section_64) u32 { - return sect.flags & 0xffffff00; -} - -pub fn sectionIsCode(sect: macho.section_64) bool { - const attr = sectionAttrs(sect); - return attr & macho.S_ATTR_PURE_INSTRUCTIONS != 0 or attr & macho.S_ATTR_SOME_INSTRUCTIONS != 0; -} - -pub fn sectionIsDebug(sect: macho.section_64) bool { - return sectionAttrs(sect) & macho.S_ATTR_DEBUG != 0; -} - -pub fn sectionIsDontDeadStrip(sect: macho.section_64) bool { - return sectionAttrs(sect) & macho.S_ATTR_NO_DEAD_STRIP != 0; -} - -pub fn sectionIsDontDeadStripIfReferencesLive(sect: macho.section_64) bool { - return sectionAttrs(sect) & macho.S_ATTR_LIVE_SUPPORT != 0; -} - fn testRead(allocator: Allocator, buffer: []const u8, expected: anytype) !void { var stream = io.fixedBufferStream(buffer); var given = try LoadCommand.read(allocator, stream.reader()); |
