aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf/Archive.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-11-04 00:08:55 +0100
committerJakub Konka <kubkon@jakubkonka.com>2023-11-04 09:13:26 +0100
commite3b82eaa661bc964f62a9481ac9ebfe35cf3bb87 (patch)
tree615947d93e00e1a4a8dedd50344908938d5d0524 /src/link/Elf/Archive.zig
parentacd700ac6b4ec03412e2bac6aaf168f80f83f521 (diff)
downloadzig-e3b82eaa661bc964f62a9481ac9ebfe35cf3bb87.tar.gz
zig-e3b82eaa661bc964f62a9481ac9ebfe35cf3bb87.zip
elf: do not store filename in strtab unless longer than 15 chars
Diffstat (limited to 'src/link/Elf/Archive.zig')
-rw-r--r--src/link/Elf/Archive.zig24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/link/Elf/Archive.zig b/src/link/Elf/Archive.zig
index 59576312e8..58a9e541a7 100644
--- a/src/link/Elf/Archive.zig
+++ b/src/link/Elf/Archive.zig
@@ -61,14 +61,15 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {
const object_name = blk: {
if (name[0] == '/') {
const off = try std.fmt.parseInt(u32, name[1..], 10);
- break :blk self.getString(off);
+ const object_name = self.getString(off);
+ break :blk try gpa.dupe(u8, object_name[0 .. object_name.len - 1]); // To account for trailing '/'
}
- break :blk name;
+ break :blk try gpa.dupe(u8, name);
};
const object = Object{
.archive = try gpa.dupe(u8, self.path),
- .path = try gpa.dupe(u8, object_name[0 .. object_name.len - 1]), // To account for trailing '/'
+ .path = object_name,
.data = try gpa.dupe(u8, self.data[stream.pos..][0..size]),
.index = undefined,
.alive = false,
@@ -86,8 +87,12 @@ fn getString(self: Archive, off: u32) []const u8 {
}
pub fn setArHdr(opts: struct {
- kind: enum { symtab, strtab, object },
- name_off: u32,
+ name: union(enum) {
+ symtab: void,
+ strtab: void,
+ name: []const u8,
+ name_off: u32,
+ },
size: u32,
}) ar_hdr {
var hdr: ar_hdr = .{
@@ -105,10 +110,11 @@ pub fn setArHdr(opts: struct {
{
var stream = std.io.fixedBufferStream(&hdr.ar_name);
const writer = stream.writer();
- switch (opts.kind) {
+ switch (opts.name) {
.symtab => writer.print("{s}", .{Archive.SYM64NAME}) catch unreachable,
.strtab => writer.print("//", .{}) catch unreachable,
- .object => writer.print("/{d}", .{opts.name_off}) catch unreachable,
+ .name => |x| writer.print("{s}", .{x}) catch unreachable,
+ .name_off => |x| writer.print("/{d}", .{x}) catch unreachable,
}
}
{
@@ -213,7 +219,7 @@ pub const ArSymtab = struct {
pub fn write(ar: ArSymtab, kind: enum { p32, p64 }, elf_file: *Elf, writer: anytype) !void {
assert(kind == .p64); // TODO p32
- const hdr = setArHdr(.{ .kind = .symtab, .name_off = 0, .size = @intCast(ar.size(.p64)) });
+ const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) });
try writer.writeAll(mem.asBytes(&hdr));
const gpa = elf_file.base.allocator;
@@ -314,7 +320,7 @@ pub const ArStrtab = struct {
}
pub fn write(ar: ArStrtab, writer: anytype) !void {
- const hdr = setArHdr(.{ .kind = .strtab, .name_off = 0, .size = @intCast(ar.size()) });
+ const hdr = setArHdr(.{ .name = .strtab, .size = @intCast(ar.size()) });
try writer.writeAll(mem.asBytes(&hdr));
try writer.writeAll(ar.buffer.items);
}