aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-11-03 10:03:03 +0100
committerJakub Konka <kubkon@jakubkonka.com>2023-11-04 09:12:26 +0100
commit33a0a72e87bd01ce6dbd10fa327c74168a0166db (patch)
treeef016abc30e70792ab37cb872e2bf4d1dba79a9a /src
parent875beb25b5493ee3b0aedd730f831e4ea5d124cc (diff)
downloadzig-33a0a72e87bd01ce6dbd10fa327c74168a0166db.tar.gz
zig-33a0a72e87bd01ce6dbd10fa327c74168a0166db.zip
elf: align ar_hdr to at least 2 bytes
Diffstat (limited to 'src')
-rw-r--r--src/link/Elf.zig21
-rw-r--r--src/link/Elf/Archive.zig2
2 files changed, 18 insertions, 5 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 85274d37d3..d938355da5 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1580,6 +1580,13 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
files.putAssumeCapacityNoClobber(zig_object.index, .{ off, 0, 0 });
}
+ // Align to even byte boundary
+ {
+ const end = ar_strtab.items.len;
+ const aligned = mem.alignForward(usize, end, 2);
+ try ar_strtab.writer().writeByteNTimes(0, aligned - end);
+ }
+
// Encode ar symtab in 64bit format.
var ar_symtab = std.ArrayList(u8).init(gpa);
defer ar_symtab.deinit();
@@ -1599,7 +1606,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
try ar_symtab.writer().print("{s}\x00", .{name});
}
- // Align to 8bytes if required
+ // Align to 8 bytes if required
{
const end = ar_symtab.items.len;
const aligned = mem.alignForward(usize, end, 8);
@@ -1617,8 +1624,6 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(ar_symtab.items.len));
// Strtab
file_off += @sizeOf(Archive.ar_hdr) + @as(u64, @intCast(ar_strtab.items.len));
- // And because we are nice, we will align to 8 bytes.
- file_off = mem.alignForward(u64, file_off, 8);
const files_ptr = files.getPtr(zig_object.index).?;
files_ptr[1] = file_off;
@@ -1661,7 +1666,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
const hdr = setArHdr(.{
.kind = .strtab,
.name_off = 0,
- .size = @intCast(mem.alignForward(usize, ar_strtab.items.len, 8)),
+ .size = @intCast(ar_strtab.items.len),
});
try self.base.file.?.pwriteAll(mem.asBytes(&hdr), pos);
pos += @sizeOf(Archive.ar_hdr);
@@ -1674,8 +1679,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation) link.File.FlushError!void
const entry = files.get(zig_object.index).?;
const hdr = setArHdr(.{ .kind = .object, .name_off = entry[0], .size = @intCast(entry[2]) });
try self.base.file.?.pwriteAll(mem.asBytes(&hdr), entry[1]);
+ pos += @sizeOf(Archive.ar_hdr) + entry[2];
}
+ if (pos % 2 != 0) {
+ pos += 1;
+ try self.base.file.?.pwriteAll(&[1]u8{0}, pos);
+ }
+
+ assert(mem.isAligned(pos, 2));
+
// TODO parsed positionals
// Magic bytes.
diff --git a/src/link/Elf/Archive.zig b/src/link/Elf/Archive.zig
index 49496ec7b5..bdefbfad04 100644
--- a/src/link/Elf/Archive.zig
+++ b/src/link/Elf/Archive.zig
@@ -88,7 +88,7 @@ pub fn parse(self: *Archive, elf_file: *Elf) !void {
if (stream.pos % 2 != 0) {
stream.pos += 1;
}
-
+ // TODO flag an error if stream.pos > self.data.len after alignment
const hdr = reader.readStruct(ar_hdr) catch break;
if (!mem.eql(u8, &hdr.ar_fmag, ARFMAG)) {