| author | |
| committer | |
| log | 22a22ceaeb3f693207fc4821b55959ba0732d7ed |
| tree | feb6df740e4d0a2fbe767b48d92518484bb57619 |
| parent | 2be291c98773e25d4a47e5c35744084627d11f15 |
- Add MappedFile.realign
- Fix the case of MappedFile.addNode adding a node in between nodes that have lower alignment than it (by realigning the following node)
- Fixup the capacity reservation in addNode to occur after the resize (which may have consumed that capacity)
- Remove incorrect path in `.load_host_libc` that was loading mingw libs, they were already being loaded via their build tasks
- Generate mingw implibs as a prelink task, so they can be supplied to the linker before prelink()
- Any other libraries discovered during Sema are have their implibs generated after, but the self-hosted linker is not passed these. Lld can still use this path.
- mingw implib generation now interacts with the progress system
- Supply `__ImageBase` for mingw6 files changed, 161 insertions(+), 61 deletions(-)
src/Compilation.zig+40-11| ... | ... | @@ -4475,18 +4475,10 @@ fn performAllTheWork( |
| 4475 | 4475 | |
| 4476 | 4476 | comp.link_queue.finishZcuQueue(comp); |
| 4477 | 4477 | |
| 4478 | // This has to happen after the main semantic analysis loop because it is possible for Sema to | |
| 4478 | // This has to happen again after the main semantic analysis loop because it is possible for Sema to | |
| 4479 | 4479 | // call `addLinkLib` and hence add more items to `comp.windows_libs`. |
| 4480 | for (comp.windows_libs.keys()[comp.windows_libs_num_done..]) |link_lib| { | |
| 4481 | mingw.buildImportLib(comp, link_lib) catch |err| { | |
| 4482 | // TODO Surface more error details. | |
| 4483 | comp.lockAndSetMiscFailure( | |
| 4484 | .windows_import_lib, | |
| 4485 | "unable to generate DLL import .lib file for {s}: {t}", | |
| 4486 | .{ link_lib, err }, | |
| 4487 | ); | |
| 4488 | }; | |
| 4489 | } | |
| 4480 | for (comp.windows_libs.keys()[comp.windows_libs_num_done..]) |lib_name| | |
| 4481 | comp.buildMingwImportLib(lib_name, false, main_progress_node); | |
| 4490 | 4482 | comp.windows_libs_num_done = @intCast(comp.windows_libs.count()); |
| 4491 | 4483 | |
| 4492 | 4484 | // Main thread work is all done, now just wait for all async work. |
| ... | ... | @@ -4692,6 +4684,15 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node |
| 4692 | 4684 | }); |
| 4693 | 4685 | } |
| 4694 | 4686 | |
| 4687 | while (comp.windows_libs_num_done < comp.windows_libs.count()) { | |
| 4688 | prelink_group.async( | |
| 4689 | io, | |
| 4690 | buildMingwImportLib, | |
| 4691 | .{ comp, comp.windows_libs.keys()[comp.windows_libs_num_done], true, main_progress_node }, | |
| 4692 | ); | |
| 4693 | comp.windows_libs_num_done += 1; | |
| 4694 | } | |
| 4695 | ||
| 4695 | 4696 | prelink_group.await(io) catch |err| switch (err) { |
| 4696 | 4697 | error.Canceled => unreachable, // see swapCancelProtection above |
| 4697 | 4698 | }; |
| ... | ... | @@ -5377,6 +5378,34 @@ fn buildMingwCrtFile(comp: *Compilation, crt_file: mingw.CrtFile, prog_node: std |
| 5377 | 5378 | } |
| 5378 | 5379 | } |
| 5379 | 5380 | |
| 5381 | fn buildMingwImportLib(comp: *Compilation, lib_name: []const u8, is_prelink: bool, prog_node: std.Progress.Node) void { | |
| 5382 | const crt_file_path = mingw.buildImportLib(comp, lib_name, prog_node) catch |err| switch (err) { | |
| 5383 | // TODO: This isn't actually true for self-hosted | |
| 5384 | // In the non-prelink case we will end up putting foo.lib onto the linker line and letting the linker | |
| 5385 | // use its library paths to look for libraries and report any problems. | |
| 5386 | error.DefNotFound => return if (is_prelink) { | |
| 5387 | comp.lockAndSetMiscFailure( | |
| 5388 | .windows_import_lib, | |
| 5389 | "definition not found for required mingw DLL import .lib {s}", | |
| 5390 | .{lib_name}, | |
| 5391 | ); | |
| 5392 | }, | |
| 5393 | // TODO Surface more error details. | |
| 5394 | else => |e| return comp.lockAndSetMiscFailure( | |
| 5395 | .windows_import_lib, | |
| 5396 | "unable to generate mingw DLL import .lib file for {s}: {t}", | |
| 5397 | .{ lib_name, e }, | |
| 5398 | ), | |
| 5399 | }; | |
| 5400 | ||
| 5401 | if (is_prelink) | |
| 5402 | comp.queuePrelinkTasks(&.{.{ .load_archive = crt_file_path }}) catch |err| comp.lockAndSetMiscFailure( | |
| 5403 | .windows_import_lib, | |
| 5404 | "unable to queue prelink task for mingw import lib {f}: {t}", | |
| 5405 | .{ crt_file_path, err }, | |
| 5406 | ); | |
| 5407 | } | |
| 5408 | ||
| 5380 | 5409 | fn buildWasiLibcCrtFile(comp: *Compilation, crt_file: wasi_libc.CrtFile, prog_node: std.Progress.Node) void { |
| 5381 | 5410 | if (wasi_libc.buildCrtFile(comp, crt_file, prog_node)) |_| { |
| 5382 | 5411 | comp.queued_jobs.wasi_libc_crt_file[@intFromEnum(crt_file)] = false; |
src/libs/mingw.zig+21-16| ... | ... | @@ -207,9 +207,12 @@ fn addCrtCcArgs( |
| 207 | 207 | }); |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | |
| 210 | pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.Progress.Node) !Cache.Path { | |
| 211 | 211 | dev.check(.build_import_lib); |
| 212 | 212 | |
| 213 | const sub_node = prog_node.start(lib_name, 0); | |
| 214 | defer sub_node.end(); | |
| 215 | ||
| 213 | 216 | const gpa = comp.gpa; |
| 214 | 217 | const io = comp.io; |
| 215 | 218 | |
| ... | ... | @@ -218,12 +221,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 218 | 221 | const arena = arena_allocator.allocator(); |
| 219 | 222 | |
| 220 | 223 | const def_file_path = findDef(arena, io, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { |
| 221 | error.FileNotFound => { | |
| 222 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); | |
| 223 | // In this case we will end up putting foo.lib onto the linker line and letting the linker | |
| 224 | // use its library paths to look for libraries and report any problems. | |
| 225 | return; | |
| 226 | }, | |
| 224 | error.FileNotFound => return error.DefNotFound, | |
| 227 | 225 | else => |e| return e, |
| 228 | 226 | }; |
| 229 | 227 | // Only .def.in files need preprocessing |
| ... | ... | @@ -263,14 +261,16 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 263 | 261 | comp.mutex.lockUncancelable(io); |
| 264 | 262 | defer comp.mutex.unlock(io); |
| 265 | 263 | try comp.crt_files.ensureUnusedCapacity(gpa, 1); |
| 264 | ||
| 265 | const crt_file_path: Cache.Path = .{ | |
| 266 | .root_dir = comp.dirs.global_cache, | |
| 267 | .sub_path = sub_path, | |
| 268 | }; | |
| 266 | 269 | comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{ |
| 267 | .full_object_path = .{ | |
| 268 | .root_dir = comp.dirs.global_cache, | |
| 269 | .sub_path = sub_path, | |
| 270 | }, | |
| 270 | .full_object_path = crt_file_path, | |
| 271 | 271 | .lock = man.toOwnedLock(), |
| 272 | 272 | }); |
| 273 | return; | |
| 273 | return crt_file_path; | |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | 276 | const digest = man.final(); |
| ... | ... | @@ -294,6 +294,9 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | const members = members: { |
| 297 | const members_node = sub_node.start("Members", 0); | |
| 298 | defer members_node.end(); | |
| 299 | ||
| 297 | 300 | const input = switch (def_needs_preprocessing) { |
| 298 | 301 | true => pp: { |
| 299 | 302 | var aw: Io.Writer.Allocating = .init(gpa); |
| ... | ... | @@ -357,13 +360,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 357 | 360 | |
| 358 | 361 | comp.mutex.lockUncancelable(io); |
| 359 | 362 | defer comp.mutex.unlock(io); |
| 363 | const crt_file_path: Cache.Path = .{ | |
| 364 | .root_dir = comp.dirs.global_cache, | |
| 365 | .sub_path = lib_final_path, | |
| 366 | }; | |
| 360 | 367 | try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{ |
| 361 | .full_object_path = .{ | |
| 362 | .root_dir = comp.dirs.global_cache, | |
| 363 | .sub_path = lib_final_path, | |
| 364 | }, | |
| 368 | .full_object_path = crt_file_path, | |
| 365 | 369 | .lock = man.toOwnedLock(), |
| 366 | 370 | }); |
| 371 | return crt_file_path; | |
| 367 | 372 | } |
| 368 | 373 | |
| 369 | 374 | pub fn libExists( |
src/link.zig+3-12| ... | ... | @@ -482,7 +482,7 @@ pub const File = struct { |
| 482 | 482 | rpath_list: []const []const u8, |
| 483 | 483 | |
| 484 | 484 | /// Zig compiler development linker flags. |
| 485 | /// Enable dumping of linker's state as JSON. | |
| 485 | /// Enable dumping of linker's state. | |
| 486 | 486 | enable_link_snapshots: bool, |
| 487 | 487 | |
| 488 | 488 | /// Darwin-specific linker flags: |
| ... | ... | @@ -1527,20 +1527,11 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1527 | 1527 | } |
| 1528 | 1528 | } |
| 1529 | 1529 | |
| 1530 | if (target.os.tag == .windows) { | |
| 1530 | if (target.os.tag == .windows and target.abi == .msvc) { | |
| 1531 | 1531 | const inputs: []const struct { |
| 1532 | 1532 | dir: enum { crt, msvc_lib, kernel32_lib }, |
| 1533 | 1533 | name: []const u8, |
| 1534 | } = if (target.abi.isGnu()) switch (comp.config.link_mode) { | |
| 1535 | .dynamic => &.{ | |
| 1536 | .{ .dir = .crt, .name = "dllcrt2.obj" }, | |
| 1537 | .{ .dir = .crt, .name = "libmingw32.lib" }, | |
| 1538 | }, | |
| 1539 | .static => &.{ | |
| 1540 | .{ .dir = .crt, .name = "crt2.obj" }, | |
| 1541 | .{ .dir = .crt, .name = "libmingw32.lib" }, | |
| 1542 | }, | |
| 1543 | } else switch (comp.config.link_mode) { | |
| 1534 | } = switch (comp.config.link_mode) { | |
| 1544 | 1535 | .dynamic => &.{ |
| 1545 | 1536 | .{ .dir = .msvc_lib, .name = "msvcrt.lib" }, |
| 1546 | 1537 | .{ .dir = .msvc_lib, .name = "vcruntime.lib" }, |
src/link/Coff.zig+29-8| ... | ... | @@ -2017,6 +2017,16 @@ fn initHeaders( |
| 2017 | 2017 | .{ .read = true, .write = !is_image }, |
| 2018 | 2018 | ); |
| 2019 | 2019 | } |
| 2020 | ||
| 2021 | // Linker-supplied symbols | |
| 2022 | { | |
| 2023 | const target = &comp.root_mod.resolved_target.result; | |
| 2024 | if (is_image and target.isMinGW()) { | |
| 2025 | const si = try coff.globalSymbol(.{ .name = "__ImageBase", .type = .data }); | |
| 2026 | const sym = si.get(coff); | |
| 2027 | sym.ni = Node.known.header; | |
| 2028 | } | |
| 2029 | } | |
| 2020 | 2030 | } |
| 2021 | 2031 | |
| 2022 | 2032 | pub fn startProgress(coff: *Coff, prog_node: std.Progress.Node) void { |
| ... | ... | @@ -2044,7 +2054,7 @@ pub fn endProgress(coff: *Coff) void { |
| 2044 | 2054 | coff.mf.update_prog_node = .none; |
| 2045 | 2055 | coff.input_prog_node.end(); |
| 2046 | 2056 | coff.input_prog_node = .none; |
| 2047 | if (!isImage(coff)) { | |
| 2057 | if (!coff.isImage()) { | |
| 2048 | 2058 | coff.member_prog_node.end(); |
| 2049 | 2059 | coff.member_prog_node = .none; |
| 2050 | 2060 | coff.symbol_prog_node.end(); |
| ... | ... | @@ -3103,7 +3113,7 @@ fn objectSectionMapIndex( |
| 3103 | 3113 | |
| 3104 | 3114 | const object_section_gop = try coff.object_section_table.getOrPut(gpa, name); |
| 3105 | 3115 | const osmi: Node.ObjectSectionMapIndex = @enumFromInt(object_section_gop.index); |
| 3106 | const sn = if (!object_section_gop.found_existing) sn: { | |
| 3116 | const sym = if (!object_section_gop.found_existing) sn: { | |
| 3107 | 3117 | try coff.ensureUnusedStringCapacity(name_slice.len); |
| 3108 | 3118 | const parent_name = coff.getOrPutStringAssumeCapacity(coff.objectSectionParentName(name_slice)); |
| 3109 | 3119 | const parent = (try coff.pseudoSectionMapIndex(parent_name, alignment, effective_attributes)).symbol(coff); |
| ... | ... | @@ -3140,14 +3150,24 @@ fn objectSectionMapIndex( |
| 3140 | 3150 | assert(sym.loc_relocs == .none); |
| 3141 | 3151 | sym.loc_relocs = @enumFromInt(coff.relocs.items.len); |
| 3142 | 3152 | coff.nodes.appendAssumeCapacity(.{ .object_section = osmi }); |
| 3143 | break :sn sym.section_number; | |
| 3144 | } else object_section_gop.value_ptr.get(coff).section_number; | |
| 3153 | break :sn sym; | |
| 3154 | } else object_section_gop.value_ptr.get(coff); | |
| 3155 | ||
| 3156 | const parent_ni = sym.ni.parent(&coff.mf); | |
| 3157 | const parent_alignment = parent_ni.alignment(&coff.mf); | |
| 3158 | if (alignment.compare(.gt, parent_alignment)) { | |
| 3159 | log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment }); | |
| 3160 | parent_ni.realign(&coff.mf, gpa, alignment, true) catch |err| switch (err) { | |
| 3161 | error.Unimplemented => unreachable, | |
| 3162 | else => |e| return e, | |
| 3163 | }; | |
| 3164 | } | |
| 3145 | 3165 | |
| 3146 | 3166 | try coff.verifyParentSectionAttributes( |
| 3147 | 3167 | .object, |
| 3148 | sn.name(coff), | |
| 3168 | sym.section_number.name(coff), | |
| 3149 | 3169 | name, |
| 3150 | .fromFlags(sn.header(coff).flags), | |
| 3170 | .fromFlags(sym.section_number.header(coff).flags), | |
| 3151 | 3171 | effective_attributes, |
| 3152 | 3172 | ); |
| 3153 | 3173 | |
| ... | ... | @@ -4135,7 +4155,7 @@ fn loadObject( |
| 4135 | 4155 | }, |
| 4136 | 4156 | .weak_external => unreachable, |
| 4137 | 4157 | }); |
| 4138 | sym.section_number = symbol.section_number; | |
| 4158 | sym.section_number = section.si.get(coff).section_number; | |
| 4139 | 4159 | } |
| 4140 | 4160 | |
| 4141 | 4161 | log.debug("addInputSymbol({s}, 0x{x}, {t}=0x{x}) = {d}@{d}", .{ |
| ... | ... | @@ -4988,7 +5008,7 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 4988 | 5008 | const other_ioi = isi.input(coff); |
| 4989 | 5009 | if (loc_sym.gmi == .none) { |
| 4990 | 5010 | // TODO: We could report the name here if we interned it in loadObject |
| 4991 | err.addNote("referenced internally by input '{f}{f}'", .{ | |
| 5011 | err.addNote("referenced by input '{f}{f}'", .{ | |
| 4992 | 5012 | other_ioi.path(coff).fmtEscapeString(), |
| 4993 | 5013 | fmtMemberNameString(other_ioi.memberName(coff)), |
| 4994 | 5014 | }); |
| ... | ... | @@ -5430,6 +5450,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool { |
| 5430 | 5450 | return true; |
| 5431 | 5451 | } |
| 5432 | 5452 | |
| 5453 | // TODO: Only do this if actually referenced? Might have to do on-demand? | |
| 5433 | 5454 | { |
| 5434 | 5455 | // Resolve unresolved .WEAK_EXTERNAL symbols to their aliases |
| 5435 | 5456 | const alias_si = sym.weakAlias(); |
src/link/MappedFile.zig+68-12| ... | ... | @@ -351,15 +351,17 @@ pub const Node = extern struct { |
| 351 | 351 | } |
| 352 | 352 | |
| 353 | 353 | /// Moves and expands a node such that its offset and size are aligned to `new_alignment`. |
| 354 | /// | |
| 354 | /// If it is possible to move the node backwards, this will be done instead of moving it forward. | |
| 355 | /// If `set_alignment` is set, persists `new_alignment` as the node's alignment for future operations. | |
| 355 | 356 | /// Asserts that `ni` is not `Node.Index.root`. |
| 356 | 357 | pub fn realign( |
| 357 | 358 | ni: Node.Index, |
| 358 | 359 | mf: *MappedFile, |
| 359 | 360 | gpa: std.mem.Allocator, |
| 360 | 361 | new_alignment: std.mem.Alignment, |
| 362 | set_alignment: bool, | |
| 361 | 363 | ) Error!void { |
| 362 | mf.realignNode(gpa, ni, new_alignment) catch |err| switch (err) { | |
| 364 | mf.realignNode(gpa, ni, new_alignment, true, set_alignment) catch |err| switch (err) { | |
| 363 | 365 | error.OutOfMemory, |
| 364 | 366 | error.Canceled, |
| 365 | 367 | => |e| return e, |
| ... | ... | @@ -554,6 +556,24 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 554 | 556 | }) Error!Node.Index { |
| 555 | 557 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 556 | 558 | const offset = opts.add_node.alignment.forward(@intCast(opts.offset)); |
| 559 | if (opts.parent != .none) { | |
| 560 | const new_end = offset + opts.add_node.size; | |
| 561 | switch (opts.next) { | |
| 562 | .none => { | |
| 563 | _, const parent_size = opts.parent.location(mf).resolve(mf); | |
| 564 | if (new_end > parent_size) | |
| 565 | try opts.parent.resize(mf, gpa, new_end); | |
| 566 | }, | |
| 567 | else => |next_ni| { | |
| 568 | const next_offset, _ = next_ni.location(mf).resolve(mf); | |
| 569 | if (new_end > next_offset) | |
| 570 | mf.realignNode(gpa, next_ni, opts.add_node.alignment, false, false) catch |err| switch (err) { | |
| 571 | error.Unimplemented => unreachable, | |
| 572 | else => |e| return e, | |
| 573 | }; | |
| 574 | }, | |
| 575 | } | |
| 576 | } | |
| 557 | 577 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { |
| 558 | 578 | if (std.math.cast(u32, offset)) |small_offset| break :location .{ .small, .{ |
| 559 | 579 | .small = .{ .offset = small_offset, .size = 0 }, |
| ... | ... | @@ -595,16 +615,12 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 595 | 615 | }, |
| 596 | 616 | .location_payload = location_payload, |
| 597 | 617 | }; |
| 618 | ||
| 598 | 619 | { |
| 599 | defer { | |
| 600 | free_node.flags.moved = false; | |
| 601 | free_node.flags.resized = false; | |
| 602 | } | |
| 603 | _, const parent_size = opts.parent.location(mf).resolve(mf); | |
| 604 | const required_parent_size = offset + opts.add_node.size; | |
| 605 | if (required_parent_size > parent_size) | |
| 606 | try opts.parent.resize(mf, gpa, required_parent_size); | |
| 607 | 620 | try free_ni.resize(mf, gpa, opts.add_node.size); |
| 621 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); | |
| 622 | free_node.flags.moved = false; | |
| 623 | free_node.flags.resized = false; | |
| 608 | 624 | } |
| 609 | 625 | if (opts.add_node.moved) free_ni.movedAssumeCapacity(mf); |
| 610 | 626 | if (opts.add_node.resized) free_ni.resizedAssumeCapacity(mf); |
| ... | ... | @@ -703,6 +719,7 @@ fn shrinkNode( |
| 703 | 719 | |
| 704 | 720 | // This would require unmapping first |
| 705 | 721 | if (ni == Node.Index.root) return error.Unimplemented; |
| 722 | defer if (std.debug.runtime_safety) mf.verify(); | |
| 706 | 723 | |
| 707 | 724 | if (node.last != .none) { |
| 708 | 725 | const last = node.last.get(mf); |
| ... | ... | @@ -725,9 +742,10 @@ fn shrinkNode( |
| 725 | 742 | const old_file_offset = node.next.fileLocation(mf, false).offset; |
| 726 | 743 | const new_file_offset = (old_file_offset - old_next_offset) + new_next_offset; |
| 727 | 744 | @memmove( |
| 728 | mf.memory_map.memory[new_file_offset..][0..next_size], | |
| 729 | mf.memory_map.memory[old_file_offset..][0..next_size], | |
| 745 | mf.memory_map.memory[@intCast(new_file_offset)..][0..@intCast(next_size)], | |
| 746 | mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(next_size)], | |
| 730 | 747 | ); |
| 748 | @memset(mf.memory_map.memory[@intCast(new_file_offset + next_size)..@intCast(old_file_offset + next_size)], 0); | |
| 731 | 749 | } |
| 732 | 750 | |
| 733 | 751 | node.next.setLocationAssumeCapacity(mf, new_next_offset, next_size); |
| ... | ... | @@ -999,6 +1017,8 @@ fn realignNode( |
| 999 | 1017 | gpa: std.mem.Allocator, |
| 1000 | 1018 | ni: Node.Index, |
| 1001 | 1019 | new_alignment: std.mem.Alignment, |
| 1020 | try_backward: bool, | |
| 1021 | set_alignment: bool, | |
| 1002 | 1022 | ) (Allocator.Error || Io.Cancelable || IoError)!void { |
| 1003 | 1023 | assert(ni != Node.Index.root); // currently unsupported |
| 1004 | 1024 | |
| ... | ... | @@ -1009,7 +1029,12 @@ fn realignNode( |
| 1009 | 1029 | |
| 1010 | 1030 | defer if (std.debug.runtime_safety) mf.verify(); |
| 1011 | 1031 | |
| 1032 | const prev_alignment = node.flags.alignment; | |
| 1012 | 1033 | node.flags.alignment = new_alignment; |
| 1034 | defer { | |
| 1035 | // alignment needs to be temporarily set for the resizes below | |
| 1036 | if (!set_alignment) node.flags.alignment = prev_alignment; | |
| 1037 | } | |
| 1013 | 1038 | |
| 1014 | 1039 | const new_size = node.flags.alignment.forward(@intCast(size)); |
| 1015 | 1040 | if (new_alignment.check(@intCast(old_offset))) { |
| ... | ... | @@ -1026,6 +1051,37 @@ fn realignNode( |
| 1026 | 1051 | }, |
| 1027 | 1052 | }; |
| 1028 | 1053 | |
| 1054 | if (try_backward) { | |
| 1055 | const backward_offset = new_alignment.backward(old_offset); | |
| 1056 | const prev_end = if (node.prev == .none) 0 else prev: { | |
| 1057 | const prev_offset, const prev_size = node.prev.location(mf).resolve(mf); | |
| 1058 | break :prev prev_offset + prev_size; | |
| 1059 | }; | |
| 1060 | ||
| 1061 | if (backward_offset >= prev_end) { | |
| 1062 | try mf.ensureCapacityForSetLocation(gpa); | |
| 1063 | ||
| 1064 | if (node.flags.has_content) { | |
| 1065 | const old_file_offset = ni.fileLocation(mf, false).offset; | |
| 1066 | const new_file_offset = (old_file_offset - old_offset) + backward_offset; | |
| 1067 | @memmove( | |
| 1068 | mf.memory_map.memory[@intCast(new_file_offset)..][0..@intCast(size)], | |
| 1069 | mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], | |
| 1070 | ); | |
| 1071 | @memset(mf.memory_map.memory[@intCast(new_file_offset + size)..@intCast(old_file_offset + size)], 0); | |
| 1072 | } | |
| 1073 | ||
| 1074 | if (backward_offset + new_size <= trailing_end) { | |
| 1075 | ni.setLocationAssumeCapacity(mf, backward_offset, new_size); | |
| 1076 | } else { | |
| 1077 | ni.setLocationAssumeCapacity(mf, backward_offset, size); | |
| 1078 | try mf.resizeNode(gpa, ni, new_size); | |
| 1079 | } | |
| 1080 | ||
| 1081 | return; | |
| 1082 | } | |
| 1083 | } | |
| 1084 | ||
| 1029 | 1085 | const forward_offset = new_alignment.forward(@intCast(old_offset)); |
| 1030 | 1086 | if (forward_offset + new_size <= trailing_end) { |
| 1031 | 1087 | // Shift into the free space if possible |
test/standalone/shared_library/build.zig-2| ... | ... | @@ -20,8 +20,6 @@ pub fn build(b: *std.Build) void { |
| 20 | 20 | if (!use_llvm and target.result.cpu.arch == .loongarch64) continue; // TODO |
| 21 | 21 | if (!use_llvm and target.result.cpu.arch == .powerpc64le) continue; // TODO |
| 22 | 22 | if (!use_llvm and target.result.cpu.arch == .s390x) continue; // TODO |
| 23 | if (!use_llvm and target.result.os.tag == .windows and target.result.abi == .gnu and dyn_libc) | |
| 24 | continue; // TODO: sub-compilation of compiler_rt failed (failed to link with LLD: LibCInstallationNotAvailable) | |
| 25 | 23 | |
| 26 | 24 | const lib = b.addLibrary(.{ |
| 27 | 25 | .linkage = .dynamic, |