authorgravatar for xavierb@gmail.comXavier Bouchoux <xavierb@gmail.com> 2023-08-12 06:48:35+00:00
committergravatar for xavierb@gmail.comXavier Bouchoux <xavierb@gmail.com> 2023-08-12 09:54:20+02:00
logaecc15391a4c37a4504d29cb7e3179990b180773
tree26548183a2606900d3534ea4a3d70ef3add6d437
parent5e0107fbce8f33f84af232c3edc912a81615175f

objcpy: preserve the mode when striping an elf file.

+ clean some @as()

1 files changed, 31 insertions(+), 23 deletions(-)

src/objcopy.zig+31-23
...@@ -104,9 +104,6 @@ pub fn cmdObjCopy(...@@ -104,9 +104,6 @@ pub fn cmdObjCopy(
104 fatal("unable to open '{s}': {s}", .{ input, @errorName(err) });104 fatal("unable to open '{s}': {s}", .{ input, @errorName(err) });
105 defer in_file.close();105 defer in_file.close();
106106
107 var out_file = try fs.cwd().createFile(output, .{});
108 defer out_file.close();
109
110 const elf_hdr = std.elf.Header.read(in_file) catch |err| switch (err) {107 const elf_hdr = std.elf.Header.read(in_file) catch |err| switch (err) {
111 error.InvalidElfMagic => fatal("not an ELF file: '{s}'", .{input}),108 error.InvalidElfMagic => fatal("not an ELF file: '{s}'", .{input}),
112 else => fatal("unable to read '{s}': {s}", .{ input, @errorName(err) }),109 else => fatal("unable to read '{s}': {s}", .{ input, @errorName(err) }),
...@@ -126,6 +123,17 @@ pub fn cmdObjCopy(...@@ -126,6 +123,17 @@ pub fn cmdObjCopy(
126 }123 }
127 };124 };
128125
126 const mode = mode: {
127 if (out_fmt != .elf or !only_keep_debug)
128 break :mode fs.File.default_mode;
129 if (in_file.stat()) |stat|
130 break :mode stat.mode
131 else |_|
132 break :mode fs.File.default_mode;
133 };
134 var out_file = try fs.cwd().createFile(output, .{ .mode = mode });
135 defer out_file.close();
136
129 switch (out_fmt) {137 switch (out_fmt) {
130 .hex, .raw => {138 .hex, .raw => {
131 if (strip_debug or strip_all or only_keep_debug)139 if (strip_debug or strip_all or only_keep_debug)
...@@ -345,7 +353,7 @@ const BinaryElfOutput = struct {...@@ -345,7 +353,7 @@ const BinaryElfOutput = struct {
345353
346 const shstrtab_shdr = (try section_headers.next()).?;354 const shstrtab_shdr = (try section_headers.next()).?;
347355
348 const buffer = try allocator.alloc(u8, @as(usize, @intCast(shstrtab_shdr.sh_size)));356 const buffer = try allocator.alloc(u8, @intCast(shstrtab_shdr.sh_size));
349 errdefer allocator.free(buffer);357 errdefer allocator.free(buffer);
350358
351 const num_read = try elf_file.preadAll(buffer, shstrtab_shdr.sh_offset);359 const num_read = try elf_file.preadAll(buffer, shstrtab_shdr.sh_offset);
...@@ -363,7 +371,7 @@ const BinaryElfOutput = struct {...@@ -363,7 +371,7 @@ const BinaryElfOutput = struct {
363371
364 newSection.binaryOffset = 0;372 newSection.binaryOffset = 0;
365 newSection.elfOffset = section.sh_offset;373 newSection.elfOffset = section.sh_offset;
366 newSection.fileSize = @as(usize, @intCast(section.sh_size));374 newSection.fileSize = @intCast(section.sh_size);
367 newSection.segment = null;375 newSection.segment = null;
368376
369 newSection.name = if (self.shstrtab) |shstrtab|377 newSection.name = if (self.shstrtab) |shstrtab|
...@@ -382,7 +390,7 @@ const BinaryElfOutput = struct {...@@ -382,7 +390,7 @@ const BinaryElfOutput = struct {
382390
383 newSegment.physicalAddress = if (phdr.p_paddr != 0) phdr.p_paddr else phdr.p_vaddr;391 newSegment.physicalAddress = if (phdr.p_paddr != 0) phdr.p_paddr else phdr.p_vaddr;
384 newSegment.virtualAddress = phdr.p_vaddr;392 newSegment.virtualAddress = phdr.p_vaddr;
385 newSegment.fileSize = @as(usize, @intCast(phdr.p_filesz));393 newSegment.fileSize = @intCast(phdr.p_filesz);
386 newSegment.elfOffset = phdr.p_offset;394 newSegment.elfOffset = phdr.p_offset;
387 newSegment.binaryOffset = 0;395 newSegment.binaryOffset = 0;
388 newSegment.firstSection = null;396 newSegment.firstSection = null;
...@@ -478,8 +486,8 @@ const HexWriter = struct {...@@ -478,8 +486,8 @@ const HexWriter = struct {
478 const MAX_PAYLOAD_LEN: u8 = 16;486 const MAX_PAYLOAD_LEN: u8 = 16;
479487
480 fn addressParts(address: u16) [2]u8 {488 fn addressParts(address: u16) [2]u8 {
481 const msb = @as(u8, @truncate(address >> 8));489 const msb: u8 = @truncate(address >> 8);
482 const lsb = @as(u8, @truncate(address));490 const lsb: u8 = @truncate(address);
483 return [2]u8{ msb, lsb };491 return [2]u8{ msb, lsb };
484 }492 }
485493
...@@ -508,14 +516,14 @@ const HexWriter = struct {...@@ -508,14 +516,14 @@ const HexWriter = struct {
508516
509 fn Data(address: u32, data: []const u8) Record {517 fn Data(address: u32, data: []const u8) Record {
510 return Record{518 return Record{
511 .address = @as(u16, @intCast(address % 0x10000)),519 .address = @intCast(address % 0x10000),
512 .payload = .{ .Data = data },520 .payload = .{ .Data = data },
513 };521 };
514 }522 }
515523
516 fn Address(address: u32) Record {524 fn Address(address: u32) Record {
517 assert(address > 0xFFFF);525 assert(address > 0xFFFF);
518 const segment = @as(u16, @intCast(address / 0x10000));526 const segment: u16 = @intCast(address / 0x10000);
519 if (address > 0xFFFFF) {527 if (address > 0xFFFFF) {
520 return Record{528 return Record{
521 .address = 0,529 .address = 0,
...@@ -540,7 +548,7 @@ const HexWriter = struct {...@@ -540,7 +548,7 @@ const HexWriter = struct {
540 fn checksum(self: Record) u8 {548 fn checksum(self: Record) u8 {
541 const payload_bytes = self.getPayloadBytes();549 const payload_bytes = self.getPayloadBytes();
542550
543 var sum: u8 = @as(u8, @intCast(payload_bytes.len));551 var sum: u8 = @intCast(payload_bytes.len);
544 const parts = addressParts(self.address);552 const parts = addressParts(self.address);
545 sum +%= parts[0];553 sum +%= parts[0];
546 sum +%= parts[1];554 sum +%= parts[1];
...@@ -574,10 +582,10 @@ const HexWriter = struct {...@@ -574,10 +582,10 @@ const HexWriter = struct {
574 var buf: [MAX_PAYLOAD_LEN]u8 = undefined;582 var buf: [MAX_PAYLOAD_LEN]u8 = undefined;
575 var bytes_read: usize = 0;583 var bytes_read: usize = 0;
576 while (bytes_read < segment.fileSize) {584 while (bytes_read < segment.fileSize) {
577 const row_address = @as(u32, @intCast(segment.physicalAddress + bytes_read));585 const row_address: u32 = @intCast(segment.physicalAddress + bytes_read);
578586
579 const remaining = segment.fileSize - bytes_read;587 const remaining = segment.fileSize - bytes_read;
580 const to_read = @as(usize, @intCast(@min(remaining, MAX_PAYLOAD_LEN)));588 const to_read: usize = @intCast(@min(remaining, MAX_PAYLOAD_LEN));
581 const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read);589 const did_read = try elf_file.preadAll(buf[0..to_read], segment.elfOffset + bytes_read);
582 if (did_read < to_read) return error.UnexpectedEOF;590 if (did_read < to_read) return error.UnexpectedEOF;
583591
...@@ -593,7 +601,7 @@ const HexWriter = struct {...@@ -593,7 +601,7 @@ const HexWriter = struct {
593 try Record.Address(address).write(self.out_file);601 try Record.Address(address).write(self.out_file);
594 }602 }
595 try record.write(self.out_file);603 try record.write(self.out_file);
596 self.prev_addr = @as(u32, @intCast(record.address + data.len));604 self.prev_addr = @intCast(record.address + data.len);
597 }605 }
598606
599 fn writeEOF(self: HexWriter) File.WriteError!void {607 fn writeEOF(self: HexWriter) File.WriteError!void {
...@@ -814,7 +822,7 @@ fn ElfFile(comptime is_64: bool) type {...@@ -814,7 +822,7 @@ fn ElfFile(comptime is_64: bool) type {
814 const need_strings = (idx == header.shstrndx);822 const need_strings = (idx == header.shstrndx);
815823
816 if (need_data or need_strings) {824 if (need_data or need_strings) {
817 const buffer = try allocator.alignedAlloc(u8, section_memory_align, @as(usize, @intCast(section.section.sh_size)));825 const buffer = try allocator.alignedAlloc(u8, section_memory_align, @intCast(section.section.sh_size));
818 const bytes_read = try in_file.preadAll(buffer, section.section.sh_offset);826 const bytes_read = try in_file.preadAll(buffer, section.section.sh_offset);
819 if (bytes_read != section.section.sh_size) return error.TRUNCATED_ELF;827 if (bytes_read != section.section.sh_size) return error.TRUNCATED_ELF;
820 section.payload = buffer;828 section.payload = buffer;
...@@ -935,7 +943,7 @@ fn ElfFile(comptime is_64: bool) type {...@@ -935,7 +943,7 @@ fn ElfFile(comptime is_64: bool) type {
935 const update = &sections_update[self.raw_elf_header.e_shstrndx];943 const update = &sections_update[self.raw_elf_header.e_shstrndx];
936944
937 const name: []const u8 = ".gnu_debuglink";945 const name: []const u8 = ".gnu_debuglink";
938 const new_offset = @as(u32, @intCast(strtab.payload.?.len));946 const new_offset: u32 = @intCast(strtab.payload.?.len);
939 const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1);947 const buf = try allocator.alignedAlloc(u8, section_memory_align, new_offset + name.len + 1);
940 @memcpy(buf[0..new_offset], strtab.payload.?);948 @memcpy(buf[0..new_offset], strtab.payload.?);
941 @memcpy(buf[new_offset..][0..name.len], name);949 @memcpy(buf[new_offset..][0..name.len], name);
...@@ -965,7 +973,7 @@ fn ElfFile(comptime is_64: bool) type {...@@ -965,7 +973,7 @@ fn ElfFile(comptime is_64: bool) type {
965 update.payload = payload;973 update.payload = payload;
966 update.section = section.section;974 update.section = section.section;
967 update.section.?.sh_addralign = @alignOf(Elf_Chdr);975 update.section.?.sh_addralign = @alignOf(Elf_Chdr);
968 update.section.?.sh_size = @as(Elf_OffSize, @intCast(payload.len));976 update.section.?.sh_size = @intCast(payload.len);
969 update.section.?.sh_flags |= elf.SHF_COMPRESSED;977 update.section.?.sh_flags |= elf.SHF_COMPRESSED;
970 }978 }
971 }979 }
...@@ -1032,7 +1040,7 @@ fn ElfFile(comptime is_64: bool) type {...@@ -1032,7 +1040,7 @@ fn ElfFile(comptime is_64: bool) type {
1032 dest.sh_info = sections_update[src.sh_info].remap_idx;1040 dest.sh_info = sections_update[src.sh_info].remap_idx;
10331041
1034 if (payload) |data|1042 if (payload) |data|
1035 dest.sh_size = @as(Elf_OffSize, @intCast(data.len));1043 dest.sh_size = @intCast(data.len);
10361044
1037 const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign;1045 const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign;
1038 dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign);1046 dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign);
...@@ -1110,7 +1118,7 @@ fn ElfFile(comptime is_64: bool) type {...@@ -1110,7 +1118,7 @@ fn ElfFile(comptime is_64: bool) type {
1110 .sh_flags = 0,1118 .sh_flags = 0,
1111 .sh_addr = 0,1119 .sh_addr = 0,
1112 .sh_offset = eof_offset,1120 .sh_offset = eof_offset,
1113 .sh_size = @as(Elf_OffSize, @intCast(payload.len)),1121 .sh_size = @intCast(payload.len),
1114 .sh_link = elf.SHN_UNDEF,1122 .sh_link = elf.SHN_UNDEF,
1115 .sh_info = elf.SHN_UNDEF,1123 .sh_info = elf.SHN_UNDEF,
1116 .sh_addralign = 4,1124 .sh_addralign = 4,
...@@ -1232,7 +1240,7 @@ const ElfFileHelper = struct {...@@ -1232,7 +1240,7 @@ const ElfFileHelper = struct {
1232 fused_cmd = null;1240 fused_cmd = null;
1233 }1241 }
1234 if (data.out_offset > offset) {1242 if (data.out_offset > offset) {
1235 consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@as(usize, @intCast(data.out_offset - offset))], .out_offset = offset } });1243 consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(data.out_offset - offset)], .out_offset = offset } });
1236 }1244 }
1237 consolidated.appendAssumeCapacity(cmd);1245 consolidated.appendAssumeCapacity(cmd);
1238 offset = data.out_offset + data.data.len;1246 offset = data.out_offset + data.data.len;
...@@ -1249,7 +1257,7 @@ const ElfFileHelper = struct {...@@ -1249,7 +1257,7 @@ const ElfFileHelper = struct {
1249 } else {1257 } else {
1250 consolidated.appendAssumeCapacity(prev);1258 consolidated.appendAssumeCapacity(prev);
1251 if (range.out_offset > offset) {1259 if (range.out_offset > offset) {
1252 consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@as(usize, @intCast(range.out_offset - offset))], .out_offset = offset } });1260 consolidated.appendAssumeCapacity(.{ .write_data = .{ .data = zeroes[0..@intCast(range.out_offset - offset)], .out_offset = offset } });
1253 }1261 }
1254 fused_cmd = cmd;1262 fused_cmd = cmd;
1255 }1263 }
...@@ -1286,7 +1294,7 @@ const ElfFileHelper = struct {...@@ -1286,7 +1294,7 @@ const ElfFileHelper = struct {
1286 var section_reader = std.io.limitedReader(in_file.reader(), size);1294 var section_reader = std.io.limitedReader(in_file.reader(), size);
12871295
1288 // allocate as large as decompressed data. if the compression doesn't fit, keep the data uncompressed.1296 // allocate as large as decompressed data. if the compression doesn't fit, keep the data uncompressed.
1289 const compressed_data = try allocator.alignedAlloc(u8, 8, @as(usize, @intCast(size)));1297 const compressed_data = try allocator.alignedAlloc(u8, 8, @intCast(size));
1290 var compressed_stream = std.io.fixedBufferStream(compressed_data);1298 var compressed_stream = std.io.fixedBufferStream(compressed_data);
12911299
1292 try compressed_stream.writer().writeAll(prefix);1300 try compressed_stream.writer().writeAll(prefix);
...@@ -1317,7 +1325,7 @@ const ElfFileHelper = struct {...@@ -1317,7 +1325,7 @@ const ElfFileHelper = struct {
1317 };1325 };
1318 }1326 }
13191327
1320 const compressed_len = @as(usize, @intCast(compressed_stream.getPos() catch unreachable));1328 const compressed_len: usize = @intCast(compressed_stream.getPos() catch unreachable);
1321 const data = allocator.realloc(compressed_data, compressed_len) catch compressed_data;1329 const data = allocator.realloc(compressed_data, compressed_len) catch compressed_data;
1322 return data[0..compressed_len];1330 return data[0..compressed_len];
1323 }1331 }