diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 18a69c0ad20e4d75b136f89580dfed26ddc89343..58cf6f11947702e85c5d31db6fa79c5e61d865c2 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -3730,33 +3730,37 @@ fn addRelocAssumeCapacity( break :sti .none; } else .none; - const section = loc_sn.section(coff); - const header = loc_sn.header(coff); - const old_num_relocations = coff.targetLoad(&header.number_of_relocations); - const new_num_relocations = old_num_relocations + 1; - const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); - if (section.relocation_table_ni == .none) { - section.relocation_table_ni = try coff.mf.addLastChildNode( - gpa, - coff.sectionParent(), - .{ - .size = new_size, - .alignment = .@"2", - .moved = true, - .resized = true, - }, - ); - coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); - } else { - try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); - } + const sri: Section.RelocationIndex = blk: { + const section = loc_sn.section(coff); + const header = loc_sn.header(coff); + const old_num_relocations = coff.targetLoad(&header.number_of_relocations); + const new_num_relocations = old_num_relocations + 1; + const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); - coff.targetStore(&header.number_of_relocations, new_num_relocations); - if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| - coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); + coff.targetStore(&header.number_of_relocations, new_num_relocations); + if (coff.symbolTableSectionAuxEntryPtr(loc_sn.symbol(coff).sti(coff))) |aux_ptr| + coff.targetStore(&aux_ptr.number_of_relocations, new_num_relocations); + + if (section.relocation_table_ni == .none) { + section.relocation_table_ni = try coff.mf.addLastChildNode( + gpa, + coff.sectionParent(), + .{ + .size = new_size, + .alignment = .@"2", + .moved = true, + .resized = true, + }, + ); + coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); + } else { + try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); + } + + // TODO: These need to allocate from a free list, once deleting relocs from the table is supported + break :blk .wrap(old_num_relocations); + }; - // TODO: These need to allocate from a free list, once deleting relocs is supported - const sri: Section.RelocationIndex = .wrap(old_num_relocations); const entry = sri.entry(coff, loc_sn).?; if (sti.unwrap()) |index| coff.targetStore(&entry.symbol_table_index, index); diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 63a4fc78b335b8ee9f01dadd3dc2ae6e48d8ff2e..669274d055e2fd019722a0ff1ea075490a8033df 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -799,19 +799,26 @@ fn resizeNode( if (is_linux and !mf.flags.fallocate_insert_range_unsupported and node.flags.alignment.order(mf.flags.block_size).compare(.gte)) insert_range: { - mf.memory_map.write(io) catch |err| switch (err) { - error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking - error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing - else => |e| return e, - }; - // Ask the filesystem driver to insert extents into the file without copying any data - const last_offset, const last_size = parent.last.location(mf).resolve(mf); - const last_end = last_offset + last_size; - assert(last_end <= old_parent_size); const range_file_offset = ni.fileLocation(mf, false).offset + old_size; const range_size = node.flags.alignment.forward( @intCast(requested_size +| requested_size / growth_factor), ) - old_size; + + // If this node is being realigned, its current state might not + // meet the requirements for fallocate + if (!mf.flags.block_size.check(@intCast(range_file_offset)) or + !mf.flags.block_size.check(@intCast(range_size))) + break :insert_range; + + mf.memory_map.write(io) catch |err| switch (err) { + error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking + error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing + else => |e| return e, + }; + // Ask the filesystem driver to insert extents into the file without copying any data + const last_offset, const last_size = parent.last.location(mf).resolve(mf); + const last_end = last_offset + last_size; + assert(last_end <= old_parent_size); _, const file_size = Node.Index.root.location(mf).resolve(mf); while (true) switch (linux.errno(switch (std.math.order(range_file_offset, file_size)) { .lt => linux.fallocate(