| ... | @@ -377,6 +377,17 @@ pub fn open( | ... | @@ -377,6 +377,17 @@ pub fn open( |
| 377 | comp: *Compilation, | 377 | comp: *Compilation, |
| 378 | emit: Compilation.Emit, | 378 | emit: Compilation.Emit, |
| 379 | options: link.File.OpenOptions, | 379 | options: link.File.OpenOptions, |
| | 380 | ) !*Wasm { |
| | 381 | // TODO: restore saved linker state, don't truncate the file, and |
| | 382 | // participate in incremental compilation. |
| | 383 | return createEmpty(arena, comp, emit, options); |
| | 384 | } |
| | 385 | |
| | 386 | pub fn createEmpty( |
| | 387 | arena: Allocator, |
| | 388 | comp: *Compilation, |
| | 389 | emit: Compilation.Emit, |
| | 390 | options: link.File.OpenOptions, |
| 380 | ) !*Wasm { | 391 | ) !*Wasm { |
| 381 | const gpa = comp.gpa; | 392 | const gpa = comp.gpa; |
| 382 | const target = comp.root_mod.resolved_target.result; | 393 | const target = comp.root_mod.resolved_target.result; |
| ... | @@ -387,7 +398,46 @@ pub fn open( | ... | @@ -387,7 +398,46 @@ pub fn open( |
| 387 | const output_mode = comp.config.output_mode; | 398 | const output_mode = comp.config.output_mode; |
| 388 | const shared_memory = comp.config.shared_memory; | 399 | const shared_memory = comp.config.shared_memory; |
| 389 | | 400 | |
| 390 | const wasm = try createEmpty(arena, comp, emit, options); | 401 | // If using LLD to link, this code should produce an object file so that it |
| | 402 | // can be passed to LLD. |
| | 403 | // If using LLVM to generate the object file for the zig compilation unit, |
| | 404 | // we need a place to put the object file so that it can be subsequently |
| | 405 | // handled. |
| | 406 | const zcu_object_sub_path = if (!use_lld and !use_llvm) |
| | 407 | null |
| | 408 | else |
| | 409 | try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); |
| | 410 | |
| | 411 | const wasm = try arena.create(Wasm); |
| | 412 | wasm.* = .{ |
| | 413 | .base = .{ |
| | 414 | .tag = .wasm, |
| | 415 | .comp = comp, |
| | 416 | .emit = emit, |
| | 417 | .zcu_object_sub_path = zcu_object_sub_path, |
| | 418 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), |
| | 419 | .print_gc_sections = options.print_gc_sections, |
| | 420 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB |
| | 421 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| | 422 | .file = null, |
| | 423 | .disable_lld_caching = options.disable_lld_caching, |
| | 424 | .build_id = options.build_id, |
| | 425 | .rpath_list = options.rpath_list, |
| | 426 | .force_undefined_symbols = options.force_undefined_symbols, |
| | 427 | }, |
| | 428 | .name = undefined, |
| | 429 | .import_table = options.import_table, |
| | 430 | .export_table = options.export_table, |
| | 431 | .import_symbols = options.import_symbols, |
| | 432 | .export_symbol_names = options.export_symbol_names, |
| | 433 | .global_base = options.global_base, |
| | 434 | .initial_memory = options.initial_memory, |
| | 435 | .max_memory = options.max_memory, |
| | 436 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| | 437 | }; |
| | 438 | if (use_llvm and comp.config.have_zcu) { |
| | 439 | wasm.llvm_object = try LlvmObject.create(arena, comp); |
| | 440 | } |
| 391 | errdefer wasm.base.destroy(); | 441 | errdefer wasm.base.destroy(); |
| 392 | | 442 | |
| 393 | if (use_lld and use_llvm) { | 443 | if (use_lld and use_llvm) { |
| ... | @@ -395,17 +445,11 @@ pub fn open( | ... | @@ -395,17 +445,11 @@ pub fn open( |
| 395 | return wasm; | 445 | return wasm; |
| 396 | } | 446 | } |
| 397 | | 447 | |
| 398 | const sub_path = if (!use_lld) emit.sub_path else p: { | 448 | // What path should this Wasm linker code output to? |
| 399 | // Open a temporary object file, not the final output file because we | 449 | // If using LLD to link, this code should produce an object file so that it |
| 400 | // want to link with LLD. | 450 | // can be passed to LLD. |
| 401 | const o_file_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ | 451 | const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path; |
| 402 | emit.sub_path, target.ofmt.fileExt(target.cpu.arch), | | |
| 403 | }); | | |
| 404 | wasm.base.zcu_object_sub_path = o_file_path; | | |
| 405 | break :p o_file_path; | | |
| 406 | }; | | |
| 407 | | 452 | |
| 408 | // TODO: read the file and keep valid parts instead of truncating | | |
| 409 | const file = try emit.directory.handle.createFile(sub_path, .{ | 453 | const file = try emit.directory.handle.createFile(sub_path, .{ |
| 410 | .truncate = true, | 454 | .truncate = true, |
| 411 | .read = true, | 455 | .read = true, |
| ... | @@ -532,48 +576,6 @@ pub fn open( | ... | @@ -532,48 +576,6 @@ pub fn open( |
| 532 | return wasm; | 576 | return wasm; |
| 533 | } | 577 | } |
| 534 | | 578 | |
| 535 | pub fn createEmpty( | | |
| 536 | arena: Allocator, | | |
| 537 | comp: *Compilation, | | |
| 538 | emit: Compilation.Emit, | | |
| 539 | options: link.File.OpenOptions, | | |
| 540 | ) !*Wasm { | | |
| 541 | const use_llvm = comp.config.use_llvm; | | |
| 542 | const output_mode = comp.config.output_mode; | | |
| 543 | | | |
| 544 | const wasm = try arena.create(Wasm); | | |
| 545 | wasm.* = .{ | | |
| 546 | .base = .{ | | |
| 547 | .tag = .wasm, | | |
| 548 | .comp = comp, | | |
| 549 | .emit = emit, | | |
| 550 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), | | |
| 551 | .print_gc_sections = options.print_gc_sections, | | |
| 552 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB | | |
| 553 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | | |
| 554 | .file = null, | | |
| 555 | .disable_lld_caching = options.disable_lld_caching, | | |
| 556 | .build_id = options.build_id, | | |
| 557 | .rpath_list = options.rpath_list, | | |
| 558 | .force_undefined_symbols = options.force_undefined_symbols, | | |
| 559 | }, | | |
| 560 | .name = undefined, | | |
| 561 | .import_table = options.import_table, | | |
| 562 | .export_table = options.export_table, | | |
| 563 | .import_symbols = options.import_symbols, | | |
| 564 | .export_symbol_names = options.export_symbol_names, | | |
| 565 | .global_base = options.global_base, | | |
| 566 | .initial_memory = options.initial_memory, | | |
| 567 | .max_memory = options.max_memory, | | |
| 568 | .wasi_emulated_libs = options.wasi_emulated_libs, | | |
| 569 | }; | | |
| 570 | | | |
| 571 | if (use_llvm) { | | |
| 572 | wasm.llvm_object = try LlvmObject.create(arena, comp); | | |
| 573 | } | | |
| 574 | return wasm; | | |
| 575 | } | | |
| 576 | | | |
| 577 | /// For a given name, creates a new global synthetic symbol. | 579 | /// For a given name, creates a new global synthetic symbol. |
| 578 | /// Leaves index undefined and the default flags (0). | 580 | /// Leaves index undefined and the default flags (0). |
| 579 | fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc { | 581 | fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc { |