authorgravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2025-11-02 09:57:15-05:00
committergravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2026-02-13 17:58:09-05:00
logaf1e196db3bca66c29979c685b1c9c896c275211
tree03ab8aa21c4fd56ad91561f8efc48ef6b9a88946
parent3c9024be08f34d2bb38693df38e5b4b334c74f90

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.

2 files changed, 11 insertions(+), 5 deletions(-)

lib/std/Build/Step/CheckObject.zig+5-1
...@@ -1702,6 +1702,10 @@ const ElfDumper = struct {...@@ -1702,6 +1702,10 @@ const ElfDumper = struct {
1702 return error.InvalidArchiveMagicNumber;1702 return error.InvalidArchiveMagicNumber;
1703 }1703 }
17041704
1705 if (!mem.isAligned(bytes.len, 2)) {
1706 return error.InvalidArchivePadding;
1707 }
1708
1705 var ctx = ArchiveContext{1709 var ctx = ArchiveContext{
1706 .gpa = gpa,1710 .gpa = gpa,
1707 .data = bytes,1711 .data = bytes,
...@@ -1715,8 +1719,8 @@ const ElfDumper = struct {...@@ -1715,8 +1719,8 @@ const ElfDumper = struct {
1715 }1719 }
17161720
1717 while (true) {1721 while (true) {
1718 if (reader.seek >= ctx.data.len) break;
1719 if (!mem.isAligned(reader.seek, 2)) reader.seek += 1;1722 if (!mem.isAligned(reader.seek, 2)) reader.seek += 1;
1723 if (reader.seek >= ctx.data.len) break;
17201724
1721 const hdr = try reader.takeStruct(elf.ar_hdr, .little);1725 const hdr = try reader.takeStruct(elf.ar_hdr, .little);
17221726
src/link/Elf/relocatable.zig+6-4
...@@ -95,10 +95,11 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {...@@ -95,10 +95,11 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
95 const total_size: usize = blk: {95 const total_size: usize = blk: {
96 var pos: usize = elf.ARMAG.len;96 var pos: usize = elf.ARMAG.len;
97 pos += @sizeOf(elf.ar_hdr) + ar_symtab.size(.p64);97 pos += @sizeOf(elf.ar_hdr) + ar_symtab.size(.p64);
98 pos = mem.alignForward(usize, pos, 2);
9899
99 if (ar_strtab.size() > 0) {100 if (ar_strtab.size() > 0) {
100 pos = mem.alignForward(usize, pos, 2);
101 pos += @sizeOf(elf.ar_hdr) + ar_strtab.size();101 pos += @sizeOf(elf.ar_hdr) + ar_strtab.size();
102 pos = mem.alignForward(usize, pos, 2);
102 }103 }
103104
104 for (files.items) |index| {105 for (files.items) |index| {
...@@ -108,9 +109,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {...@@ -108,9 +109,9 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
108 .object => |x| &x.output_ar_state,109 .object => |x| &x.output_ar_state,
109 else => unreachable,110 else => unreachable,
110 };111 };
111 pos = mem.alignForward(usize, pos, 2);
112 state.file_off = pos;112 state.file_off = pos;
113 pos += @sizeOf(elf.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);113 pos += @sizeOf(elf.ar_hdr) + (math.cast(usize, state.size) orelse return error.Overflow);
114 pos = mem.alignForward(usize, pos, 2);
114 }115 }
115116
116 break :blk pos;117 break :blk pos;
...@@ -131,17 +132,18 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {...@@ -131,17 +132,18 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
131132
132 // Write symtab133 // Write symtab
133 try ar_symtab.write(.p64, elf_file, &writer);134 try ar_symtab.write(.p64, elf_file, &writer);
135 if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
134136
135 // Write strtab137 // Write strtab
136 if (ar_strtab.size() > 0) {138 if (ar_strtab.size() > 0) {
137 if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
138 try ar_strtab.write(&writer);139 try ar_strtab.write(&writer);
140 if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
139 }141 }
140142
141 // Write object files143 // Write object files
142 for (files.items) |index| {144 for (files.items) |index| {
143 if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
144 try elf_file.file(index).?.writeAr(elf_file, &writer);145 try elf_file.file(index).?.writeAr(elf_file, &writer);
146 if (!mem.isAligned(writer.end, 2)) try writer.writeByte(0);
145 }147 }
146148
147 assert(writer.buffered().len == total_size);149 assert(writer.buffered().len == total_size);