| author | |
| committer | |
| log | c9601664c6914a8bdbf778f494a0a4fe6d84fa53 |
| tree | 5fdb2bf3bad6e0492fc310f63200dc26e6c7208a |
| parent | e2c587ae54cba1d2b13b5cbef8530e13fab04c7f |
MappedFile: add check to prevent INVAL from fallocate() when realigning nodes that are not aligned to the block size2 files changed, 40 insertions(+), 29 deletions(-)
src/link/Coff.zig+29-25| ... | @@ -3730,33 +3730,37 @@ fn addRelocAssumeCapacity( | ... | @@ -3730,33 +3730,37 @@ fn addRelocAssumeCapacity( |
| 3730 | break :sti .none; | 3730 | break :sti .none; |
| 3731 | } else .none; | 3731 | } else .none; |
| 3732 | 3732 | ||
| 3733 | const section = loc_sn.section(coff); | 3733 | const sri: Section.RelocationIndex = blk: { |
| 3734 | const header = loc_sn.header(coff); | 3734 | const section = loc_sn.section(coff); |
| 3735 | const old_num_relocations = coff.targetLoad(&header.number_of_relocations); | 3735 | const header = loc_sn.header(coff); |
| 3736 | const new_num_relocations = old_num_relocations + 1; | 3736 | const old_num_relocations = coff.targetLoad(&header.number_of_relocations); |
| 3737 | const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); | 3737 | const new_num_relocations = old_num_relocations + 1; |
| 3738 | if (section.relocation_table_ni == .none) { | 3738 | const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); |
| 3739 | section.relocation_table_ni = try coff.mf.addLastChildNode( | 3739 | |
| 3740 | gpa, | 3740 | coff.targetStore(&header.number_of_relocations, new_num_relocations); |
| 3741 | coff.sectionParent(), | 3741 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| |
| 3742 | .{ | 3742 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); |
| 3743 | .size = new_size, | 3743 | |
| 3744 | .alignment = .@"2", | 3744 | if (section.relocation_table_ni == .none) { |
| 3745 | .moved = true, | 3745 | section.relocation_table_ni = try coff.mf.addLastChildNode( |
| 3746 | .resized = true, | 3746 | gpa, |
| 3747 | }, | 3747 | coff.sectionParent(), |
| 3748 | ); | 3748 | .{ |
| 3749 | coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); | 3749 | .size = new_size, |
| 3750 | } else { | 3750 | .alignment = .@"2", |
| 3751 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); | 3751 | .moved = true, |
| 3752 | } | 3752 | .resized = true, |
| 3753 | }, | ||
| 3754 | ); | ||
| 3755 | coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); | ||
| 3756 | } else { | ||
| 3757 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); | ||
| 3758 | } | ||
| 3753 | 3759 | ||
| 3754 | coff.targetStore(&header.number_of_relocations, new_num_relocations); | 3760 | // TODO: These need to allocate from a free list, once deleting relocs from the table is supported |
| 3755 | if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| | 3761 | break :blk .wrap(old_num_relocations); |
| 3756 | coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); | 3762 | }; |
| 3757 | 3763 | ||
| 3758 | // TODO: These need to allocate from a free list, once deleting relocs is supported | ||
| 3759 | const sri: Section.RelocationIndex = .wrap(old_num_relocations); | ||
| 3760 | const entry = sri.entry(coff, loc_sn).?; | 3764 | const entry = sri.entry(coff, loc_sn).?; |
| 3761 | if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index); | 3765 | if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index); |
| 3762 | 3766 |
src/link/MappedFile.zig+11-4| ... | @@ -799,6 +799,17 @@ fn resizeNode( | ... | @@ -799,6 +799,17 @@ fn resizeNode( |
| 799 | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and | 799 | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and |
| 800 | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) | 800 | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) |
| 801 | insert_range: { | 801 | insert_range: { |
| 802 | const range_file_offset = ni.fileLocation(mf, false).offset + old_size; | ||
| 803 | const range_size = node.flags.alignment.forward( | ||
| 804 | @intCast(requested_size +| requested_size / growth_factor), | ||
| 805 | ) - old_size; | ||
| 806 | |||
| 807 | // If this node is being realigned, its current state might not | ||
| 808 | // meet the requirements for fallocate | ||
| 809 | if (!mf.flags.block_size.check(@intCast(range_file_offset)) or | ||
| 810 | !mf.flags.block_size.check(@intCast(range_size))) | ||
| 811 | break :insert_range; | ||
| 812 | |||
| 802 | mf.memory_map.write(io) catch |err| switch (err) { | 813 | mf.memory_map.write(io) catch |err| switch (err) { |
| 803 | error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking | 814 | error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking |
| 804 | error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing | 815 | error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing |
| ... | @@ -808,10 +819,6 @@ fn resizeNode( | ... | @@ -808,10 +819,6 @@ fn resizeNode( |
| 808 | const last_offset, const last_size = parent.last.location(mf).resolve(mf); | 819 | const last_offset, const last_size = parent.last.location(mf).resolve(mf); |
| 809 | const last_end = last_offset + last_size; | 820 | const last_end = last_offset + last_size; |
| 810 | assert(last_end <= old_parent_size); | 821 | assert(last_end <= old_parent_size); |
| 811 | const range_file_offset = ni.fileLocation(mf, false).offset + old_size; | ||
| 812 | const range_size = node.flags.alignment.forward( | ||
| 813 | @intCast(requested_size +| requested_size / growth_factor), | ||
| 814 | ) - old_size; | ||
| 815 | _, const file_size = Node.Index.root.location(mf).resolve(mf); | 822 | _, const file_size = Node.Index.root.location(mf).resolve(mf); |
| 816 | while (true) switch (linux.errno(switch (std.math.order(range_file_offset, file_size)) { | 823 | while (true) switch (linux.errno(switch (std.math.order(range_file_offset, file_size)) { |
| 817 | .lt => linux.fallocate( | 824 | .lt => linux.fallocate( |