| 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 | 1572 | const total_size: u64 = blk: { |
| 1573 | 1573 | var pos: u64 = Archive.SARMAG; |
| 1574 | 1574 | pos += @sizeOf(Archive.ar_hdr) + ar_symtab.size(.p64); |
| 1575 | pos = mem.alignForward(u64, pos, 2); | |
| 1576 | pos += @sizeOf(Archive.ar_hdr) + ar_strtab.size(); | |
| 1575 | ||
| 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 | 1581 | if (self.zigObjectPtr()) |zig_object| { |
| 1579 | 1582 | pos = mem.alignForward(u64, pos, 2); |
| ... | ... | @@ -1598,19 +1601,22 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void |
| 1598 | 1601 | |
| 1599 | 1602 | // Write symtab |
| 1600 | 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 | 1605 | // Write strtab |
| 1604 | try ar_strtab.write(buffer.writer()); | |
| 1605 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); | |
| 1606 | if (ar_strtab.size() > 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 | 1611 | // Write object files |
| 1608 | 1612 | if (self.zigObjectPtr()) |zig_object| { |
| 1613 | if (!mem.isAligned(buffer.items.len, 2)) try buffer.writer().writeByte(0); | |
| 1609 | 1614 | try zig_object.writeAr(self, buffer.writer()); |
| 1610 | 1615 | } |
| 1611 | 1616 | |
| 1612 | 1617 | assert(buffer.items.len == total_size); |
| 1613 | 1618 | |
| 1619 | try self.base.file.?.setEndPos(total_size); | |
| 1614 | 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 | 61 | const object_name = blk: { |
| 62 | 62 | if (name[0] == '/') { |
| 63 | 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 | 70 | const object = Object{ |
| 70 | 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 | 73 | .data = try gpa.dupe(u8, self.data[stream.pos..][0..size]), |
| 73 | 74 | .index = undefined, |
| 74 | 75 | .alive = false, |
| ... | ... | @@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 { |
| 86 | 87 | } |
| 87 | 88 | |
| 88 | 89 | pub fn setArHdr(opts: struct { |
| 89 | kind: enum { symtab, strtab, object }, | |
| 90 | name_off: u32, | |
| 90 | name: union(enum) { | |
| 91 | symtab: void, | |
| 92 | strtab: void, | |
| 93 | name: []const u8, | |
| 94 | name_off: u32, | |
| 95 | }, | |
| 91 | 96 | size: u32, |
| 92 | 97 | }) ar_hdr { |
| 93 | 98 | var hdr: ar_hdr = .{ |
| ... | ... | @@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct { |
| 105 | 110 | { |
| 106 | 111 | var stream = std.io.fixedBufferStream(&hdr.ar_name); |
| 107 | 112 | const writer = stream.writer(); |
| 108 | switch (opts.kind) { | |
| 113 | switch (opts.name) { | |
| 109 | 114 | .symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable, |
| 110 | 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 | 219 | |
| 214 | 220 | pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void { |
| 215 | 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 | 223 | try writer.writeAll(mem.asBytes(&hdr)); |
| 218 | 224 | |
| 219 | 225 | const gpa = elf_file.base.allocator; |
| ... | ... | @@ -314,7 +320,7 @@ pub const ArStrtab = struct { |
| 314 | 320 | } |
| 315 | 321 | |
| 316 | 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 | 324 | try writer.writeAll(mem.asBytes(&hdr)); |
| 319 | 325 | try writer.writeAll(ar.buffer.items); |
| 320 | 326 | } |
src/link/Elf/ZigObject.zig+8-2| ... | ... | @@ -526,6 +526,7 @@ pub fn updateArStrtab( |
| 526 | 526 | ) error{OutOfMemory}!void { |
| 527 | 527 | const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)}); |
| 528 | 528 | defer allocator.free(name); |
| 529 | if (name.len <= 15) return; | |
| 529 | 530 | const name_off = try ar_strtab.insert(allocator, name); |
| 530 | 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 | 541 | |
| 541 | 542 | pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void { |
| 542 | 543 | const gpa = elf_file.base.allocator; |
| 544 | ||
| 543 | 545 | const contents = try gpa.alloc(u8, self.output_ar_state.size); |
| 544 | 546 | defer gpa.free(contents); |
| 547 | ||
| 545 | 548 | const amt = try elf_file.base.file.?.preadAll(contents, 0); |
| 546 | 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 | 554 | const hdr = Archive.setArHdr(.{ |
| 548 | .kind = .object, | |
| 549 | .name_off = self.output_ar_state.name_off, | |
| 555 | .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off }, | |
| 550 | 556 | .size = @intCast(self.output_ar_state.size), |
| 551 | 557 | }); |
| 552 | 558 | try writer.writeAll(mem.asBytes(&hdr)); |