aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf
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
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')
-rw-r--r--src/link/Elf/Archive.zig24
-rw-r--r--src/link/Elf/ZigObject.zig10
2 files changed, 23 insertions, 11 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);
}
diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig
index bd5ba04834..5442d9a4bb 100644
--- a/src/link/Elf/ZigObject.zig
+++ b/src/link/Elf/ZigObject.zig
@@ -526,6 +526,7 @@ pub fn updateArStrtab(
) error{OutOfMemory}!void {
const name = try std.fmt.allocPrint(allocator, "{s}.o", .{std.fs.path.stem(self.path)});
defer allocator.free(name);
+ if (name.len <= 15) return;
const name_off = try ar_strtab.insert(allocator, name);
self.output_ar_state.name_off = name_off;
}
@@ -540,13 +541,18 @@ pub fn updateArSize(self: *ZigObject, elf_file: *Elf) void {
pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void {
const gpa = elf_file.base.allocator;
+
const contents = try gpa.alloc(u8, self.output_ar_state.size);
defer gpa.free(contents);
+
const amt = try elf_file.base.file.?.preadAll(contents, 0);
if (amt != self.output_ar_state.size) return error.InputOutput;
+
+ const name = try std.fmt.allocPrint(gpa, "{s}.o", .{std.fs.path.stem(self.path)});
+ defer gpa.free(name);
+
const hdr = Archive.setArHdr(.{
- .kind = .object,
- .name_off = self.output_ar_state.name_off,
+ .name = if (name.len <= 15) .{ .name = name } else .{ .name_off = self.output_ar_state.name_off },
.size = @intCast(self.output_ar_state.size),
});
try writer.writeAll(mem.asBytes(&hdr));