authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-12 14:12:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:19-07:00
log3b6cb257dfbcfe7217cdb00819615d1cf1e6b89c
tree4431c016e34bbda2600a0a582064a1ba932ffe9e
parent9a48a5ab0784ae9744c72cfcc6d7ad9b2cea6a9c

update image_base references


7 files changed, 129 insertions(+), 115 deletions(-)

src/Compilation.zig+43-33
......@@ -1014,7 +1014,7 @@ pub const InitOptions = struct {
10141014 entry: ?[]const u8 = null,
10151015 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{},
10161016 stack_size: ?u64 = null,
1017 image_base_override: ?u64 = null,
1017 image_base: ?u64 = null,
10181018 version: ?std.SemanticVersion = null,
10191019 compatibility_version: ?std.SemanticVersion = null,
10201020 libc_installation: ?*const LibCInstallation = null,
......@@ -1686,7 +1686,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16861686 .major_subsystem_version = options.major_subsystem_version,
16871687 .minor_subsystem_version = options.minor_subsystem_version,
16881688 .stack_size = options.stack_size,
1689 .image_base_override = options.image_base_override,
1689 .image_base = options.image_base,
16901690 .version_script = options.version_script,
16911691 .gc_sections = options.linker_gc_sections,
16921692 .eh_frame_hdr = link_eh_frame_hdr,
......@@ -2429,7 +2429,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
24292429 man.hash.add(comp.formatted_panics);
24302430 man.hash.add(mod.emit_h != null);
24312431 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);
24332433 }
24342434
24352435 try man.addOptionalFile(comp.bin_file.options.linker_script);
......@@ -2468,8 +2468,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
24682468 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
24692469
24702470 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);
24732472 man.hash.add(comp.bin_file.options.eh_frame_hdr);
24742473 man.hash.add(comp.bin_file.options.emit_relocs);
24752474 man.hash.add(comp.bin_file.options.rdynamic);
......@@ -2491,8 +2490,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
24912490 man.hash.add(comp.bin_file.options.hash_style);
24922491 man.hash.add(comp.bin_file.options.compress_debug_sections);
24932492 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) {
24962495 man.hash.add(comp.bin_file.options.libc_installation != null);
24972496 if (comp.bin_file.options.libc_installation) |libc_installation| {
24982497 man.hash.addOptionalBytes(libc_installation.crt_dir);
......@@ -2504,39 +2503,50 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
25042503 man.hash.addOptionalBytes(target.dynamic_linker.get());
25052504 }
25062505 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);
25082507 try link.hashAddSystemLibs(man, comp.system_libs);
25092508 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);
25112510 man.hash.add(comp.bin_file.options.bind_global_refs_locally);
25122511 man.hash.add(comp.bin_file.options.tsan);
25132512 man.hash.addOptionalBytes(comp.bin_file.options.sysroot);
25142513 man.hash.add(comp.bin_file.options.linker_optimization);
25152514
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 }
25402550}
25412551
25422552fn emitOthers(comp: *Compilation) void {
src/link.zig+4-3
......@@ -102,7 +102,7 @@ pub const File = struct {
102102 /// Virtual address of the entry point procedure relative to image base.
103103 entry_addr: ?u64,
104104 stack_size: ?u64,
105 image_base_override: ?u64,
105 image_base: ?u64,
106106 function_sections: bool,
107107 data_sections: bool,
108108 no_builtin: bool,
......@@ -974,8 +974,9 @@ pub const File = struct {
974974 const llvm_bindings = @import("codegen/llvm/bindings.zig");
975975 const Builder = @import("codegen/llvm/Builder.zig");
976976 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);
979980 const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);
980981 if (bad) return error.UnableToWriteArchive;
981982
src/link/C.zig+9-3
......@@ -93,10 +93,13 @@ pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
9393}
9494
9595pub 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);
9798 const optimize_mode = options.comp.root_mod.optimize_mode;
9899 const use_lld = build_options.have_llvm and options.comp.config.use_lld;
99100 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;
100103
101104 // These are caught by `Compilation.Config.resolve`.
102105 assert(!use_lld);
......@@ -107,7 +110,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
107110 const file = try emit.directory.handle.createFile(emit.sub_path, .{
108111 // Truncation is done on `flush`.
109112 .truncate = false,
110 .mode = link.determineMode(options),
113 .mode = link.File.determineMode(use_lld, output_mode, link_mode),
111114 });
112115 errdefer file.close();
113116
......@@ -118,7 +121,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
118121 .tag = .c,
119122 .comp = options.comp,
120123 .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),
122125 .stack_size = options.stack_size orelse 16777216,
123126 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
124127 .file = file,
......@@ -126,6 +129,9 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
126129 .build_id = options.build_id,
127130 .rpath_list = options.rpath_list,
128131 .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,
129135 },
130136 };
131137
src/link/Coff.zig+37-34
......@@ -7,6 +7,7 @@
77llvm_object: ?*LlvmObject = null,
88
99base: link.File,
10image_base: u64,
1011error_flags: link.File.ErrorFlags = .{},
1112
1213ptr_width: PtrWidth,
......@@ -352,8 +353,10 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Coff {
352353}
353354
354355pub 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;
357360 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
358361 0...32 => .p32,
359362 33...64 => .p64,
......@@ -366,7 +369,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
366369 self.* = .{
367370 .base = .{
368371 .tag = .coff,
369 .comp = options.comp,
372 .comp = comp,
370373 .emit = options.emit,
371374 .stack_size = options.stack_size orelse 16777216,
372375 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
......@@ -382,11 +385,25 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
382385 },
383386 .ptr_width = ptr_width,
384387 .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 },
386403 };
387404
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) {
390407 self.llvm_object = try LlvmObject.create(arena, options);
391408 }
392409 return self;
......@@ -833,7 +850,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
833850 }
834851 }
835852
836 self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase());
853 self.resolveRelocs(atom_index, relocs.items, code, self.image_base);
837854 try self.base.file.?.pwriteAll(code, file_offset);
838855
839856 // Now we can mark the relocs as resolved.
......@@ -879,17 +896,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void {
879896 const file_offset = header.pointer_to_raw_data + entry_offset;
880897 const vmaddr = header.virtual_address + entry_offset;
881898
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 });
883900
884901 switch (self.ptr_width) {
885902 .p32 => {
886903 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);
888905 try self.base.file.?.pwriteAll(&buf, file_offset);
889906 },
890907 .p64 => {
891908 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);
893910 try self.base.file.?.pwriteAll(&buf, file_offset);
894911 },
895912 }
......@@ -1467,9 +1484,10 @@ pub fn updateExports(
14671484 }
14681485
14691486 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;
14711489
1472 if (self.base.options.use_llvm) {
1490 if (comp.config.use_llvm) {
14731491 // Even in the case of LLVM, we need to notice certain exported symbols in order to
14741492 // detect the default subsystem.
14751493 for (exports) |exp| {
......@@ -1485,7 +1503,7 @@ pub fn updateExports(
14851503 };
14861504 const decl_cc = exported_decl.ty.fnCallingConvention(mod);
14871505 if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and
1488 self.base.options.link_libc)
1506 comp.config.link_libc)
14891507 {
14901508 mod.stage1_flags.have_c_main = true;
14911509 } else if (decl_cc == winapi_cc and target.os.tag == .windows) {
......@@ -1506,7 +1524,7 @@ pub fn updateExports(
15061524
15071525 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
15081526
1509 const gpa = self.base.comp.gpa;
1527 const gpa = comp.gpa;
15101528
15111529 const metadata = switch (exported) {
15121530 .decl_index => |decl_index| blk: {
......@@ -2247,8 +2265,6 @@ fn writeHeader(self: *Coff) !void {
22472265 const subsystem: coff.Subsystem = .WINDOWS_CUI;
22482266 const size_of_image: u32 = self.getSizeOfImage();
22492267 const size_of_headers: u32 = mem.alignForward(u32, self.getSizeOfHeaders(), default_file_alignment);
2250 const image_base = self.getImageBase();
2251
22522268 const base_of_code = self.sections.get(self.text_section_index.?).header.virtual_address;
22532269 const base_of_data = self.sections.get(self.data_section_index.?).header.virtual_address;
22542270
......@@ -2279,7 +2295,7 @@ fn writeHeader(self: *Coff) !void {
22792295 .address_of_entry_point = self.entry_addr orelse 0,
22802296 .base_of_code = base_of_code,
22812297 .base_of_data = base_of_data,
2282 .image_base = @as(u32, @intCast(image_base)),
2298 .image_base = @intCast(self.image_base),
22832299 .section_alignment = self.page_size,
22842300 .file_alignment = default_file_alignment,
22852301 .major_operating_system_version = 6,
......@@ -2313,7 +2329,7 @@ fn writeHeader(self: *Coff) !void {
23132329 .size_of_uninitialized_data = size_of_uninitialized_data,
23142330 .address_of_entry_point = self.entry_addr orelse 0,
23152331 .base_of_code = base_of_code,
2316 .image_base = image_base,
2332 .image_base = self.image_base,
23172333 .section_alignment = self.page_size,
23182334 .file_alignment = default_file_alignment,
23192335 .major_operating_system_version = 6,
......@@ -2333,7 +2349,7 @@ fn writeHeader(self: *Coff) !void {
23332349 .size_of_heap_reserve = default_size_of_heap_reserve,
23342350 .size_of_heap_commit = default_size_of_heap_commit,
23352351 .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),
23372353 };
23382354 writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
23392355 },
......@@ -2447,25 +2463,12 @@ inline fn getSizeOfImage(self: Coff) u32 {
24472463
24482464/// Returns symbol location corresponding to the set entrypoint (if any).
24492465pub 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;
24512468 const global_index = self.resolver.get(entry_name) orelse return null;
24522469 return self.globals.items[global_index];
24532470}
24542471
2455pub 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
24692472/// Returns pointer-to-symbol described by `sym_loc` descriptor.
24702473pub fn getSymbolPtr(self: *Coff, sym_loc: SymbolWithLoc) *coff.Symbol {
24712474 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
8181 try man.addOptionalFile(module_obj_path);
8282 man.hash.addOptionalBytes(self.base.options.entry);
8383 man.hash.add(self.base.stack_size);
84 man.hash.addOptional(self.base.options.image_base_override);
84 man.hash.addOptional(self.image_base);
8585 man.hash.addListOfBytes(self.base.options.lib_dirs);
8686 man.hash.add(self.base.options.skip_linker_dependencies);
8787 if (self.base.options.link_libc) {
......@@ -195,9 +195,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
195195 if (self.base.comp.config.output_mode == .Exe) {
196196 try argv.append(try allocPrint(arena, "-STACK:{d}", .{self.base.stack_size}));
197197 }
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}));
201199
202200 if (target.cpu.arch == .x86) {
203201 try argv.append("-MACHINE:X86");
src/link/Elf.zig+25-28
......@@ -1,4 +1,5 @@
11base: link.File,
2image_base: u64,
23
34ptr_width: PtrWidth,
45
......@@ -264,7 +265,6 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
264265 .p32 => @alignOf(elf.Elf32_Phdr),
265266 .p64 => @alignOf(elf.Elf64_Phdr),
266267 };
267 const image_base = self.calcImageBase();
268268 const ehsize: u64 = switch (self.ptr_width) {
269269 .p32 => @sizeOf(elf.Elf32_Ehdr),
270270 .p64 => @sizeOf(elf.Elf64_Ehdr),
......@@ -279,7 +279,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
279279 .type = elf.PT_PHDR,
280280 .flags = elf.PF_R,
281281 .@"align" = p_align,
282 .addr = image_base + ehsize,
282 .addr = self.image_base + ehsize,
283283 .offset = ehsize,
284284 .filesz = reserved,
285285 .memsz = reserved,
......@@ -288,7 +288,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
288288 .type = elf.PT_LOAD,
289289 .flags = elf.PF_R,
290290 .@"align" = self.page_size,
291 .addr = image_base,
291 .addr = self.image_base,
292292 .offset = 0,
293293 .filesz = reserved + ehsize,
294294 .memsz = reserved + ehsize,
......@@ -317,12 +317,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
317317}
318318
319319pub 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;
326327 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
327328 0...32 => .p32,
328329 33...64 => .p64,
......@@ -344,7 +345,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
344345 self.* = .{
345346 .base = .{
346347 .tag = .elf,
347 .comp = options.comp,
348 .comp = comp,
348349 .emit = options.emit,
349350 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
350351 .stack_size = options.stack_size orelse 16777216,
......@@ -357,12 +358,21 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
357358 .debug_format = options.debug_format orelse .{ .dwarf = .@"32" },
358359 .function_sections = options.function_sections,
359360 .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 },
360370 },
361371 .ptr_width = ptr_width,
362372 .page_size = page_size,
363373 .default_sym_version = default_sym_version,
364374 };
365 if (use_llvm and options.comp.config.have_zcu) {
375 if (use_llvm and comp.config.have_zcu) {
366376 self.llvm_object = try LlvmObject.create(arena, options);
367377 }
368378
......@@ -1653,9 +1663,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
16531663 try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
16541664 });
16551665
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}));
16591667
16601668 if (self.base.gc_sections) {
16611669 try argv.append("--gc-sections");
......@@ -2378,7 +2386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
23782386 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
23792387 // installation sources because they are always a product of the compiler version + target information.
23802388 man.hash.addOptionalBytes(self.base.options.entry);
2381 man.hash.addOptional(self.base.options.image_base_override);
2389 man.hash.addOptional(self.image_base);
23822390 man.hash.add(self.base.gc_sections);
23832391 man.hash.addOptional(self.base.options.sort_section);
23842392 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
25492557 }
25502558 }
25512559
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}));
25552561
25562562 if (self.base.options.linker_script) |linker_script| {
25572563 try argv.append("-T");
......@@ -3321,7 +3327,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
33213327 // __ehdr_start
33223328 {
33233329 const symbol_ptr = self.symbol(self.ehdr_start_index.?);
3324 symbol_ptr.value = self.calcImageBase();
3330 symbol_ptr.value = self.image_base;
33253331 symbol_ptr.output_section_index = 1;
33263332 }
33273333
......@@ -5631,15 +5637,6 @@ const CsuObjects = struct {
56315637 }
56325638};
56335639
5634pub 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
56435640pub fn isZigSection(self: Elf, shndx: u16) bool {
56445641 inline for (&[_]?u16{
56455642 self.zig_text_section_index,
src/main.zig+9-10
......@@ -860,7 +860,7 @@ fn buildOutputType(
860860 var test_no_exec = false;
861861 var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{};
862862 var stack_size: ?u64 = null;
863 var image_base_override: ?u64 = null;
863 var image_base: ?u64 = null;
864864 var link_eh_frame_hdr = false;
865865 var link_emit_relocs = false;
866866 var each_lib_rpath: ?bool = null;
......@@ -1131,10 +1131,7 @@ fn buildOutputType(
11311131 } else if (mem.eql(u8, arg, "--stack")) {
11321132 stack_size = parseStackSize(args_iter.nextOrFatal());
11331133 } 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());
11381135 } else if (mem.eql(u8, arg, "--name")) {
11391136 provided_name = args_iter.nextOrFatal();
11401137 if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?)))
......@@ -2283,10 +2280,7 @@ fn buildOutputType(
22832280 } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) {
22842281 stack_size = parseStackSize(linker_args_it.nextOrFatal());
22852282 } 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());
22902284 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
22912285 linker_script = linker_args_it.nextOrFatal();
22922286 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
......@@ -3424,7 +3418,7 @@ fn buildOutputType(
34243418 .link_emit_relocs = link_emit_relocs,
34253419 .force_undefined_symbols = force_undefined_symbols,
34263420 .stack_size = stack_size,
3427 .image_base_override = image_base_override,
3421 .image_base = image_base,
34283422 .formatted_panics = formatted_panics,
34293423 .function_sections = function_sections,
34303424 .data_sections = data_sections,
......@@ -7686,3 +7680,8 @@ fn parseStackSize(s: []const u8) u64 {
76867680 return std.fmt.parseUnsigned(u64, s, 0) catch |err|
76877681 fatal("unable to parse stack size '{s}': {s}", .{ s, @errorName(err) });
76887682}
7683
7684fn 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}