| author | |
| committer | |
| log | e3b82eaa661bc964f62a9481ac9ebfe35cf3bb87 |
| tree | 615947d93e00e1a4a8dedd50344908938d5d0524 |
| parent | acd700ac6b4ec03412e2bac6aaf168f80f83f521 |
3 files changed, 34 insertions(+), 16 deletions(-)
src/link/Elf.zig+11-5| ... | @@ -1572,8 +1572,11 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void | ... | @@ -1572,8 +1572,11 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void |
| 1572 | const total_size: u64 = blk: { | 1572 | const total_size: u64 = blk: { |
| 1573 | var pos: u64 = Archive.SARMAG; | 1573 | var pos: u64 = Archive.SARMAG; |
| 1574 | pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64); | 1574 | pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64); |
| 1575 | pos = mem.alignForward(u64, pos, 2); | 1575 | |
| 1576 | pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size(); | 1576 | if (ar_strtab.size() > 0) { |
| 1577 | pos = mem.alignForward(u64, pos, 2); | ||
| 1578 | pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size(); | ||
| 1579 | } | ||
| 1577 | 1580 | ||
| 1578 | if (self.zigObjectPtr()) |zig_object| { | 1581 | if (self.zigObjectPtr()) |zig_object| { |
| 1579 | pos = mem.alignForward(u64, pos, 2); | 1582 | pos = mem.alignForward(u64, pos, 2); |
| ... | @@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void | ... | @@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void |
| 1598 | 1601 | ||
| 1599 | // Write symtab | 1602 | // Write symtab |
| 1600 | try ar_symtab.write(.p64, self, buffer.writer()); | 1603 | try ar_symtab.write(.p64, self, buffer.writer()); |
| 1601 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); | ||
| 1602 | 1604 | ||
| 1603 | // Write strtab | 1605 | // Write strtab |
| 1604 | try ar_strtab.write(buffer.writer()); | 1606 | if (ar_strtab.size() > 0) { |
| 1605 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); | 1607 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); |
| 1608 | try ar_strtab.write(buffer.writer()); | ||
| 1609 | } | ||
| 1606 | 1610 | ||
| 1607 | // Write object files | 1611 | // Write object files |
| 1608 | if (self.zigObjectPtr()) |zig_object| { | 1612 | if (self.zigObjectPtr()) |zig_object| { |
| 1613 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); | ||
| 1609 | try zig_object.writeAr(self, buffer.writer()); | 1614 | try zig_object.writeAr(self, buffer.writer()); |
| 1610 | } | 1615 | } |
| 1611 | 1616 | ||
| 1612 | assert(buffer.items.len == total_size); | 1617 | assert(buffer.items.len == total_size); |
| 1613 | 1618 | ||
| 1619 | try self.base.file.?.setEndPos(total_size); | ||
| 1614 | try self.base.file.?.pwriteAll(buffer.items, 0); | 1620 | try self.base.file.?.pwriteAll(buffer.items, 0); |
| 1615 | } | 1621 | } |
| 1616 | 1622 |
src/link/Elf/Archive.zig+15-9| ... | @@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void { | ... | @@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void { |
| 61 | const object_name = blk: { | 61 | const object_name = blk: { |
| 62 | if (name[0] == '/') { | 62 | if (name[0] == '/') { |
| 63 | const off = try std.fmt.parseInt(u32, name[1..], 10); | 63 | const off = try std.fmt.parseInt(u32, name[1..], 10); |
| 64 | break :blk self.getString(off); | 64 | const object_name = self.getString(off); |
| 65 | break :blk try gpa.dupe(u8, object_name[0 .. object_name.len - 1]); // To account for trailing '/' | ||
| 65 | } | 66 | } |
| 66 | break :blk name; | 67 | break :blk try gpa.dupe(u8, name); |
| 67 | }; | 68 | }; |
| 68 | 69 | ||
| 69 | const object = Object{ | 70 | const object = Object{ |
| 70 | .archive = try gpa.dupe(u8, self.path), | 71 | .archive = try gpa.dupe(u8, self.path), |
| 71 | .path = try gpa.dupe(u8, object_name[0 .. object_name.len - 1]), // To account for trailing '/' | 72 | .path = object_name, |
| 72 | .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]), | 73 | .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]), |
| 73 | .index = undefined, | 74 | .index = undefined, |
| 74 | .alive = false, | 75 | .alive = false, |
| ... | @@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 { | ... | @@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 { |
| 86 | } | 87 | } |
| 87 | 88 | ||
| 88 | pub fn setArHdr(opts: struct { | 89 | pub fn setArHdr(opts: struct { |
| 89 | kind: enum { symtab, strtab, object }, | 90 | name: union(enum) { |
| 90 | name_off: u32, | 91 | symtab: void, |
| 92 | strtab: void, | ||
| 93 | name: []const u8, | ||
| 94 | name_off: u32, | ||
| 95 | }, | ||
| 91 | size: u32, | 96 | size: u32, |
| 92 | }) ar_hdr { | 97 | }) ar_hdr { |
| 93 | var hdr: ar_hdr = .{ | 98 | var hdr: ar_hdr = .{ |
| ... | @@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct { | ... | @@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct { |
| 105 | { | 110 | { |
| 106 | var stream = std.io.fixedBufferStream(&hdr.ar_name); | 111 | var stream = std.io.fixedBufferStream(&hdr.ar_name); |
| 107 | const writer = stream.writer(); | 112 | const writer = stream.writer(); |
| 108 | switch (opts.kind) { | 113 | switch (opts.name) { |
| 109 | .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable, | 114 | .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable, |
| 110 | .strtab => writer.print("//", .{}) catch unreachable, | 115 | .strtab => writer.print("//", .{}) catch unreachable, |
| 111 | .object => writer.print("/{d}", .{opts.name_off}) catch unreachable, | 116 | .name => |x| writer.print("{s}", .{x}) catch unreachable, |
| 117 | .name_off => |x| writer.print("/{d}", .{x}) catch unreachable, | ||
| 112 | } | 118 | } |
| 113 | } | 119 | } |
| 114 | { | 120 | { |
| ... | @@ -213,7 +219,7 @@ pub const ArSymtab = struct { | ... | @@ -213,7 +219,7 @@ pub const ArSymtab = struct { |
| 213 | 219 | ||
| 214 | pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void { | 220 | pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void { |
| 215 | assert(kind == .p64); // TODO p32 | 221 | assert(kind == .p64); // TODO p32 |
| 216 | const hdr = setArHdr(.{ .kind = .symtab, .name_off = 0, .size = @intCast(ar.size(.p64)) }); | 222 | const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) }); |
| 217 | try writer.writeAll(mem.asBytes(&hdr)); | 223 | try writer.writeAll(mem.asBytes(&hdr)); |
| 218 | 224 | ||
| 219 | const gpa = elf_file.base.allocator; | 225 | const gpa = elf_file.base.allocator; |
| ... | @@ -314,7 +320,7 @@ pub const ArStrtab = struct { | ... | @@ -314,7 +320,7 @@ pub const ArStrtab = struct { |
| 314 | } | 320 | } |
| 315 | 321 | ||
| 316 | pub fn write(ar: ArStrtab, writer: anytype) !void { | 322 | pub fn write(ar: ArStrtab, writer: anytype) !void { |
| 317 | const hdr = setArHdr(.{ .kind = .strtab, .name_off = 0, .size = @intCast(ar.size()) }); | 323 | const hdr = setArHdr(.{ .name = .strtab, .size = @intCast(ar.size()) }); |
| 318 | try writer.writeAll(mem.asBytes(&hdr)); | 324 | try writer.writeAll(mem.asBytes(&hdr)); |
| 319 | try writer.writeAll(ar.buffer.items); | 325 | try writer.writeAll(ar.buffer.items); |
| 320 | } | 326 | } |
src/link/Elf/ZigObject.zig+8-2| ... | @@ -526,6 +526,7 @@ pub fn updateArStrtab( | ... | @@ -526,6 +526,7 @@ pub fn updateArStrtab( |
| 526 | ) error{OutOfMemory}!void { | 526 | ) error{OutOfMemory}!void { |
| 527 | const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)}); | 527 | const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)}); |
| 528 | defer allocator.free(name); | 528 | defer allocator.free(name); |
| 529 | if (name.len <= 15) return; | ||
| 529 | const name_off = try ar_strtab.insert(allocator, name); | 530 | const name_off = try ar_strtab.insert(allocator, name); |
| 530 | self.output_ar_state.name_off = name_off; | 531 | self.output_ar_state.name_off = name_off; |
| 531 | } | 532 | } |
| ... | @@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void { | ... | @@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void { |
| 540 | 541 | ||
| 541 | pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void { | 542 | pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void { |
| 542 | const gpa = elf_file.base.allocator; | 543 | const gpa = elf_file.base.allocator; |
| 544 | |||
| 543 | const contents = try gpa.alloc(u8, self.output_ar_state.size); | 545 | const contents = try gpa.alloc(u8, self.output_ar_state.size); |
| 544 | defer gpa.free(contents); | 546 | defer gpa.free(contents); |
| 547 | |||
| 545 | const amt = try elf_file.base.file.?.preadAll(contents, 0); | 548 | const amt = try elf_file.base.file.?.preadAll(contents, 0); |
| 546 | if (amt != self.output_ar_state.size) return error.InputOutput; | 549 | if (amt != self.output_ar_state.size) return error.InputOutput; |
| 550 | |||
| 551 | const name = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(self.path)}); | ||
| 552 | defer gpa.free(name); | ||
| 553 | |||
| 547 | const hdr = Archive.setArHdr(.{ | 554 | const hdr = Archive.setArHdr(.{ |
| 548 | .kind = .object, | 555 | .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off }, |
| 549 | .name_off = self.output_ar_state.name_off, | ||
| 550 | .size = @intCast(self.output_ar_state.size), | 556 | .size = @intCast(self.output_ar_state.size), |
| 551 | }); | 557 | }); |
| 552 | try writer.writeAll(mem.asBytes(&hdr)); | 558 | try writer.writeAll(mem.asBytes(&hdr)); |