| author | |
| committer | |
| log | 3b6cb257dfbcfe7217cdb00819615d1cf1e6b89c |
| tree | 4431c016e34bbda2600a0a582064a1ba932ffe9e |
| parent | 9a48a5ab0784ae9744c72cfcc6d7ad9b2cea6a9c |
7 files changed, 129 insertions(+), 115 deletions(-)
src/Compilation.zig+43-33| ... | ... | @@ -1014,7 +1014,7 @@ pub const InitOptions = struct { |
| 1014 | 1014 | entry: ?[]const u8 = null, |
| 1015 | 1015 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}, |
| 1016 | 1016 | stack_size: ?u64 = null, |
| 1017 | image_base_override: ?u64 = null, | |
| 1017 | image_base: ?u64 = null, | |
| 1018 | 1018 | version: ?std.SemanticVersion = null, |
| 1019 | 1019 | compatibility_version: ?std.SemanticVersion = null, |
| 1020 | 1020 | libc_installation: ?*const LibCInstallation = null, |
| ... | ... | @@ -1686,7 +1686,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1686 | 1686 | .major_subsystem_version = options.major_subsystem_version, |
| 1687 | 1687 | .minor_subsystem_version = options.minor_subsystem_version, |
| 1688 | 1688 | .stack_size = options.stack_size, |
| 1689 | .image_base_override = options.image_base_override, | |
| 1689 | .image_base = options.image_base, | |
| 1690 | 1690 | .version_script = options.version_script, |
| 1691 | 1691 | .gc_sections = options.linker_gc_sections, |
| 1692 | 1692 | .eh_frame_hdr = link_eh_frame_hdr, |
| ... | ... | @@ -2429,7 +2429,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2429 | 2429 | man.hash.add(comp.formatted_panics); |
| 2430 | 2430 | man.hash.add(mod.emit_h != null); |
| 2431 | 2431 | man.hash.add(mod.error_limit); |
| 2432 | man.hash.addOptional(comp.bin_file.options.want_structured_cfg); | |
| 2432 | man.hash.add(comp.bin_file.options.want_structured_cfg); | |
| 2433 | 2433 | } |
| 2434 | 2434 | |
| 2435 | 2435 | try man.addOptionalFile(comp.bin_file.options.linker_script); |
| ... | ... | @@ -2468,8 +2468,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2468 | 2468 | cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc); |
| 2469 | 2469 | |
| 2470 | 2470 | man.hash.add(comp.bin_file.stack_size); |
| 2471 | man.hash.addOptional(comp.bin_file.options.image_base_override); | |
| 2472 | man.hash.addOptional(comp.bin_file.options.gc_sections); | |
| 2471 | man.hash.add(comp.bin_file.options.gc_sections); | |
| 2473 | 2472 | man.hash.add(comp.bin_file.options.eh_frame_hdr); |
| 2474 | 2473 | man.hash.add(comp.bin_file.options.emit_relocs); |
| 2475 | 2474 | man.hash.add(comp.bin_file.options.rdynamic); |
| ... | ... | @@ -2491,8 +2490,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2491 | 2490 | man.hash.add(comp.bin_file.options.hash_style); |
| 2492 | 2491 | man.hash.add(comp.bin_file.options.compress_debug_sections); |
| 2493 | 2492 | man.hash.add(comp.bin_file.options.include_compiler_rt); |
| 2494 | man.hash.addOptional(comp.bin_file.options.sort_section); | |
| 2495 | if (comp.bin_file.options.link_libc) { | |
| 2493 | man.hash.add(comp.bin_file.options.sort_section); | |
| 2494 | if (comp.config.link_libc) { | |
| 2496 | 2495 | man.hash.add(comp.bin_file.options.libc_installation != null); |
| 2497 | 2496 | if (comp.bin_file.options.libc_installation) |libc_installation| { |
| 2498 | 2497 | man.hash.addOptionalBytes(libc_installation.crt_dir); |
| ... | ... | @@ -2504,39 +2503,50 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2504 | 2503 | man.hash.addOptionalBytes(target.dynamic_linker.get()); |
| 2505 | 2504 | } |
| 2506 | 2505 | man.hash.addOptionalBytes(comp.bin_file.options.soname); |
| 2507 | man.hash.addOptional(comp.bin_file.options.version); | |
| 2506 | man.hash.add(comp.bin_file.options.version); | |
| 2508 | 2507 | try link.hashAddSystemLibs(man, comp.system_libs); |
| 2509 | 2508 | man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys()); |
| 2510 | man.hash.addOptional(comp.bin_file.allow_shlib_undefined); | |
| 2509 | man.hash.add(comp.bin_file.allow_shlib_undefined); | |
| 2511 | 2510 | man.hash.add(comp.bin_file.options.bind_global_refs_locally); |
| 2512 | 2511 | man.hash.add(comp.bin_file.options.tsan); |
| 2513 | 2512 | man.hash.addOptionalBytes(comp.bin_file.options.sysroot); |
| 2514 | 2513 | man.hash.add(comp.bin_file.options.linker_optimization); |
| 2515 | 2514 | |
| 2516 | // WASM specific stuff | |
| 2517 | man.hash.add(comp.bin_file.options.import_memory); | |
| 2518 | man.hash.add(comp.bin_file.options.export_memory); | |
| 2519 | man.hash.addOptional(comp.bin_file.options.initial_memory); | |
| 2520 | man.hash.addOptional(comp.bin_file.options.max_memory); | |
| 2521 | man.hash.add(comp.bin_file.options.shared_memory); | |
| 2522 | man.hash.addOptional(comp.bin_file.options.global_base); | |
| 2523 | ||
| 2524 | // Mach-O specific stuff | |
| 2525 | man.hash.addListOfBytes(comp.framework_dirs); | |
| 2526 | try link.hashAddFrameworks(man, comp.bin_file.options.frameworks); | |
| 2527 | try man.addOptionalFile(comp.bin_file.options.entitlements); | |
| 2528 | man.hash.addOptional(comp.bin_file.options.pagezero_size); | |
| 2529 | man.hash.addOptional(comp.bin_file.options.headerpad_size); | |
| 2530 | man.hash.add(comp.bin_file.options.headerpad_max_install_names); | |
| 2531 | man.hash.add(comp.bin_file.options.dead_strip_dylibs); | |
| 2532 | ||
| 2533 | // COFF specific stuff | |
| 2534 | man.hash.addOptional(comp.bin_file.options.subsystem); | |
| 2535 | man.hash.add(comp.bin_file.options.tsaware); | |
| 2536 | man.hash.add(comp.bin_file.options.nxcompat); | |
| 2537 | man.hash.add(comp.bin_file.options.dynamicbase); | |
| 2538 | man.hash.addOptional(comp.bin_file.options.major_subsystem_version); | |
| 2539 | man.hash.addOptional(comp.bin_file.options.minor_subsystem_version); | |
| 2515 | switch (comp.bin_file.tag) { | |
| 2516 | .elf => { | |
| 2517 | const elf = comp.bin_file.cast(link.File.Elf).?; | |
| 2518 | man.hash.add(elf.image_base); | |
| 2519 | }, | |
| 2520 | .wasm => { | |
| 2521 | const wasm = comp.bin_file.cast(link.File.Wasm).?; | |
| 2522 | man.hash.add(comp.config.import_memory); | |
| 2523 | man.hash.add(comp.config.export_memory); | |
| 2524 | man.hash.add(comp.config.shared_memory); | |
| 2525 | man.hash.add(wasm.initial_memory); | |
| 2526 | man.hash.add(wasm.max_memory); | |
| 2527 | man.hash.add(wasm.global_base); | |
| 2528 | }, | |
| 2529 | .macho => { | |
| 2530 | const macho = comp.bin_file.cast(link.File.MachO).?; | |
| 2531 | man.hash.addListOfBytes(comp.framework_dirs); | |
| 2532 | try link.hashAddFrameworks(man, macho.frameworks); | |
| 2533 | try man.addOptionalFile(macho.entitlements); | |
| 2534 | man.hash.add(macho.pagezero_size); | |
| 2535 | man.hash.add(macho.headerpad_size); | |
| 2536 | man.hash.add(macho.headerpad_max_install_names); | |
| 2537 | man.hash.add(macho.dead_strip_dylibs); | |
| 2538 | }, | |
| 2539 | .coff => { | |
| 2540 | const coff = comp.bin_file.cast(link.File.Coff).?; | |
| 2541 | man.hash.add(coff.image_base); | |
| 2542 | man.hash.add(coff.subsystem); | |
| 2543 | man.hash.add(coff.tsaware); | |
| 2544 | man.hash.add(coff.nxcompat); | |
| 2545 | man.hash.add(coff.dynamicbase); | |
| 2546 | man.hash.add(coff.major_subsystem_version); | |
| 2547 | man.hash.add(coff.minor_subsystem_version); | |
| 2548 | }, | |
| 2549 | } | |
| 2540 | 2550 | } |
| 2541 | 2551 | |
| 2542 | 2552 | fn emitOthers(comp: *Compilation) void { |
src/link.zig+4-3| ... | ... | @@ -102,7 +102,7 @@ pub const File = struct { |
| 102 | 102 | /// Virtual address of the entry point procedure relative to image base. |
| 103 | 103 | entry_addr: ?u64, |
| 104 | 104 | stack_size: ?u64, |
| 105 | image_base_override: ?u64, | |
| 105 | image_base: ?u64, | |
| 106 | 106 | function_sections: bool, |
| 107 | 107 | data_sections: bool, |
| 108 | 108 | no_builtin: bool, |
| ... | ... | @@ -974,8 +974,9 @@ pub const File = struct { |
| 974 | 974 | const llvm_bindings = @import("codegen/llvm/bindings.zig"); |
| 975 | 975 | const Builder = @import("codegen/llvm/Builder.zig"); |
| 976 | 976 | const llvm = @import("codegen/llvm.zig"); |
| 977 | Builder.initializeLLVMTarget(base.options.target.cpu.arch); | |
| 978 | const os_tag = llvm.targetOs(base.options.target.os.tag); | |
| 977 | const target = comp.root_mod.resolved_target.result; | |
| 978 | Builder.initializeLLVMTarget(target.cpu.arch); | |
| 979 | const os_tag = llvm.targetOs(target.os.tag); | |
| 979 | 980 | const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag); |
| 980 | 981 | if (bad) return error.UnableToWriteArchive; |
| 981 | 982 |
src/link/C.zig+9-3| ... | ... | @@ -93,10 +93,13 @@ pub fn addString(this: *C, s: []const u8) Allocator.Error!String { |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | 95 | pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C { |
| 96 | assert(options.target.ofmt == .c); | |
| 96 | const target = options.comp.root_mod.resolved_target.result; | |
| 97 | assert(target.ofmt == .c); | |
| 97 | 98 | const optimize_mode = options.comp.root_mod.optimize_mode; |
| 98 | 99 | const use_lld = build_options.have_llvm and options.comp.config.use_lld; |
| 99 | 100 | const use_llvm = options.comp.config.use_llvm; |
| 101 | const output_mode = options.comp.config.output_mode; | |
| 102 | const link_mode = options.comp.config.link_mode; | |
| 100 | 103 | |
| 101 | 104 | // These are caught by `Compilation.Config.resolve`. |
| 102 | 105 | assert(!use_lld); |
| ... | ... | @@ -107,7 +110,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C { |
| 107 | 110 | const file = try emit.directory.handle.createFile(emit.sub_path, .{ |
| 108 | 111 | // Truncation is done on `flush`. |
| 109 | 112 | .truncate = false, |
| 110 | .mode = link.determineMode(options), | |
| 113 | .mode = link.File.determineMode(use_lld, output_mode, link_mode), | |
| 111 | 114 | }); |
| 112 | 115 | errdefer file.close(); |
| 113 | 116 | |
| ... | ... | @@ -118,7 +121,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C { |
| 118 | 121 | .tag = .c, |
| 119 | 122 | .comp = options.comp, |
| 120 | 123 | .emit = emit, |
| 121 | .gc_sections = options.gc_sections orelse optimize_mode != .Debug, | |
| 124 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), | |
| 122 | 125 | .stack_size = options.stack_size orelse 16777216, |
| 123 | 126 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 124 | 127 | .file = file, |
| ... | ... | @@ -126,6 +129,9 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C { |
| 126 | 129 | .build_id = options.build_id, |
| 127 | 130 | .rpath_list = options.rpath_list, |
| 128 | 131 | .force_undefined_symbols = options.force_undefined_symbols, |
| 132 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, | |
| 133 | .function_sections = options.function_sections, | |
| 134 | .data_sections = options.data_sections, | |
| 129 | 135 | }, |
| 130 | 136 | }; |
| 131 | 137 |
src/link/Coff.zig+37-34| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | llvm_object: ?*LlvmObject = null, |
| 8 | 8 | |
| 9 | 9 | base: link.File, |
| 10 | image_base: u64, | |
| 10 | 11 | error_flags: link.File.ErrorFlags = .{}, |
| 11 | 12 | |
| 12 | 13 | ptr_width: PtrWidth, |
| ... | ... | @@ -352,8 +353,10 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Coff { |
| 352 | 353 | } |
| 353 | 354 | |
| 354 | 355 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff { |
| 355 | const target = options.comp.root_mod.resolved_target.result; | |
| 356 | const optimize_mode = options.comp.root_mod.optimize_mode; | |
| 356 | const comp = options.comp; | |
| 357 | const target = comp.root_mod.resolved_target.result; | |
| 358 | const optimize_mode = comp.root_mod.optimize_mode; | |
| 359 | const output_mode = comp.config.output_mode; | |
| 357 | 360 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { |
| 358 | 361 | 0...32 => .p32, |
| 359 | 362 | 33...64 => .p64, |
| ... | ... | @@ -366,7 +369,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff { |
| 366 | 369 | self.* = .{ |
| 367 | 370 | .base = .{ |
| 368 | 371 | .tag = .coff, |
| 369 | .comp = options.comp, | |
| 372 | .comp = comp, | |
| 370 | 373 | .emit = options.emit, |
| 371 | 374 | .stack_size = options.stack_size orelse 16777216, |
| 372 | 375 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), |
| ... | ... | @@ -382,11 +385,25 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff { |
| 382 | 385 | }, |
| 383 | 386 | .ptr_width = ptr_width, |
| 384 | 387 | .page_size = page_size, |
| 385 | .data_directories = comptime mem.zeroes([coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]coff.ImageDataDirectory), | |
| 388 | ||
| 389 | .data_directories = [1]coff.ImageDataDirectory{.{ | |
| 390 | .virtual_address = 0, | |
| 391 | .size = 0, | |
| 392 | }} ** coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES, | |
| 393 | ||
| 394 | .image_base = options.image_base orelse switch (output_mode) { | |
| 395 | .Exe => switch (target.cpu.arch) { | |
| 396 | .aarch64 => 0x140000000, | |
| 397 | .x86_64, .x86 => 0x400000, | |
| 398 | else => unreachable, | |
| 399 | }, | |
| 400 | .Lib => 0x10000000, | |
| 401 | .Obj => 0, | |
| 402 | }, | |
| 386 | 403 | }; |
| 387 | 404 | |
| 388 | const use_llvm = options.comp.config.use_llvm; | |
| 389 | if (use_llvm and options.comp.config.have_zcu) { | |
| 405 | const use_llvm = comp.config.use_llvm; | |
| 406 | if (use_llvm and comp.config.have_zcu) { | |
| 390 | 407 | self.llvm_object = try LlvmObject.create(arena, options); |
| 391 | 408 | } |
| 392 | 409 | return self; |
| ... | ... | @@ -833,7 +850,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { |
| 833 | 850 | } |
| 834 | 851 | } |
| 835 | 852 | |
| 836 | self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase()); | |
| 853 | self.resolveRelocs(atom_index, relocs.items, code, self.image_base); | |
| 837 | 854 | try self.base.file.?.pwriteAll(code, file_offset); |
| 838 | 855 | |
| 839 | 856 | // Now we can mark the relocs as resolved. |
| ... | ... | @@ -879,17 +896,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 879 | 896 | const file_offset = header.pointer_to_raw_data + entry_offset; |
| 880 | 897 | const vmaddr = header.virtual_address + entry_offset; |
| 881 | 898 | |
| 882 | log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.getImageBase() }); | |
| 899 | log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.image_base }); | |
| 883 | 900 | |
| 884 | 901 | switch (self.ptr_width) { |
| 885 | 902 | .p32 => { |
| 886 | 903 | var buf: [4]u8 = undefined; |
| 887 | mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.getImageBase())), .little); | |
| 904 | mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.image_base)), .little); | |
| 888 | 905 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 889 | 906 | }, |
| 890 | 907 | .p64 => { |
| 891 | 908 | var buf: [8]u8 = undefined; |
| 892 | mem.writeInt(u64, &buf, entry_value + self.getImageBase(), .little); | |
| 909 | mem.writeInt(u64, &buf, entry_value + self.image_base, .little); | |
| 893 | 910 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 894 | 911 | }, |
| 895 | 912 | } |
| ... | ... | @@ -1467,9 +1484,10 @@ pub fn updateExports( |
| 1467 | 1484 | } |
| 1468 | 1485 | |
| 1469 | 1486 | const ip = &mod.intern_pool; |
| 1470 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1487 | const comp = self.base.comp; | |
| 1488 | const target = comp.root_mod.resolved_target.result; | |
| 1471 | 1489 | |
| 1472 | if (self.base.options.use_llvm) { | |
| 1490 | if (comp.config.use_llvm) { | |
| 1473 | 1491 | // Even in the case of LLVM, we need to notice certain exported symbols in order to |
| 1474 | 1492 | // detect the default subsystem. |
| 1475 | 1493 | for (exports) |exp| { |
| ... | ... | @@ -1485,7 +1503,7 @@ pub fn updateExports( |
| 1485 | 1503 | }; |
| 1486 | 1504 | const decl_cc = exported_decl.ty.fnCallingConvention(mod); |
| 1487 | 1505 | if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and |
| 1488 | self.base.options.link_libc) | |
| 1506 | comp.config.link_libc) | |
| 1489 | 1507 | { |
| 1490 | 1508 | mod.stage1_flags.have_c_main = true; |
| 1491 | 1509 | } else if (decl_cc == winapi_cc and target.os.tag == .windows) { |
| ... | ... | @@ -1506,7 +1524,7 @@ pub fn updateExports( |
| 1506 | 1524 | |
| 1507 | 1525 | if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports); |
| 1508 | 1526 | |
| 1509 | const gpa = self.base.comp.gpa; | |
| 1527 | const gpa = comp.gpa; | |
| 1510 | 1528 | |
| 1511 | 1529 | const metadata = switch (exported) { |
| 1512 | 1530 | .decl_index => |decl_index| blk: { |
| ... | ... | @@ -2247,8 +2265,6 @@ fn writeHeader(self: *Coff) !void { |
| 2247 | 2265 | const subsystem: coff.Subsystem = .WINDOWS_CUI; |
| 2248 | 2266 | const size_of_image: u32 = self.getSizeOfImage(); |
| 2249 | 2267 | const size_of_headers: u32 = mem.alignForward(u32, self.getSizeOfHeaders(), default_file_alignment); |
| 2250 | const image_base = self.getImageBase(); | |
| 2251 | ||
| 2252 | 2268 | const base_of_code = self.sections.get(self.text_section_index.?).header.virtual_address; |
| 2253 | 2269 | const base_of_data = self.sections.get(self.data_section_index.?).header.virtual_address; |
| 2254 | 2270 | |
| ... | ... | @@ -2279,7 +2295,7 @@ fn writeHeader(self: *Coff) !void { |
| 2279 | 2295 | .address_of_entry_point = self.entry_addr orelse 0, |
| 2280 | 2296 | .base_of_code = base_of_code, |
| 2281 | 2297 | .base_of_data = base_of_data, |
| 2282 | .image_base = @as(u32, @intCast(image_base)), | |
| 2298 | .image_base = @intCast(self.image_base), | |
| 2283 | 2299 | .section_alignment = self.page_size, |
| 2284 | 2300 | .file_alignment = default_file_alignment, |
| 2285 | 2301 | .major_operating_system_version = 6, |
| ... | ... | @@ -2313,7 +2329,7 @@ fn writeHeader(self: *Coff) !void { |
| 2313 | 2329 | .size_of_uninitialized_data = size_of_uninitialized_data, |
| 2314 | 2330 | .address_of_entry_point = self.entry_addr orelse 0, |
| 2315 | 2331 | .base_of_code = base_of_code, |
| 2316 | .image_base = image_base, | |
| 2332 | .image_base = self.image_base, | |
| 2317 | 2333 | .section_alignment = self.page_size, |
| 2318 | 2334 | .file_alignment = default_file_alignment, |
| 2319 | 2335 | .major_operating_system_version = 6, |
| ... | ... | @@ -2333,7 +2349,7 @@ fn writeHeader(self: *Coff) !void { |
| 2333 | 2349 | .size_of_heap_reserve = default_size_of_heap_reserve, |
| 2334 | 2350 | .size_of_heap_commit = default_size_of_heap_commit, |
| 2335 | 2351 | .loader_flags = 0, |
| 2336 | .number_of_rva_and_sizes = @as(u32, @intCast(self.data_directories.len)), | |
| 2352 | .number_of_rva_and_sizes = @intCast(self.data_directories.len), | |
| 2337 | 2353 | }; |
| 2338 | 2354 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; |
| 2339 | 2355 | }, |
| ... | ... | @@ -2447,25 +2463,12 @@ inline fn getSizeOfImage(self: Coff) u32 { |
| 2447 | 2463 | |
| 2448 | 2464 | /// Returns symbol location corresponding to the set entrypoint (if any). |
| 2449 | 2465 | pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { |
| 2450 | const entry_name = self.base.options.entry orelse "wWinMainCRTStartup"; // TODO this is incomplete | |
| 2466 | const comp = self.base.comp; | |
| 2467 | const entry_name = comp.config.entry orelse return null; | |
| 2451 | 2468 | const global_index = self.resolver.get(entry_name) orelse return null; |
| 2452 | 2469 | return self.globals.items[global_index]; |
| 2453 | 2470 | } |
| 2454 | 2471 | |
| 2455 | pub fn getImageBase(self: Coff) u64 { | |
| 2456 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 2457 | const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) { | |
| 2458 | .Exe => switch (target.cpu.arch) { | |
| 2459 | .aarch64 => @as(u64, 0x140000000), | |
| 2460 | .x86_64, .x86 => 0x400000, | |
| 2461 | else => unreachable, // unsupported target architecture | |
| 2462 | }, | |
| 2463 | .Lib => 0x10000000, | |
| 2464 | .Obj => 0, | |
| 2465 | }; | |
| 2466 | return image_base; | |
| 2467 | } | |
| 2468 | ||
| 2469 | 2472 | /// Returns pointer-to-symbol described by `sym_loc` descriptor. |
| 2470 | 2473 | pub fn getSymbolPtr(self: *Coff, sym_loc: SymbolWithLoc) *coff.Symbol { |
| 2471 | 2474 | assert(sym_loc.file == null); // TODO linking object files |
src/link/Coff/lld.zig+2-4| ... | ... | @@ -81,7 +81,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 81 | 81 | try man.addOptionalFile(module_obj_path); |
| 82 | 82 | man.hash.addOptionalBytes(self.base.options.entry); |
| 83 | 83 | man.hash.add(self.base.stack_size); |
| 84 | man.hash.addOptional(self.base.options.image_base_override); | |
| 84 | man.hash.addOptional(self.image_base); | |
| 85 | 85 | man.hash.addListOfBytes(self.base.options.lib_dirs); |
| 86 | 86 | man.hash.add(self.base.options.skip_linker_dependencies); |
| 87 | 87 | if (self.base.options.link_libc) { |
| ... | ... | @@ -195,9 +195,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 195 | 195 | if (self.base.comp.config.output_mode == .Exe) { |
| 196 | 196 | try argv.append(try allocPrint(arena, "-STACK:{d}", .{self.base.stack_size})); |
| 197 | 197 | } |
| 198 | if (self.base.options.image_base_override) |image_base| { | |
| 199 | try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{image_base})); | |
| 200 | } | |
| 198 | try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{self.image_base})); | |
| 201 | 199 | |
| 202 | 200 | if (target.cpu.arch == .x86) { |
| 203 | 201 | try argv.append("-MACHINE:X86"); |
src/link/Elf.zig+25-28| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | base: link.File, |
| 2 | image_base: u64, | |
| 2 | 3 | |
| 3 | 4 | ptr_width: PtrWidth, |
| 4 | 5 | |
| ... | ... | @@ -264,7 +265,6 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 264 | 265 | .p32 => @alignOf(elf.Elf32_Phdr), |
| 265 | 266 | .p64 => @alignOf(elf.Elf64_Phdr), |
| 266 | 267 | }; |
| 267 | const image_base = self.calcImageBase(); | |
| 268 | 268 | const ehsize: u64 = switch (self.ptr_width) { |
| 269 | 269 | .p32 => @sizeOf(elf.Elf32_Ehdr), |
| 270 | 270 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| ... | ... | @@ -279,7 +279,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 279 | 279 | .type = elf.PT_PHDR, |
| 280 | 280 | .flags = elf.PF_R, |
| 281 | 281 | .@"align" = p_align, |
| 282 | .addr = image_base + ehsize, | |
| 282 | .addr = self.image_base + ehsize, | |
| 283 | 283 | .offset = ehsize, |
| 284 | 284 | .filesz = reserved, |
| 285 | 285 | .memsz = reserved, |
| ... | ... | @@ -288,7 +288,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 288 | 288 | .type = elf.PT_LOAD, |
| 289 | 289 | .flags = elf.PF_R, |
| 290 | 290 | .@"align" = self.page_size, |
| 291 | .addr = image_base, | |
| 291 | .addr = self.image_base, | |
| 292 | 292 | .offset = 0, |
| 293 | 293 | .filesz = reserved + ehsize, |
| 294 | 294 | .memsz = reserved + ehsize, |
| ... | ... | @@ -317,12 +317,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | 319 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 320 | const use_llvm = options.comp.config.use_llvm; | |
| 321 | const optimize_mode = options.comp.root_mod.optimize_mode; | |
| 322 | const target = options.comp.root_mod.resolved_target.result; | |
| 323 | const output_mode = options.comp.config.output_mode; | |
| 324 | const link_mode = options.comp.config.link_mode; | |
| 325 | const is_native_os = options.comp.root_mod.resolved_target.is_native_os; | |
| 320 | const comp = options.comp; | |
| 321 | const use_llvm = comp.config.use_llvm; | |
| 322 | const optimize_mode = comp.root_mod.optimize_mode; | |
| 323 | const target = comp.root_mod.resolved_target.result; | |
| 324 | const output_mode = comp.config.output_mode; | |
| 325 | const link_mode = comp.config.link_mode; | |
| 326 | const is_native_os = comp.root_mod.resolved_target.is_native_os; | |
| 326 | 327 | const ptr_width: PtrWidth = switch (target.ptrBitWidth()) { |
| 327 | 328 | 0...32 => .p32, |
| 328 | 329 | 33...64 => .p64, |
| ... | ... | @@ -344,7 +345,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 344 | 345 | self.* = .{ |
| 345 | 346 | .base = .{ |
| 346 | 347 | .tag = .elf, |
| 347 | .comp = options.comp, | |
| 348 | .comp = comp, | |
| 348 | 349 | .emit = options.emit, |
| 349 | 350 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), |
| 350 | 351 | .stack_size = options.stack_size orelse 16777216, |
| ... | ... | @@ -357,12 +358,21 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf { |
| 357 | 358 | .debug_format = options.debug_format orelse .{ .dwarf = .@"32" }, |
| 358 | 359 | .function_sections = options.function_sections, |
| 359 | 360 | .data_sections = options.data_sections, |
| 361 | ||
| 362 | .image_base = b: { | |
| 363 | if (is_dyn_lib) break :b 0; | |
| 364 | if (output_mode == .Exe and comp.config.pie) return 0; | |
| 365 | return options.image_base orelse switch (ptr_width) { | |
| 366 | .p32 => 0x1000, | |
| 367 | .p64 => 0x1000000, | |
| 368 | }; | |
| 369 | }, | |
| 360 | 370 | }, |
| 361 | 371 | .ptr_width = ptr_width, |
| 362 | 372 | .page_size = page_size, |
| 363 | 373 | .default_sym_version = default_sym_version, |
| 364 | 374 | }; |
| 365 | if (use_llvm and options.comp.config.have_zcu) { | |
| 375 | if (use_llvm and comp.config.have_zcu) { | |
| 366 | 376 | self.llvm_object = try LlvmObject.create(arena, options); |
| 367 | 377 | } |
| 368 | 378 | |
| ... | ... | @@ -1653,9 +1663,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1653 | 1663 | try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}), |
| 1654 | 1664 | }); |
| 1655 | 1665 | |
| 1656 | if (self.base.options.image_base_override) |image_base| { | |
| 1657 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base})); | |
| 1658 | } | |
| 1666 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base})); | |
| 1659 | 1667 | |
| 1660 | 1668 | if (self.base.gc_sections) { |
| 1661 | 1669 | try argv.append("--gc-sections"); |
| ... | ... | @@ -2378,7 +2386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2378 | 2386 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 2379 | 2387 | // installation sources because they are always a product of the compiler version + target information. |
| 2380 | 2388 | man.hash.addOptionalBytes(self.base.options.entry); |
| 2381 | man.hash.addOptional(self.base.options.image_base_override); | |
| 2389 | man.hash.addOptional(self.image_base); | |
| 2382 | 2390 | man.hash.add(self.base.gc_sections); |
| 2383 | 2391 | man.hash.addOptional(self.base.options.sort_section); |
| 2384 | 2392 | man.hash.add(self.base.options.eh_frame_hdr); |
| ... | ... | @@ -2549,9 +2557,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2549 | 2557 | } |
| 2550 | 2558 | } |
| 2551 | 2559 | |
| 2552 | if (self.base.options.image_base_override) |image_base| { | |
| 2553 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base})); | |
| 2554 | } | |
| 2560 | try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base})); | |
| 2555 | 2561 | |
| 2556 | 2562 | if (self.base.options.linker_script) |linker_script| { |
| 2557 | 2563 | try argv.append("-T"); |
| ... | ... | @@ -3321,7 +3327,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void { |
| 3321 | 3327 | // __ehdr_start |
| 3322 | 3328 | { |
| 3323 | 3329 | const symbol_ptr = self.symbol(self.ehdr_start_index.?); |
| 3324 | symbol_ptr.value = self.calcImageBase(); | |
| 3330 | symbol_ptr.value = self.image_base; | |
| 3325 | 3331 | symbol_ptr.output_section_index = 1; |
| 3326 | 3332 | } |
| 3327 | 3333 | |
| ... | ... | @@ -5631,15 +5637,6 @@ const CsuObjects = struct { |
| 5631 | 5637 | } |
| 5632 | 5638 | }; |
| 5633 | 5639 | |
| 5634 | pub fn calcImageBase(self: Elf) u64 { | |
| 5635 | if (self.base.isDynLib()) return 0; | |
| 5636 | if (self.base.isExe() and self.base.options.pie) return 0; | |
| 5637 | return self.base.options.image_base_override orelse switch (self.ptr_width) { | |
| 5638 | .p32 => 0x1000, | |
| 5639 | .p64 => 0x1000000, | |
| 5640 | }; | |
| 5641 | } | |
| 5642 | ||
| 5643 | 5640 | pub fn isZigSection(self: Elf, shndx: u16) bool { |
| 5644 | 5641 | inline for (&[_]?u16{ |
| 5645 | 5642 | self.zig_text_section_index, |
src/main.zig+9-10| ... | ... | @@ -860,7 +860,7 @@ fn buildOutputType( |
| 860 | 860 | var test_no_exec = false; |
| 861 | 861 | var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{}; |
| 862 | 862 | var stack_size: ?u64 = null; |
| 863 | var image_base_override: ?u64 = null; | |
| 863 | var image_base: ?u64 = null; | |
| 864 | 864 | var link_eh_frame_hdr = false; |
| 865 | 865 | var link_emit_relocs = false; |
| 866 | 866 | var each_lib_rpath: ?bool = null; |
| ... | ... | @@ -1131,10 +1131,7 @@ fn buildOutputType( |
| 1131 | 1131 | } else if (mem.eql(u8, arg, "--stack")) { |
| 1132 | 1132 | stack_size = parseStackSize(args_iter.nextOrFatal()); |
| 1133 | 1133 | } else if (mem.eql(u8, arg, "--image-base")) { |
| 1134 | const next_arg = args_iter.nextOrFatal(); | |
| 1135 | image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { | |
| 1136 | fatal("unable to parse image base override '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 1137 | }; | |
| 1134 | image_base = parseImageBase(args_iter.nextOrFatal()); | |
| 1138 | 1135 | } else if (mem.eql(u8, arg, "--name")) { |
| 1139 | 1136 | provided_name = args_iter.nextOrFatal(); |
| 1140 | 1137 | if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?))) |
| ... | ... | @@ -2283,10 +2280,7 @@ fn buildOutputType( |
| 2283 | 2280 | } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) { |
| 2284 | 2281 | stack_size = parseStackSize(linker_args_it.nextOrFatal()); |
| 2285 | 2282 | } else if (mem.eql(u8, arg, "--image-base")) { |
| 2286 | const image_base = linker_args_it.nextOrFatal(); | |
| 2287 | image_base_override = std.fmt.parseUnsigned(u64, image_base, 0) catch |err| { | |
| 2288 | fatal("unable to parse image base override '{s}': {s}", .{ image_base, @errorName(err) }); | |
| 2289 | }; | |
| 2283 | image_base = parseImageBase(linker_args_it.nextOrFatal()); | |
| 2290 | 2284 | } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { |
| 2291 | 2285 | linker_script = linker_args_it.nextOrFatal(); |
| 2292 | 2286 | } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { |
| ... | ... | @@ -3424,7 +3418,7 @@ fn buildOutputType( |
| 3424 | 3418 | .link_emit_relocs = link_emit_relocs, |
| 3425 | 3419 | .force_undefined_symbols = force_undefined_symbols, |
| 3426 | 3420 | .stack_size = stack_size, |
| 3427 | .image_base_override = image_base_override, | |
| 3421 | .image_base = image_base, | |
| 3428 | 3422 | .formatted_panics = formatted_panics, |
| 3429 | 3423 | .function_sections = function_sections, |
| 3430 | 3424 | .data_sections = data_sections, |
| ... | ... | @@ -7686,3 +7680,8 @@ fn parseStackSize(s: []const u8) u64 { |
| 7686 | 7680 | return std.fmt.parseUnsigned(u64, s, 0) catch |err| |
| 7687 | 7681 | fatal("unable to parse stack size '{s}': {s}", .{ s, @errorName(err) }); |
| 7688 | 7682 | } |
| 7683 | ||
| 7684 | fn parseImageBase(s: []const u8) u64 { | |
| 7685 | return std.fmt.parseUnsigned(u64, s, 0) catch |err| | |
| 7686 | fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) }); | |
| 7687 | } |