| ... | @@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, | ... | @@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| 26 | pagezero_segment_cmd_index: ?u16 = null, | 26 | pagezero_segment_cmd_index: ?u16 = null, |
| 27 | /// __TEXT segment | 27 | /// __TEXT segment |
| 28 | text_segment_cmd_index: ?u16 = null, | 28 | text_segment_cmd_index: ?u16 = null, |
| 29 | /// __DWARF segment | | |
| 30 | dwarf_segment_cmd_index: ?u16 = null, | | |
| 31 | /// __DATA segment | 29 | /// __DATA segment |
| 32 | data_segment_cmd_index: ?u16 = null, | 30 | data_segment_cmd_index: ?u16 = null, |
| 33 | /// __LINKEDIT segment | 31 | /// __LINKEDIT segment |
| 34 | linkedit_segment_cmd_index: ?u16 = null, | 32 | linkedit_segment_cmd_index: ?u16 = null, |
| | 33 | /// __DWARF segment |
| | 34 | dwarf_segment_cmd_index: ?u16 = null, |
| 35 | /// Symbol table | 35 | /// Symbol table |
| 36 | symtab_cmd_index: ?u16 = null, | 36 | symtab_cmd_index: ?u16 = null, |
| 37 | /// UUID load command | 37 | /// UUID load command |
| 38 | uuid_cmd_index: ?u16 = null, | 38 | uuid_cmd_index: ?u16 = null, |
| 39 | | 39 | |
| | 40 | /// Index into __TEXT,__text section. |
| | 41 | text_section_index: ?u16 = null, |
| | 42 | |
| 40 | header_dirty: bool = false, | 43 | header_dirty: bool = false, |
| 41 | load_commands_dirty: bool = false, | 44 | load_commands_dirty: bool = false, |
| 42 | | 45 | |
| ... | @@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void | ... | @@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void |
| 58 | self.header = header; | 61 | self.header = header; |
| 59 | self.header_dirty = true; | 62 | self.header_dirty = true; |
| 60 | } | 63 | } |
| | 64 | if (self.pagezero_segment_cmd_index == null) { |
| | 65 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 66 | const base_cmd = self.base.load_commands.items[self.base.pagezero_segment_cmd_index.?].Segment; |
| | 67 | try self.copySegmentCommand(allocator, base_cmd); |
| | 68 | } |
| | 69 | if (self.text_segment_cmd_index == null) { |
| | 70 | self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 71 | const base_cmd = self.base.load_commands.items[self.base.text_segment_cmd_index.?].Segment; |
| | 72 | try self.copySegmentCommand(allocator, base_cmd); |
| | 73 | } |
| | 74 | if (self.data_segment_cmd_index == null) outer: { |
| | 75 | if (self.base.data_segment_cmd_index == null) break :outer; // __DATA is optional |
| | 76 | self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| | 77 | const base_cmd = self.base.load_commands.items[self.base.data_segment_cmd_index.?].Segment; |
| | 78 | try self.copySegmentCommand(allocator, base_cmd); |
| | 79 | } |
| 61 | if (self.uuid_cmd_index == null) { | 80 | if (self.uuid_cmd_index == null) { |
| 62 | const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?]; | 81 | const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?]; |
| 63 | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); | 82 | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); |
| ... | @@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void { | ... | @@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void { |
| 81 | self.file.close(); | 100 | self.file.close(); |
| 82 | } | 101 | } |
| 83 | | 102 | |
| | 103 | fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !void { |
| | 104 | var cmd = SegmentCommand.empty(.{ |
| | 105 | .cmd = macho.LC_SEGMENT_64, |
| | 106 | .cmdsize = base_cmd.inner.cmdsize, |
| | 107 | .segname = undefined, |
| | 108 | .vmaddr = base_cmd.inner.vmaddr, |
| | 109 | .vmsize = base_cmd.inner.vmsize, |
| | 110 | .fileoff = 0, |
| | 111 | .filesize = 0, |
| | 112 | .maxprot = base_cmd.inner.maxprot, |
| | 113 | .initprot = base_cmd.inner.initprot, |
| | 114 | .nsects = base_cmd.inner.nsects, |
| | 115 | .flags = base_cmd.inner.flags, |
| | 116 | }); |
| | 117 | mem.copy(u8, &cmd.inner.segname, &base_cmd.inner.segname); |
| | 118 | |
| | 119 | try cmd.sections.ensureCapacity(allocator, cmd.inner.nsects); |
| | 120 | for (base_cmd.sections.items) |base_sect, i| { |
| | 121 | var sect = macho.section_64{ |
| | 122 | .sectname = undefined, |
| | 123 | .segname = undefined, |
| | 124 | .addr = base_sect.addr, |
| | 125 | .size = base_sect.size, |
| | 126 | .offset = 0, |
| | 127 | .@"align" = base_sect.@"align", |
| | 128 | .reloff = 0, |
| | 129 | .nreloc = 0, |
| | 130 | .flags = base_sect.flags, |
| | 131 | .reserved1 = base_sect.reserved1, |
| | 132 | .reserved2 = base_sect.reserved2, |
| | 133 | .reserved3 = base_sect.reserved3, |
| | 134 | }; |
| | 135 | mem.copy(u8, &sect.sectname, &base_sect.sectname); |
| | 136 | mem.copy(u8, &sect.segname, &base_sect.segname); |
| | 137 | |
| | 138 | if (self.base.text_section_index.? == i) { |
| | 139 | self.text_section_index = @intCast(u16, i); |
| | 140 | } |
| | 141 | |
| | 142 | cmd.sections.appendAssumeCapacity(sect); |
| | 143 | } |
| | 144 | |
| | 145 | try self.load_commands.append(allocator, .{ .Segment = cmd }); |
| | 146 | self.header_dirty = true; |
| | 147 | self.load_commands_dirty = true; |
| | 148 | } |
| | 149 | |
| 84 | /// Writes all load commands and section headers. | 150 | /// Writes all load commands and section headers. |
| 85 | fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void { | 151 | fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void { |
| 86 | if (!self.load_commands_dirty) return; | 152 | if (!self.load_commands_dirty) return; |