| ... | ... | @@ -924,7 +924,7 @@ const ElfContents = struct { |
| 924 | 924 | // - unused sections are removed |
| 925 | 925 | // when emitting the debug file: |
| 926 | 926 | // - all sections are kept, but some are emptied and their types is changed to SHT_NOBITS |
| 927 | | // the program header is kept unchanged. (`strip` does update it, but `eu-strip` does not, and it still works) TODO: maybe it can be omitted altogether from debug? |
| 927 | // the program header is kept unchanged. (`strip` does update it, but `eu-strip` does not, and it still works) |
| 928 | 928 | |
| 929 | 929 | const Update = struct { |
| 930 | 930 | action: enum { keep, strip, empty }, |
| ... | ... | @@ -1021,6 +1021,7 @@ const ElfContents = struct { |
| 1021 | 1021 | eof_offset = @sizeOf(elf.Elf64_Ehdr); |
| 1022 | 1022 | |
| 1023 | 1023 | // program header as-is. |
| 1024 | // nb: for only-debug files, removing it appears to work, but is invalid by ELF specifcation. |
| 1024 | 1025 | { |
| 1025 | 1026 | std.debug.assert(updated_elf_header.e_phoff == @sizeOf(elf.Elf64_Ehdr)); |
| 1026 | 1027 | const data = std.mem.sliceAsBytes(self.program_segments); |
| ... | ... | @@ -1164,10 +1165,60 @@ const ElfContents = struct { |
| 1164 | 1165 | cmdbuf.appendAssumeCapacity(.{ .write_data = .{ .data = data, .out_offset = updated_elf_header.e_shoff } }); |
| 1165 | 1166 | } |
| 1166 | 1167 | |
| 1167 | | // write the target files |
| 1168 | | // TODO: pack together contiguous copies (cmdbuf is ordered, by construction) |
| 1169 | | // TODO: fill the paddings with zero or copy from source file |
| 1170 | | for (cmdbuf.items) |cmd| { |
| 1168 | // consolidate holes between writes: |
| 1169 | // by coping original padding data from in_file (by fusing contiguous ranges) |
| 1170 | // by writing zeroes otherwise |
| 1171 | const zeroes = [1]u8{0} ** 4096; |
| 1172 | const consolidated_cmdbuf = blk: { |
| 1173 | var newbuf = std.ArrayList(WriteCmd).init(allocator); |
| 1174 | try newbuf.ensureUnusedCapacity(cmdbuf.items.len * 2); |
| 1175 | var offset: u64 = 0; |
| 1176 | var fused_cmd: ?WriteCmd = null; |
| 1177 | for (cmdbuf.items) |cmd| { |
| 1178 | switch (cmd) { |
| 1179 | .write_data => |data| { |
| 1180 | std.debug.assert(data.out_offset >= offset); |
| 1181 | if (fused_cmd) |prev| { |
| 1182 | newbuf.appendAssumeCapacity(prev); |
| 1183 | fused_cmd = null; |
| 1184 | } |
| 1185 | if (data.out_offset > offset) { |
| 1186 | newbuf.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0 .. @intCast(usize, data.out_offset - offset)], .out_offset = offset } }); |
| 1187 | } |
| 1188 | newbuf.appendAssumeCapacity(cmd); |
| 1189 | offset = data.out_offset + data.data.len; |
| 1190 | }, |
| 1191 | .copy_range => |range| { |
| 1192 | std.debug.assert(range.out_offset >= offset); |
| 1193 | if (fused_cmd) |prev| { |
| 1194 | if (range.in_offset >= prev.copy_range.in_offset + prev.copy_range.len and (range.out_offset - prev.copy_range.out_offset == range.in_offset - prev.copy_range.in_offset)) { |
| 1195 | fused_cmd = .{ .copy_range = .{ |
| 1196 | .in_offset = prev.copy_range.in_offset, |
| 1197 | .out_offset = prev.copy_range.out_offset, |
| 1198 | .len = (range.out_offset + range.len) - prev.copy_range.out_offset, |
| 1199 | } }; |
| 1200 | } else { |
| 1201 | newbuf.appendAssumeCapacity(prev); |
| 1202 | if (range.out_offset > offset) { |
| 1203 | newbuf.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0 .. @intCast(usize, range.out_offset - offset)], .out_offset = offset } }); |
| 1204 | } |
| 1205 | fused_cmd = cmd; |
| 1206 | } |
| 1207 | } else { |
| 1208 | fused_cmd = cmd; |
| 1209 | } |
| 1210 | offset = range.out_offset + range.len; |
| 1211 | }, |
| 1212 | } |
| 1213 | } |
| 1214 | if (fused_cmd) |cmd| { |
| 1215 | newbuf.appendAssumeCapacity(cmd); |
| 1216 | } |
| 1217 | break :blk newbuf.items; |
| 1218 | }; |
| 1219 | |
| 1220 | // write the output file |
| 1221 | for (consolidated_cmdbuf) |cmd| { |
| 1171 | 1222 | switch (cmd) { |
| 1172 | 1223 | .write_data => |data| { |
| 1173 | 1224 | var iovec = [_]std.os.iovec_const{.{ .iov_base = data.data.ptr, .iov_len = data.data.len }}; |