Skip to content

Commit a4f1daa

Browse files
committed
align end of elf archives
The end of the archive needs to also be aligned to a two-byte boundary, not just the start of records. This was causing lld to reject archives. Notably, this was happening with compiler_rt when rebuilding in fuzz mode, which is why this commit is included in this patchset.
1 parent c60919b commit a4f1daa

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

lib/std/Build/Step/CheckObject.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,10 @@ const ElfDumper = struct {
17011701
return error.InvalidArchiveMagicNumber;
17021702
}
17031703

1704+
if (!mem.isAligned(bytes.len, 2)) {
1705+
return error.InvalidArchivePadding;
1706+
}
1707+
17041708
var ctx = ArchiveContext{
17051709
.gpa = gpa,
17061710
.data = bytes,
@@ -1714,8 +1718,8 @@ const ElfDumper = struct {
17141718
}
17151719

17161720
while (true) {
1717-
if (reader.seek >= ctx.data.len) break;
17181721
if (!mem.isAligned(reader.seek, 2)) reader.seek += 1;
1722+
if (reader.seek >= ctx.data.len) break;
17191723

17201724
const hdr = try reader.takeStruct(elf.ar_hdr, .little);
17211725

src/link/Elf/relocatable.zig

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
7474
const total_size: usize = blk: {
7575
var pos: usize = elf.ARMAG.len;
7676
pos += @sizeOf(elf.ar_hdr) + ar_symtab.size(.p64);
77+
pos = mem.alignForward(usize, pos, 2);
7778

7879
if (ar_strtab.size() > 0) {
79-
pos = mem.alignForward(usize, pos, 2);
8080
pos += @sizeOf(elf.ar_hdr) + ar_strtab.size();
81+
pos = mem.alignForward(usize, pos, 2);
8182
}
8283

8384
for (files.items) |index| {
@@ -87,9 +88,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
8788
.object => |x| &x.output_ar_state,
8889
else => unreachable,
8990
};
90-
pos = mem.alignForward(usize, pos, 2);
9191
state.file_off = pos;
9292
pos += @sizeOf(elf.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);
93+
pos = mem.alignForward(usize, pos, 2);
9394
}
9495

9596
break :blk pos;
@@ -110,17 +111,18 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
110111

111112
// Write symtab
112113
try ar_symtab.write(.p64, elf_file, &writer);
114+
if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
113115

114116
// Write strtab
115117
if (ar_strtab.size() > 0) {
116-
if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
117118
try ar_strtab.write(&writer);
119+
if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
118120
}
119121

120122
// Write object files
121123
for (files.items) |index| {
122-
if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
123124
try elf_file.file(index).?.writeAr(elf_file, &writer);
125+
if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
124126
}
125127

126128
assert(writer.buffered().len == total_size);

0 commit comments

Comments
 (0)