mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 20:13:21 +00:00
update image_base references
This commit is contained in:
parent
9a48a5ab07
commit
3b6cb257df
@ -1014,7 +1014,7 @@ pub const InitOptions = struct {
|
||||
entry: ?[]const u8 = null,
|
||||
force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||
stack_size: ?u64 = null,
|
||||
image_base_override: ?u64 = null,
|
||||
image_base: ?u64 = null,
|
||||
version: ?std.SemanticVersion = null,
|
||||
compatibility_version: ?std.SemanticVersion = null,
|
||||
libc_installation: ?*const LibCInstallation = null,
|
||||
@ -1686,7 +1686,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
.major_subsystem_version = options.major_subsystem_version,
|
||||
.minor_subsystem_version = options.minor_subsystem_version,
|
||||
.stack_size = options.stack_size,
|
||||
.image_base_override = options.image_base_override,
|
||||
.image_base = options.image_base,
|
||||
.version_script = options.version_script,
|
||||
.gc_sections = options.linker_gc_sections,
|
||||
.eh_frame_hdr = link_eh_frame_hdr,
|
||||
@ -2429,7 +2429,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
|
||||
man.hash.add(comp.formatted_panics);
|
||||
man.hash.add(mod.emit_h != null);
|
||||
man.hash.add(mod.error_limit);
|
||||
man.hash.addOptional(comp.bin_file.options.want_structured_cfg);
|
||||
man.hash.add(comp.bin_file.options.want_structured_cfg);
|
||||
}
|
||||
|
||||
try man.addOptionalFile(comp.bin_file.options.linker_script);
|
||||
@ -2468,8 +2468,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
|
||||
cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
|
||||
|
||||
man.hash.add(comp.bin_file.stack_size);
|
||||
man.hash.addOptional(comp.bin_file.options.image_base_override);
|
||||
man.hash.addOptional(comp.bin_file.options.gc_sections);
|
||||
man.hash.add(comp.bin_file.options.gc_sections);
|
||||
man.hash.add(comp.bin_file.options.eh_frame_hdr);
|
||||
man.hash.add(comp.bin_file.options.emit_relocs);
|
||||
man.hash.add(comp.bin_file.options.rdynamic);
|
||||
@ -2491,8 +2490,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
|
||||
man.hash.add(comp.bin_file.options.hash_style);
|
||||
man.hash.add(comp.bin_file.options.compress_debug_sections);
|
||||
man.hash.add(comp.bin_file.options.include_compiler_rt);
|
||||
man.hash.addOptional(comp.bin_file.options.sort_section);
|
||||
if (comp.bin_file.options.link_libc) {
|
||||
man.hash.add(comp.bin_file.options.sort_section);
|
||||
if (comp.config.link_libc) {
|
||||
man.hash.add(comp.bin_file.options.libc_installation != null);
|
||||
if (comp.bin_file.options.libc_installation) |libc_installation| {
|
||||
man.hash.addOptionalBytes(libc_installation.crt_dir);
|
||||
@ -2504,39 +2503,50 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
|
||||
man.hash.addOptionalBytes(target.dynamic_linker.get());
|
||||
}
|
||||
man.hash.addOptionalBytes(comp.bin_file.options.soname);
|
||||
man.hash.addOptional(comp.bin_file.options.version);
|
||||
man.hash.add(comp.bin_file.options.version);
|
||||
try link.hashAddSystemLibs(man, comp.system_libs);
|
||||
man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys());
|
||||
man.hash.addOptional(comp.bin_file.allow_shlib_undefined);
|
||||
man.hash.add(comp.bin_file.allow_shlib_undefined);
|
||||
man.hash.add(comp.bin_file.options.bind_global_refs_locally);
|
||||
man.hash.add(comp.bin_file.options.tsan);
|
||||
man.hash.addOptionalBytes(comp.bin_file.options.sysroot);
|
||||
man.hash.add(comp.bin_file.options.linker_optimization);
|
||||
|
||||
// WASM specific stuff
|
||||
man.hash.add(comp.bin_file.options.import_memory);
|
||||
man.hash.add(comp.bin_file.options.export_memory);
|
||||
man.hash.addOptional(comp.bin_file.options.initial_memory);
|
||||
man.hash.addOptional(comp.bin_file.options.max_memory);
|
||||
man.hash.add(comp.bin_file.options.shared_memory);
|
||||
man.hash.addOptional(comp.bin_file.options.global_base);
|
||||
|
||||
// Mach-O specific stuff
|
||||
man.hash.addListOfBytes(comp.framework_dirs);
|
||||
try link.hashAddFrameworks(man, comp.bin_file.options.frameworks);
|
||||
try man.addOptionalFile(comp.bin_file.options.entitlements);
|
||||
man.hash.addOptional(comp.bin_file.options.pagezero_size);
|
||||
man.hash.addOptional(comp.bin_file.options.headerpad_size);
|
||||
man.hash.add(comp.bin_file.options.headerpad_max_install_names);
|
||||
man.hash.add(comp.bin_file.options.dead_strip_dylibs);
|
||||
|
||||
// COFF specific stuff
|
||||
man.hash.addOptional(comp.bin_file.options.subsystem);
|
||||
man.hash.add(comp.bin_file.options.tsaware);
|
||||
man.hash.add(comp.bin_file.options.nxcompat);
|
||||
man.hash.add(comp.bin_file.options.dynamicbase);
|
||||
man.hash.addOptional(comp.bin_file.options.major_subsystem_version);
|
||||
man.hash.addOptional(comp.bin_file.options.minor_subsystem_version);
|
||||
switch (comp.bin_file.tag) {
|
||||
.elf => {
|
||||
const elf = comp.bin_file.cast(link.File.Elf).?;
|
||||
man.hash.add(elf.image_base);
|
||||
},
|
||||
.wasm => {
|
||||
const wasm = comp.bin_file.cast(link.File.Wasm).?;
|
||||
man.hash.add(comp.config.import_memory);
|
||||
man.hash.add(comp.config.export_memory);
|
||||
man.hash.add(comp.config.shared_memory);
|
||||
man.hash.add(wasm.initial_memory);
|
||||
man.hash.add(wasm.max_memory);
|
||||
man.hash.add(wasm.global_base);
|
||||
},
|
||||
.macho => {
|
||||
const macho = comp.bin_file.cast(link.File.MachO).?;
|
||||
man.hash.addListOfBytes(comp.framework_dirs);
|
||||
try link.hashAddFrameworks(man, macho.frameworks);
|
||||
try man.addOptionalFile(macho.entitlements);
|
||||
man.hash.add(macho.pagezero_size);
|
||||
man.hash.add(macho.headerpad_size);
|
||||
man.hash.add(macho.headerpad_max_install_names);
|
||||
man.hash.add(macho.dead_strip_dylibs);
|
||||
},
|
||||
.coff => {
|
||||
const coff = comp.bin_file.cast(link.File.Coff).?;
|
||||
man.hash.add(coff.image_base);
|
||||
man.hash.add(coff.subsystem);
|
||||
man.hash.add(coff.tsaware);
|
||||
man.hash.add(coff.nxcompat);
|
||||
man.hash.add(coff.dynamicbase);
|
||||
man.hash.add(coff.major_subsystem_version);
|
||||
man.hash.add(coff.minor_subsystem_version);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn emitOthers(comp: *Compilation) void {
|
||||
|
||||
@ -102,7 +102,7 @@ pub const File = struct {
|
||||
/// Virtual address of the entry point procedure relative to image base.
|
||||
entry_addr: ?u64,
|
||||
stack_size: ?u64,
|
||||
image_base_override: ?u64,
|
||||
image_base: ?u64,
|
||||
function_sections: bool,
|
||||
data_sections: bool,
|
||||
no_builtin: bool,
|
||||
@ -974,8 +974,9 @@ pub const File = struct {
|
||||
const llvm_bindings = @import("codegen/llvm/bindings.zig");
|
||||
const Builder = @import("codegen/llvm/Builder.zig");
|
||||
const llvm = @import("codegen/llvm.zig");
|
||||
Builder.initializeLLVMTarget(base.options.target.cpu.arch);
|
||||
const os_tag = llvm.targetOs(base.options.target.os.tag);
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
Builder.initializeLLVMTarget(target.cpu.arch);
|
||||
const os_tag = llvm.targetOs(target.os.tag);
|
||||
const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);
|
||||
if (bad) return error.UnableToWriteArchive;
|
||||
|
||||
|
||||
@ -93,10 +93,13 @@ pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
|
||||
}
|
||||
|
||||
pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
|
||||
assert(options.target.ofmt == .c);
|
||||
const target = options.comp.root_mod.resolved_target.result;
|
||||
assert(target.ofmt == .c);
|
||||
const optimize_mode = options.comp.root_mod.optimize_mode;
|
||||
const use_lld = build_options.have_llvm and options.comp.config.use_lld;
|
||||
const use_llvm = options.comp.config.use_llvm;
|
||||
const output_mode = options.comp.config.output_mode;
|
||||
const link_mode = options.comp.config.link_mode;
|
||||
|
||||
// These are caught by `Compilation.Config.resolve`.
|
||||
assert(!use_lld);
|
||||
@ -107,7 +110,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
|
||||
const file = try emit.directory.handle.createFile(emit.sub_path, .{
|
||||
// Truncation is done on `flush`.
|
||||
.truncate = false,
|
||||
.mode = link.determineMode(options),
|
||||
.mode = link.File.determineMode(use_lld, output_mode, link_mode),
|
||||
});
|
||||
errdefer file.close();
|
||||
|
||||
@ -118,7 +121,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
|
||||
.tag = .c,
|
||||
.comp = options.comp,
|
||||
.emit = emit,
|
||||
.gc_sections = options.gc_sections orelse optimize_mode != .Debug,
|
||||
.gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
|
||||
.stack_size = options.stack_size orelse 16777216,
|
||||
.allow_shlib_undefined = options.allow_shlib_undefined orelse false,
|
||||
.file = file,
|
||||
@ -126,6 +129,9 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*C {
|
||||
.build_id = options.build_id,
|
||||
.rpath_list = options.rpath_list,
|
||||
.force_undefined_symbols = options.force_undefined_symbols,
|
||||
.debug_format = options.debug_format orelse .{ .dwarf = .@"32" },
|
||||
.function_sections = options.function_sections,
|
||||
.data_sections = options.data_sections,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
llvm_object: ?*LlvmObject = null,
|
||||
|
||||
base: link.File,
|
||||
image_base: u64,
|
||||
error_flags: link.File.ErrorFlags = .{},
|
||||
|
||||
ptr_width: PtrWidth,
|
||||
@ -352,8 +353,10 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Coff {
|
||||
}
|
||||
|
||||
pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
|
||||
const target = options.comp.root_mod.resolved_target.result;
|
||||
const optimize_mode = options.comp.root_mod.optimize_mode;
|
||||
const comp = options.comp;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const optimize_mode = comp.root_mod.optimize_mode;
|
||||
const output_mode = comp.config.output_mode;
|
||||
const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
|
||||
0...32 => .p32,
|
||||
33...64 => .p64,
|
||||
@ -366,7 +369,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
|
||||
self.* = .{
|
||||
.base = .{
|
||||
.tag = .coff,
|
||||
.comp = options.comp,
|
||||
.comp = comp,
|
||||
.emit = options.emit,
|
||||
.stack_size = options.stack_size orelse 16777216,
|
||||
.gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
|
||||
@ -382,11 +385,25 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Coff {
|
||||
},
|
||||
.ptr_width = ptr_width,
|
||||
.page_size = page_size,
|
||||
.data_directories = comptime mem.zeroes([coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]coff.ImageDataDirectory),
|
||||
|
||||
.data_directories = [1]coff.ImageDataDirectory{.{
|
||||
.virtual_address = 0,
|
||||
.size = 0,
|
||||
}} ** coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES,
|
||||
|
||||
.image_base = options.image_base orelse switch (output_mode) {
|
||||
.Exe => switch (target.cpu.arch) {
|
||||
.aarch64 => 0x140000000,
|
||||
.x86_64, .x86 => 0x400000,
|
||||
else => unreachable,
|
||||
},
|
||||
.Lib => 0x10000000,
|
||||
.Obj => 0,
|
||||
},
|
||||
};
|
||||
|
||||
const use_llvm = options.comp.config.use_llvm;
|
||||
if (use_llvm and options.comp.config.have_zcu) {
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
if (use_llvm and comp.config.have_zcu) {
|
||||
self.llvm_object = try LlvmObject.create(arena, options);
|
||||
}
|
||||
return self;
|
||||
@ -833,7 +850,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
|
||||
}
|
||||
}
|
||||
|
||||
self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase());
|
||||
self.resolveRelocs(atom_index, relocs.items, code, self.image_base);
|
||||
try self.base.file.?.pwriteAll(code, file_offset);
|
||||
|
||||
// Now we can mark the relocs as resolved.
|
||||
@ -879,17 +896,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void {
|
||||
const file_offset = header.pointer_to_raw_data + entry_offset;
|
||||
const vmaddr = header.virtual_address + entry_offset;
|
||||
|
||||
log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.getImageBase() });
|
||||
log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.image_base });
|
||||
|
||||
switch (self.ptr_width) {
|
||||
.p32 => {
|
||||
var buf: [4]u8 = undefined;
|
||||
mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.getImageBase())), .little);
|
||||
mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.image_base)), .little);
|
||||
try self.base.file.?.pwriteAll(&buf, file_offset);
|
||||
},
|
||||
.p64 => {
|
||||
var buf: [8]u8 = undefined;
|
||||
mem.writeInt(u64, &buf, entry_value + self.getImageBase(), .little);
|
||||
mem.writeInt(u64, &buf, entry_value + self.image_base, .little);
|
||||
try self.base.file.?.pwriteAll(&buf, file_offset);
|
||||
},
|
||||
}
|
||||
@ -1467,9 +1484,10 @@ pub fn updateExports(
|
||||
}
|
||||
|
||||
const ip = &mod.intern_pool;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const comp = self.base.comp;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
|
||||
if (self.base.options.use_llvm) {
|
||||
if (comp.config.use_llvm) {
|
||||
// Even in the case of LLVM, we need to notice certain exported symbols in order to
|
||||
// detect the default subsystem.
|
||||
for (exports) |exp| {
|
||||
@ -1485,7 +1503,7 @@ pub fn updateExports(
|
||||
};
|
||||
const decl_cc = exported_decl.ty.fnCallingConvention(mod);
|
||||
if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and
|
||||
self.base.options.link_libc)
|
||||
comp.config.link_libc)
|
||||
{
|
||||
mod.stage1_flags.have_c_main = true;
|
||||
} else if (decl_cc == winapi_cc and target.os.tag == .windows) {
|
||||
@ -1506,7 +1524,7 @@ pub fn updateExports(
|
||||
|
||||
if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
|
||||
|
||||
const gpa = self.base.comp.gpa;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
const metadata = switch (exported) {
|
||||
.decl_index => |decl_index| blk: {
|
||||
@ -2247,8 +2265,6 @@ fn writeHeader(self: *Coff) !void {
|
||||
const subsystem: coff.Subsystem = .WINDOWS_CUI;
|
||||
const size_of_image: u32 = self.getSizeOfImage();
|
||||
const size_of_headers: u32 = mem.alignForward(u32, self.getSizeOfHeaders(), default_file_alignment);
|
||||
const image_base = self.getImageBase();
|
||||
|
||||
const base_of_code = self.sections.get(self.text_section_index.?).header.virtual_address;
|
||||
const base_of_data = self.sections.get(self.data_section_index.?).header.virtual_address;
|
||||
|
||||
@ -2279,7 +2295,7 @@ fn writeHeader(self: *Coff) !void {
|
||||
.address_of_entry_point = self.entry_addr orelse 0,
|
||||
.base_of_code = base_of_code,
|
||||
.base_of_data = base_of_data,
|
||||
.image_base = @as(u32, @intCast(image_base)),
|
||||
.image_base = @intCast(self.image_base),
|
||||
.section_alignment = self.page_size,
|
||||
.file_alignment = default_file_alignment,
|
||||
.major_operating_system_version = 6,
|
||||
@ -2313,7 +2329,7 @@ fn writeHeader(self: *Coff) !void {
|
||||
.size_of_uninitialized_data = size_of_uninitialized_data,
|
||||
.address_of_entry_point = self.entry_addr orelse 0,
|
||||
.base_of_code = base_of_code,
|
||||
.image_base = image_base,
|
||||
.image_base = self.image_base,
|
||||
.section_alignment = self.page_size,
|
||||
.file_alignment = default_file_alignment,
|
||||
.major_operating_system_version = 6,
|
||||
@ -2333,7 +2349,7 @@ fn writeHeader(self: *Coff) !void {
|
||||
.size_of_heap_reserve = default_size_of_heap_reserve,
|
||||
.size_of_heap_commit = default_size_of_heap_commit,
|
||||
.loader_flags = 0,
|
||||
.number_of_rva_and_sizes = @as(u32, @intCast(self.data_directories.len)),
|
||||
.number_of_rva_and_sizes = @intCast(self.data_directories.len),
|
||||
};
|
||||
writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
|
||||
},
|
||||
@ -2447,25 +2463,12 @@ inline fn getSizeOfImage(self: Coff) u32 {
|
||||
|
||||
/// Returns symbol location corresponding to the set entrypoint (if any).
|
||||
pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
|
||||
const entry_name = self.base.options.entry orelse "wWinMainCRTStartup"; // TODO this is incomplete
|
||||
const comp = self.base.comp;
|
||||
const entry_name = comp.config.entry orelse return null;
|
||||
const global_index = self.resolver.get(entry_name) orelse return null;
|
||||
return self.globals.items[global_index];
|
||||
}
|
||||
|
||||
pub fn getImageBase(self: Coff) u64 {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) {
|
||||
.Exe => switch (target.cpu.arch) {
|
||||
.aarch64 => @as(u64, 0x140000000),
|
||||
.x86_64, .x86 => 0x400000,
|
||||
else => unreachable, // unsupported target architecture
|
||||
},
|
||||
.Lib => 0x10000000,
|
||||
.Obj => 0,
|
||||
};
|
||||
return image_base;
|
||||
}
|
||||
|
||||
/// Returns pointer-to-symbol described by `sym_loc` descriptor.
|
||||
pub fn getSymbolPtr(self: *Coff, sym_loc: SymbolWithLoc) *coff.Symbol {
|
||||
assert(sym_loc.file == null); // TODO linking object files
|
||||
|
||||
@ -81,7 +81,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
try man.addOptionalFile(module_obj_path);
|
||||
man.hash.addOptionalBytes(self.base.options.entry);
|
||||
man.hash.add(self.base.stack_size);
|
||||
man.hash.addOptional(self.base.options.image_base_override);
|
||||
man.hash.addOptional(self.image_base);
|
||||
man.hash.addListOfBytes(self.base.options.lib_dirs);
|
||||
man.hash.add(self.base.options.skip_linker_dependencies);
|
||||
if (self.base.options.link_libc) {
|
||||
@ -195,9 +195,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
if (self.base.comp.config.output_mode == .Exe) {
|
||||
try argv.append(try allocPrint(arena, "-STACK:{d}", .{self.base.stack_size}));
|
||||
}
|
||||
if (self.base.options.image_base_override) |image_base| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{image_base}));
|
||||
}
|
||||
try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{self.image_base}));
|
||||
|
||||
if (target.cpu.arch == .x86) {
|
||||
try argv.append("-MACHINE:X86");
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
base: link.File,
|
||||
image_base: u64,
|
||||
|
||||
ptr_width: PtrWidth,
|
||||
|
||||
@ -264,7 +265,6 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
.p32 => @alignOf(elf.Elf32_Phdr),
|
||||
.p64 => @alignOf(elf.Elf64_Phdr),
|
||||
};
|
||||
const image_base = self.calcImageBase();
|
||||
const ehsize: u64 = switch (self.ptr_width) {
|
||||
.p32 => @sizeOf(elf.Elf32_Ehdr),
|
||||
.p64 => @sizeOf(elf.Elf64_Ehdr),
|
||||
@ -279,7 +279,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
.type = elf.PT_PHDR,
|
||||
.flags = elf.PF_R,
|
||||
.@"align" = p_align,
|
||||
.addr = image_base + ehsize,
|
||||
.addr = self.image_base + ehsize,
|
||||
.offset = ehsize,
|
||||
.filesz = reserved,
|
||||
.memsz = reserved,
|
||||
@ -288,7 +288,7 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
.type = elf.PT_LOAD,
|
||||
.flags = elf.PF_R,
|
||||
.@"align" = self.page_size,
|
||||
.addr = image_base,
|
||||
.addr = self.image_base,
|
||||
.offset = 0,
|
||||
.filesz = reserved + ehsize,
|
||||
.memsz = reserved + ehsize,
|
||||
@ -317,12 +317,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
}
|
||||
|
||||
pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
const use_llvm = options.comp.config.use_llvm;
|
||||
const optimize_mode = options.comp.root_mod.optimize_mode;
|
||||
const target = options.comp.root_mod.resolved_target.result;
|
||||
const output_mode = options.comp.config.output_mode;
|
||||
const link_mode = options.comp.config.link_mode;
|
||||
const is_native_os = options.comp.root_mod.resolved_target.is_native_os;
|
||||
const comp = options.comp;
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
const optimize_mode = comp.root_mod.optimize_mode;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const output_mode = comp.config.output_mode;
|
||||
const link_mode = comp.config.link_mode;
|
||||
const is_native_os = comp.root_mod.resolved_target.is_native_os;
|
||||
const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
|
||||
0...32 => .p32,
|
||||
33...64 => .p64,
|
||||
@ -344,7 +345,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
self.* = .{
|
||||
.base = .{
|
||||
.tag = .elf,
|
||||
.comp = options.comp,
|
||||
.comp = comp,
|
||||
.emit = options.emit,
|
||||
.gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
|
||||
.stack_size = options.stack_size orelse 16777216,
|
||||
@ -357,12 +358,21 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Elf {
|
||||
.debug_format = options.debug_format orelse .{ .dwarf = .@"32" },
|
||||
.function_sections = options.function_sections,
|
||||
.data_sections = options.data_sections,
|
||||
|
||||
.image_base = b: {
|
||||
if (is_dyn_lib) break :b 0;
|
||||
if (output_mode == .Exe and comp.config.pie) return 0;
|
||||
return options.image_base orelse switch (ptr_width) {
|
||||
.p32 => 0x1000,
|
||||
.p64 => 0x1000000,
|
||||
};
|
||||
},
|
||||
},
|
||||
.ptr_width = ptr_width,
|
||||
.page_size = page_size,
|
||||
.default_sym_version = default_sym_version,
|
||||
};
|
||||
if (use_llvm and options.comp.config.have_zcu) {
|
||||
if (use_llvm and comp.config.have_zcu) {
|
||||
self.llvm_object = try LlvmObject.create(arena, options);
|
||||
}
|
||||
|
||||
@ -1653,9 +1663,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
|
||||
try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
|
||||
});
|
||||
|
||||
if (self.base.options.image_base_override) |image_base| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base}));
|
||||
}
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
|
||||
|
||||
if (self.base.gc_sections) {
|
||||
try argv.append("--gc-sections");
|
||||
@ -2378,7 +2386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
|
||||
// We can skip hashing libc and libc++ components that we are in charge of building from Zig
|
||||
// installation sources because they are always a product of the compiler version + target information.
|
||||
man.hash.addOptionalBytes(self.base.options.entry);
|
||||
man.hash.addOptional(self.base.options.image_base_override);
|
||||
man.hash.addOptional(self.image_base);
|
||||
man.hash.add(self.base.gc_sections);
|
||||
man.hash.addOptional(self.base.options.sort_section);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if (self.base.options.image_base_override) |image_base| {
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base}));
|
||||
}
|
||||
try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
|
||||
|
||||
if (self.base.options.linker_script) |linker_script| {
|
||||
try argv.append("-T");
|
||||
@ -3321,7 +3327,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
|
||||
// __ehdr_start
|
||||
{
|
||||
const symbol_ptr = self.symbol(self.ehdr_start_index.?);
|
||||
symbol_ptr.value = self.calcImageBase();
|
||||
symbol_ptr.value = self.image_base;
|
||||
symbol_ptr.output_section_index = 1;
|
||||
}
|
||||
|
||||
@ -5631,15 +5637,6 @@ const CsuObjects = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn calcImageBase(self: Elf) u64 {
|
||||
if (self.base.isDynLib()) return 0;
|
||||
if (self.base.isExe() and self.base.options.pie) return 0;
|
||||
return self.base.options.image_base_override orelse switch (self.ptr_width) {
|
||||
.p32 => 0x1000,
|
||||
.p64 => 0x1000000,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isZigSection(self: Elf, shndx: u16) bool {
|
||||
inline for (&[_]?u16{
|
||||
self.zig_text_section_index,
|
||||
|
||||
19
src/main.zig
19
src/main.zig
@ -860,7 +860,7 @@ fn buildOutputType(
|
||||
var test_no_exec = false;
|
||||
var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{};
|
||||
var stack_size: ?u64 = null;
|
||||
var image_base_override: ?u64 = null;
|
||||
var image_base: ?u64 = null;
|
||||
var link_eh_frame_hdr = false;
|
||||
var link_emit_relocs = false;
|
||||
var each_lib_rpath: ?bool = null;
|
||||
@ -1131,10 +1131,7 @@ fn buildOutputType(
|
||||
} else if (mem.eql(u8, arg, "--stack")) {
|
||||
stack_size = parseStackSize(args_iter.nextOrFatal());
|
||||
} else if (mem.eql(u8, arg, "--image-base")) {
|
||||
const next_arg = args_iter.nextOrFatal();
|
||||
image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
|
||||
fatal("unable to parse image base override '{s}': {s}", .{ next_arg, @errorName(err) });
|
||||
};
|
||||
image_base = parseImageBase(args_iter.nextOrFatal());
|
||||
} else if (mem.eql(u8, arg, "--name")) {
|
||||
provided_name = args_iter.nextOrFatal();
|
||||
if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?)))
|
||||
@ -2283,10 +2280,7 @@ fn buildOutputType(
|
||||
} else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) {
|
||||
stack_size = parseStackSize(linker_args_it.nextOrFatal());
|
||||
} else if (mem.eql(u8, arg, "--image-base")) {
|
||||
const image_base = linker_args_it.nextOrFatal();
|
||||
image_base_override = std.fmt.parseUnsigned(u64, image_base, 0) catch |err| {
|
||||
fatal("unable to parse image base override '{s}': {s}", .{ image_base, @errorName(err) });
|
||||
};
|
||||
image_base = parseImageBase(linker_args_it.nextOrFatal());
|
||||
} else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
|
||||
linker_script = linker_args_it.nextOrFatal();
|
||||
} else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
|
||||
@ -3424,7 +3418,7 @@ fn buildOutputType(
|
||||
.link_emit_relocs = link_emit_relocs,
|
||||
.force_undefined_symbols = force_undefined_symbols,
|
||||
.stack_size = stack_size,
|
||||
.image_base_override = image_base_override,
|
||||
.image_base = image_base,
|
||||
.formatted_panics = formatted_panics,
|
||||
.function_sections = function_sections,
|
||||
.data_sections = data_sections,
|
||||
@ -7686,3 +7680,8 @@ fn parseStackSize(s: []const u8) u64 {
|
||||
return std.fmt.parseUnsigned(u64, s, 0) catch |err|
|
||||
fatal("unable to parse stack size '{s}': {s}", .{ s, @errorName(err) });
|
||||
}
|
||||
|
||||
fn parseImageBase(s: []const u8) u64 {
|
||||
return std.fmt.parseUnsigned(u64, s, 0) catch |err|
|
||||
fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) });
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user