authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-24 23:02:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:21-07:00
log944b0ef5188a066c9fe11a297c743bfb3301a02a
treedac962cc7025fda687e1f38e7feed994071b8a1e
parent98dd4f7847c0d50c3367a3bf12a80d5bf7b1fed2

link.File.Coff: fix relationship between createEmpty/open

similar commit to b0c433c80f2e4edd7b60e444b4ea56dacb727051

1 files changed, 85 insertions(+), 85 deletions(-)

src/link/Coff.zig+85-85
...@@ -235,7 +235,7 @@ const ideal_factor = 3;...@@ -235,7 +235,7 @@ const ideal_factor = 3;
235const minimum_text_block_size = 64;235const minimum_text_block_size = 64;
236pub const min_text_capacity = padToIdeal(minimum_text_block_size);236pub const min_text_capacity = padToIdeal(minimum_text_block_size);
237237
238pub fn open(238pub fn createEmpty(
239 arena: Allocator,239 arena: Allocator,
240 comp: *Compilation,240 comp: *Compilation,
241 emit: Compilation.Emit,241 emit: Compilation.Emit,
...@@ -243,36 +243,96 @@ pub fn open(...@@ -243,36 +243,96 @@ pub fn open(
243) !*Coff {243) !*Coff {
244 const target = comp.root_mod.resolved_target.result;244 const target = comp.root_mod.resolved_target.result;
245 assert(target.ofmt == .coff);245 assert(target.ofmt == .coff);
246 const optimize_mode = comp.root_mod.optimize_mode;
247 const output_mode = comp.config.output_mode;
248 const link_mode = comp.config.link_mode;
249 const use_llvm = comp.config.use_llvm;
250 const use_lld = build_options.have_llvm and comp.config.use_lld;
246251
247 const self = try createEmpty(arena, comp, emit, options);252 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
248 errdefer self.base.destroy();253 0...32 => .p32,
254 33...64 => .p64,
255 else => return error.UnsupportedCOFFArchitecture,
256 };
257 const page_size: u32 = switch (target.cpu.arch) {
258 else => 0x1000,
259 };
249260
250 const use_lld = build_options.have_llvm and comp.config.use_lld;261 // If using LLD to link, this code should produce an object file so that it
251 const use_llvm = comp.config.use_llvm;262 // can be passed to LLD.
263 // If using LLVM to generate the object file for the zig compilation unit,
264 // we need a place to put the object file so that it can be subsequently
265 // handled.
266 const zcu_object_sub_path = if (!use_lld and !use_llvm)
267 null
268 else
269 try std.fmt.allocPrint(arena, "{s}.obj", .{emit.sub_path});
270
271 const self = try arena.create(Coff);
272 self.* = .{
273 .base = .{
274 .tag = .coff,
275 .comp = comp,
276 .emit = emit,
277 .zcu_object_sub_path = zcu_object_sub_path,
278 .stack_size = options.stack_size orelse 16777216,
279 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
280 .print_gc_sections = options.print_gc_sections,
281 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
282 .file = null,
283 .disable_lld_caching = options.disable_lld_caching,
284 .build_id = options.build_id,
285 .rpath_list = options.rpath_list,
286 .force_undefined_symbols = options.force_undefined_symbols,
287 },
288 .ptr_width = ptr_width,
289 .page_size = page_size,
290
291 .data_directories = [1]coff.ImageDataDirectory{.{
292 .virtual_address = 0,
293 .size = 0,
294 }} ** coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES,
295
296 .image_base = options.image_base orelse switch (output_mode) {
297 .Exe => switch (target.cpu.arch) {
298 .aarch64 => 0x140000000,
299 .x86_64, .x86 => 0x400000,
300 else => unreachable,
301 },
302 .Lib => 0x10000000,
303 .Obj => 0,
304 },
305
306 .subsystem = options.subsystem,
307 .tsaware = options.tsaware,
308 .nxcompat = options.nxcompat,
309 .dynamicbase = options.dynamicbase,
310 .major_subsystem_version = options.major_subsystem_version orelse 6,
311 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
312 .lib_dirs = options.lib_dirs,
313 .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse
314 return error.EntryAddressTooBig,
315 .module_definition_file = options.module_definition_file,
316 .pdb_out_path = options.pdb_out_path,
317 };
318 if (use_llvm and comp.config.have_zcu) {
319 self.llvm_object = try LlvmObject.create(arena, comp);
320 }
321 errdefer self.base.destroy();
252322
253 if (use_lld and use_llvm) {323 if (use_lld and use_llvm) {
254 // LLVM emits the object file; LLD links it into the final product.324 // LLVM emits the object file; LLD links it into the final product.
255 return self;325 return self;
256 }326 }
257327
258 const sub_path = if (!use_lld) emit.sub_path else p: {328 // What path should this COFF linker code output to?
259 // Open a temporary object file, not the final output file because we329 // If using LLD to link, this code should produce an object file so that it
260 // want to link with LLD.330 // can be passed to LLD.
261 const o_file_path = try std.fmt.allocPrint(arena, "{s}{s}", .{331 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
262 emit.sub_path, target.ofmt.fileExt(target.cpu.arch),
263 });
264 self.base.zcu_object_sub_path = o_file_path;
265 break :p o_file_path;
266 };
267
268 self.base.file = try emit.directory.handle.createFile(sub_path, .{332 self.base.file = try emit.directory.handle.createFile(sub_path, .{
269 .truncate = false,333 .truncate = true,
270 .read = true,334 .read = true,
271 .mode = link.File.determineMode(335 .mode = link.File.determineMode(use_lld, output_mode, link_mode),
272 use_lld,
273 comp.config.output_mode,
274 comp.config.link_mode,
275 ),
276 });336 });
277337
278 assert(self.llvm_object == null);338 assert(self.llvm_object == null);
...@@ -367,75 +427,15 @@ pub fn open(...@@ -367,75 +427,15 @@ pub fn open(
367 return self;427 return self;
368}428}
369429
370pub fn createEmpty(430pub fn open(
371 arena: Allocator,431 arena: Allocator,
372 comp: *Compilation,432 comp: *Compilation,
373 emit: Compilation.Emit,433 emit: Compilation.Emit,
374 options: link.File.OpenOptions,434 options: link.File.OpenOptions,
375) !*Coff {435) !*Coff {
376 const target = comp.root_mod.resolved_target.result;436 // TODO: restore saved linker state, don't truncate the file, and
377 const optimize_mode = comp.root_mod.optimize_mode;437 // participate in incremental compilation.
378 const output_mode = comp.config.output_mode;438 return createEmpty(arena, comp, emit, options);
379 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
380 0...32 => .p32,
381 33...64 => .p64,
382 else => return error.UnsupportedCOFFArchitecture,
383 };
384 const page_size: u32 = switch (target.cpu.arch) {
385 else => 0x1000,
386 };
387 const self = try arena.create(Coff);
388 self.* = .{
389 .base = .{
390 .tag = .coff,
391 .comp = comp,
392 .emit = emit,
393 .stack_size = options.stack_size orelse 16777216,
394 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
395 .print_gc_sections = options.print_gc_sections,
396 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
397 .file = null,
398 .disable_lld_caching = options.disable_lld_caching,
399 .build_id = options.build_id,
400 .rpath_list = options.rpath_list,
401 .force_undefined_symbols = options.force_undefined_symbols,
402 },
403 .ptr_width = ptr_width,
404 .page_size = page_size,
405
406 .data_directories = [1]coff.ImageDataDirectory{.{
407 .virtual_address = 0,
408 .size = 0,
409 }} ** coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES,
410
411 .image_base = options.image_base orelse switch (output_mode) {
412 .Exe => switch (target.cpu.arch) {
413 .aarch64 => 0x140000000,
414 .x86_64, .x86 => 0x400000,
415 else => unreachable,
416 },
417 .Lib => 0x10000000,
418 .Obj => 0,
419 },
420
421 .subsystem = options.subsystem,
422 .tsaware = options.tsaware,
423 .nxcompat = options.nxcompat,
424 .dynamicbase = options.dynamicbase,
425 .major_subsystem_version = options.major_subsystem_version orelse 6,
426 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
427 .lib_dirs = options.lib_dirs,
428 .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse
429 return error.EntryAddressTooBig,
430 .module_definition_file = options.module_definition_file,
431 .pdb_out_path = options.pdb_out_path,
432 };
433
434 const use_llvm = comp.config.use_llvm;
435 if (use_llvm and comp.config.have_zcu) {
436 self.llvm_object = try LlvmObject.create(arena, comp);
437 }
438 return self;
439}439}
440440
441pub fn deinit(self: *Coff) void {441pub fn deinit(self: *Coff) void {