authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-04-13 22:14:48+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-04-14 22:53:13+02:00
logd66c61a2cf69665223815a1a12a1f93b30b99571
tree2f969fb2733eadc8ae16088ce98b0b19a5841ce8
parentcf37101108e56412e958a8b597bae84649893b6f

wasm-linker: Prevent overalignment for segments

Previously, the data segments were being aligned twice. This caused us to overalign the segment and therefore allocate a much larger size for each segment than was required. This fix ensures we align and set the size just once, ensuring semantically correct binaries as well as smaller binaries.

2 files changed, 7 insertions(+), 15 deletions(-)

src/link/Wasm.zig+7-10
...@@ -962,11 +962,6 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void {...@@ -962,11 +962,6 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void {
962962
963 const segment: *Segment = &self.segments.items[final_index];963 const segment: *Segment = &self.segments.items[final_index];
964 segment.alignment = std.math.max(segment.alignment, atom.alignment);964 segment.alignment = std.math.max(segment.alignment, atom.alignment);
965 segment.size = std.mem.alignForwardGeneric(
966 u32,
967 std.mem.alignForwardGeneric(u32, segment.size, atom.alignment) + atom.size,
968 segment.alignment,
969 );
970965
971 if (self.atoms.getPtr(final_index)) |last| {966 if (self.atoms.getPtr(final_index)) |last| {
972 last.*.next = atom;967 last.*.next = atom;
...@@ -978,9 +973,10 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void {...@@ -978,9 +973,10 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void {
978}973}
979974
980fn allocateAtoms(self: *Wasm) !void {975fn allocateAtoms(self: *Wasm) !void {
981 var it = self.atoms.valueIterator();976 var it = self.atoms.iterator();
982 while (it.next()) |current_atom| {977 while (it.next()) |entry| {
983 var atom: *Atom = current_atom.*.getFirst();978 const segment = &self.segments.items[entry.key_ptr.*];
979 var atom: *Atom = entry.value_ptr.*.getFirst();
984 var offset: u32 = 0;980 var offset: u32 = 0;
985 while (true) {981 while (true) {
986 offset = std.mem.alignForwardGeneric(u32, offset, atom.alignment);982 offset = std.mem.alignForwardGeneric(u32, offset, atom.alignment);
...@@ -996,6 +992,7 @@ fn allocateAtoms(self: *Wasm) !void {...@@ -996,6 +992,7 @@ fn allocateAtoms(self: *Wasm) !void {
996 self.symbol_atom.putAssumeCapacity(atom.symbolLoc(), atom); // Update atom pointers992 self.symbol_atom.putAssumeCapacity(atom.symbolLoc(), atom); // Update atom pointers
997 atom = atom.next orelse break;993 atom = atom.next orelse break;
998 }994 }
995 segment.size = std.mem.alignForwardGeneric(u32, offset, segment.alignment);
999 }996 }
1000}997}
1001998
...@@ -1566,8 +1563,8 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -1566,8 +1563,8 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
1566 try self.objects.items[object_index].parseIntoAtoms(self.base.allocator, object_index, self);1563 try self.objects.items[object_index].parseIntoAtoms(self.base.allocator, object_index, self);
1567 }1564 }
15681565
1569 try self.setupMemory();
1570 try self.allocateAtoms();1566 try self.allocateAtoms();
1567 try self.setupMemory();
1571 self.mapFunctionTable();1568 self.mapFunctionTable();
1572 try self.mergeSections();1569 try self.mergeSections();
1573 try self.mergeTypes();1570 try self.mergeTypes();
...@@ -1832,7 +1829,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {...@@ -1832,7 +1829,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation) !void {
1832 segment_count += 1;1829 segment_count += 1;
1833 const atom_index = entry.value_ptr.*;1830 const atom_index = entry.value_ptr.*;
1834 var atom: *Atom = self.atoms.getPtr(atom_index).?.*.getFirst();1831 var atom: *Atom = self.atoms.getPtr(atom_index).?.*.getFirst();
1835 var segment = self.segments.items[atom_index];1832 const segment = self.segments.items[atom_index];
18361833
1837 // flag and index to memory section (currently, there can only be 1 memory section in wasm)1834 // flag and index to memory section (currently, there can only be 1 memory section in wasm)
1838 try leb.writeULEB128(writer, @as(u32, 0));1835 try leb.writeULEB128(writer, @as(u32, 0));
src/link/Wasm/Object.zig-5
...@@ -865,11 +865,6 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin...@@ -865,11 +865,6 @@ pub fn parseIntoAtoms(self: *Object, gpa: Allocator, object_index: u16, wasm_bin
865865
866 const segment: *Wasm.Segment = &wasm_bin.segments.items[final_index];866 const segment: *Wasm.Segment = &wasm_bin.segments.items[final_index];
867 segment.alignment = std.math.max(segment.alignment, atom.alignment);867 segment.alignment = std.math.max(segment.alignment, atom.alignment);
868 segment.size = std.mem.alignForwardGeneric(
869 u32,
870 std.mem.alignForwardGeneric(u32, segment.size, atom.alignment) + atom.size,
871 segment.alignment,
872 );
873868
874 if (wasm_bin.atoms.getPtr(final_index)) |last| {869 if (wasm_bin.atoms.getPtr(final_index)) |last| {
875 last.*.next = atom;870 last.*.next = atom;