From 6d3858dc8a5e5d510a6c9cc972357dda551628b3 Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 30 Sep 2020 18:02:00 +0300 Subject: stage2: use directory handles for imports --- src/Compilation.zig | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 623635a6b0..71d91b8d2a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -8,6 +8,7 @@ const log = std.log.scoped(.compilation); const Target = std.Target; const Value = @import("value.zig").Value; +const Type = @import("type.zig").Type; const target_util = @import("target.zig"); const Package = @import("Package.zig"); const link = @import("link.zig"); @@ -638,15 +639,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const root_scope = rs: { if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) { + const struct_payload = try gpa.create(Type.Payload.EmptyStruct); const root_scope = try gpa.create(Module.Scope.File); + struct_payload.* = .{ .scope = &root_scope.root_container }; root_scope.* = .{ - .sub_file_path = root_pkg.root_src_path, + // TODO this is duped so it can be freed in Container.deinit + .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path), .source = .{ .unloaded = {} }, .contents = .{ .not_available = {} }, .status = .never_loaded, .root_container = .{ .file_scope = root_scope, .decls = .{}, + .ty = Type.initPayload(&struct_payload.base), }, }; break :rs &root_scope.base; @@ -1022,6 +1027,17 @@ pub fn update(self: *Compilation) !void { else => |e| return e, }; } + + // TODO only analyze imports if they are still referenced + for (module.import_table.items()) |entry| { + entry.value.unload(module.gpa); + module.analyzeContainer(&entry.value.root_container) catch |err| switch (err) { + error.AnalysisFail => { + assert(self.totalErrorCount() != 0); + }, + else => |e| return e, + }; + } } } -- cgit v1.2.3 From 4566b273733be9508b6178742293008d8d66451e Mon Sep 17 00:00:00 2001 From: Nathan Bourgeois Date: Thu, 1 Oct 2020 15:57:19 -0400 Subject: Patch in emit relocs support --- lib/std/build.zig | 4 ++++ src/Compilation.zig | 3 +++ src/link.zig | 1 + src/link/Elf.zig | 5 +++++ src/main.zig | 5 +++++ 5 files changed, 18 insertions(+) (limited to 'src/Compilation.zig') diff --git a/lib/std/build.zig b/lib/std/build.zig index 7e3c75bc78..88d416bee6 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1239,6 +1239,7 @@ pub const LibExeObjStep = struct { /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF /// file. link_eh_frame_hdr: bool = false, + link_emit_relocs: bool = false, /// Place every function in its own section so that unused ones may be /// safely garbage-collected during the linking phase. @@ -2075,6 +2076,9 @@ pub const LibExeObjStep = struct { if (self.link_eh_frame_hdr) { try zig_args.append("--eh-frame-hdr"); } + if(self.link_emit_relocs){ + try zig_args.append("-emit-relocs"); + } if (self.link_function_sections) { try zig_args.append("-ffunction-sections"); } diff --git a/src/Compilation.zig b/src/Compilation.zig index 623635a6b0..fc801c7789 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -352,6 +352,7 @@ pub const InitOptions = struct { time_report: bool = false, stack_report: bool = false, link_eh_frame_hdr: bool = false, + link_emit_relocs: bool = false, linker_script: ?[]const u8 = null, version_script: ?[]const u8 = null, override_soname: ?[]const u8 = null, @@ -447,6 +448,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { options.system_libs.len != 0 or options.link_libc or options.link_libcpp or options.link_eh_frame_hdr or + options.link_emit_relocs or options.output_mode == .Lib or options.lld_argv.len != 0 or options.linker_script != null or options.version_script != null) @@ -769,6 +771,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .version_script = options.version_script, .gc_sections = options.linker_gc_sections, .eh_frame_hdr = options.link_eh_frame_hdr, + .emit_relocs = options.link_emit_relocs, .rdynamic = options.rdynamic, .extra_lld_args = options.lld_argv, .override_soname = options.override_soname, diff --git a/src/link.zig b/src/link.zig index 4d28c8a1a7..3b00684170 100644 --- a/src/link.zig +++ b/src/link.zig @@ -60,6 +60,7 @@ pub const Options = struct { link_libcpp: bool, function_sections: bool, eh_frame_hdr: bool, + emit_relocs: bool, rdynamic: bool, z_nodelete: bool, z_defs: bool, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 38b9b1acca..aab7758505 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1286,6 +1286,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { man.hash.add(stack_size); man.hash.add(gc_sections); man.hash.add(self.base.options.eh_frame_hdr); + man.hash.add(self.base.options.emit_relocs); man.hash.add(self.base.options.rdynamic); man.hash.addListOfBytes(self.base.options.extra_lld_args); man.hash.addListOfBytes(self.base.options.lib_dirs); @@ -1364,6 +1365,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { if (self.base.options.eh_frame_hdr) { try argv.append("--eh-frame-hdr"); } + + if (self.base.options.emit_relocs) { + try argv.append("-emit-relocs"); + } if (self.base.options.rdynamic) { try argv.append("--export-dynamic"); diff --git a/src/main.zig b/src/main.zig index d421322c17..d365698d11 100644 --- a/src/main.zig +++ b/src/main.zig @@ -273,6 +273,7 @@ const usage_build_generic = \\ -rdynamic Add all symbols to the dynamic symbol table \\ -rpath [path] Add directory to the runtime library search path \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker + \\ -emit-relocs Enable output of relocation sections for post build tools \\ -dynamic Force output to be dynamically linked \\ -static Force output to be statically linked \\ -Bsymbolic Bind global references locally @@ -438,6 +439,7 @@ fn buildOutputType( var use_lld: ?bool = null; var use_clang: ?bool = null; var link_eh_frame_hdr = false; + var link_emit_relocs = false; var each_lib_rpath = false; var libc_paths_file: ?[]const u8 = null; var machine_code_model: std.builtin.CodeModel = .default; @@ -838,6 +840,8 @@ fn buildOutputType( function_sections = true; } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; + } else if (mem.eql(u8, arg, "-emit-relocs")) { + link_emit_relocs = true; } else if (mem.eql(u8, arg, "-Bsymbolic")) { linker_bind_global_refs_locally = true; } else if (mem.eql(u8, arg, "--verbose-link")) { @@ -1580,6 +1584,7 @@ fn buildOutputType( .linker_z_nodelete = linker_z_nodelete, .linker_z_defs = linker_z_defs, .link_eh_frame_hdr = link_eh_frame_hdr, + .link_emit_relocs = link_emit_relocs, .stack_size_override = stack_size_override, .strip = strip, .single_threaded = single_threaded, -- cgit v1.2.3 From 52ba2c3a43a88a4db30cff47f2f3eff8c3d5be19 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sat, 3 Oct 2020 19:26:21 +0300 Subject: Reintroduce progress bar when compiling C files --- src/Compilation.zig | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index fc801c7789..5288dad0d0 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1149,7 +1149,15 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { }; } -pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { +pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemory }!void { + var progress: std.Progress = .{}; + var main_progress_node = try progress.start("", null); + defer main_progress_node.end(); + if (self.color == .Off) progress.terminal = null; + + var c_comp_progress_node = main_progress_node.start("Compile C Objects", self.c_source_files.len); + defer c_comp_progress_node.end(); + while (self.work_queue.readItem()) |work_item| switch (work_item) { .codegen_decl => |decl| switch (decl.analysis) { .unreferenced => unreachable, @@ -1226,7 +1234,7 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { }; }, .c_object => |c_object| { - self.updateCObject(c_object) catch |err| switch (err) { + self.updateCObject(c_object, &c_comp_progress_node) catch |err| switch (err) { error.AnalysisFail => continue, else => { try self.failed_c_objects.ensureCapacity(self.gpa, self.failed_c_objects.items().len + 1); @@ -1312,7 +1320,7 @@ pub fn performAllTheWork(self: *Compilation) error{OutOfMemory}!void { if (!build_options.is_stage1) unreachable; - self.updateStage1Module() catch |err| { + self.updateStage1Module(main_progress_node) catch |err| { fatal("unable to build stage1 zig object: {}", .{@errorName(err)}); }; }, @@ -1473,7 +1481,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { }; } -fn updateCObject(comp: *Compilation, c_object: *CObject) !void { +fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: *std.Progress.Node) !void { if (!build_options.have_llvm) { return comp.failCObj(c_object, "clang not available: compiler built without LLVM extensions", .{}); } @@ -1516,6 +1524,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void { const arena = &arena_allocator.allocator; const c_source_basename = std.fs.path.basename(c_object.src.src_path); + + c_comp_progress_node.activate(); + var child_progress_node = c_comp_progress_node.start(c_source_basename, null); + child_progress_node.activate(); + defer child_progress_node.end(); + // Special case when doing build-obj for just one C file. When there are more than one object // file and building an object we need to link them together, but with just one it should go // directly to the output file. @@ -2509,7 +2523,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR }; } -fn updateStage1Module(comp: *Compilation) !void { +fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void { const tracy = trace(@src()); defer tracy.end(); @@ -2615,10 +2629,6 @@ fn updateStage1Module(comp: *Compilation) !void { .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, .llvm_cpu_features = comp.bin_file.options.llvm_cpu_features.?, }; - var progress: std.Progress = .{}; - var main_progress_node = try progress.start("", null); - defer main_progress_node.end(); - if (comp.color == .Off) progress.terminal = null; comp.stage1_cache_manifest = &man; -- cgit v1.2.3 From 1d777e99588be047ec4d7650f048b043d6e52da0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 4 Oct 2020 17:48:07 -0700 Subject: add --image-base support Based on #6121 by Jay Petacat. --- lib/std/build.zig | 8 ++++++++ src/Compilation.zig | 3 +++ src/link.zig | 1 + src/link/Coff.zig | 30 +++++++++++++++++------------- src/link/Elf.zig | 5 +++++ src/main.zig | 36 ++++++++++++++++++++++++++++++------ 6 files changed, 64 insertions(+), 19 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/std/build.zig b/lib/std/build.zig index 8749c7ce2d..bb9744859c 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1232,6 +1232,9 @@ pub const LibExeObjStep = struct { installed_path: ?[]const u8, install_step: ?*InstallArtifactStep, + /// Base address for an executable image. + image_base: ?u64 = null, + libc_file: ?[]const u8 = null, valgrind_support: ?bool = null, @@ -2041,6 +2044,11 @@ pub const LibExeObjStep = struct { try zig_args.append("--pkg-end"); } + if (self.image_base) |image_base| { + try zig_args.append("--image-base"); + try zig_args.append(image_base); + } + if (self.filter) |filter| { try zig_args.append("--test-filter"); try zig_args.append(filter); diff --git a/src/Compilation.zig b/src/Compilation.zig index 16a475b2fc..1085e2d779 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -378,6 +378,7 @@ pub const InitOptions = struct { is_compiler_rt_or_libc: bool = false, parent_compilation_link_libc: bool = false, stack_size_override: ?u64 = null, + image_base_override: ?u64 = null, self_exe_path: ?[]const u8 = null, version: ?std.builtin.Version = null, libc_installation: ?*const LibCInstallation = null, @@ -452,6 +453,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { options.link_emit_relocs or options.output_mode == .Lib or options.lld_argv.len != 0 or + options.image_base_override != null or options.linker_script != null or options.version_script != null) { break :blk true; @@ -772,6 +774,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .z_nodelete = options.linker_z_nodelete, .z_defs = options.linker_z_defs, .stack_size_override = options.stack_size_override, + .image_base_override = options.image_base_override, .linker_script = options.linker_script, .version_script = options.version_script, .gc_sections = options.linker_gc_sections, diff --git a/src/link.zig b/src/link.zig index 3b00684170..139977b3e2 100644 --- a/src/link.zig +++ b/src/link.zig @@ -45,6 +45,7 @@ pub const Options = struct { program_code_size_hint: u64 = 256 * 1024, entry_addr: ?u64 = null, stack_size_override: ?u64, + image_base_override: ?u64, /// Set to `true` to omit debug info. strip: bool, /// If this is true then this link code is responsible for outputting an object diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 3f462582e7..24c3833e0a 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -22,10 +22,10 @@ const minimum_text_block_size = 64 * allocation_padding; const section_alignment = 4096; const file_alignment = 512; -const image_base = 0x400_000; +const default_image_base = 0x400_000; const section_table_size = 2 * 40; comptime { - assert(mem.isAligned(image_base, section_alignment)); + assert(mem.isAligned(default_image_base, section_alignment)); } pub const base_tag: link.File.Tag = .coff; @@ -55,7 +55,7 @@ offset_table: std.ArrayListUnmanaged(u64) = .{}, /// Free list of offset table indices offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, -/// Virtual address of the entry point procedure relative to `image_base` +/// Virtual address of the entry point procedure relative to image base. entry_addr: ?u32 = null, /// Absolute virtual address of the text section when the executable is loaded in memory. @@ -183,14 +183,14 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio self.section_data_offset = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, file_alignment); const section_data_relative_virtual_address = mem.alignForwardGeneric(u32, self.section_table_offset + section_table_size, section_alignment); - self.offset_table_virtual_address = image_base + section_data_relative_virtual_address; + self.offset_table_virtual_address = default_image_base + section_data_relative_virtual_address; self.offset_table_size = default_offset_table_size; self.section_table_offset = section_table_offset; - self.text_section_virtual_address = image_base + section_data_relative_virtual_address + section_alignment; + self.text_section_virtual_address = default_image_base + section_data_relative_virtual_address + section_alignment; self.text_section_size = default_size_of_code; // Size of file when loaded in memory - const size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + default_size_of_code, section_alignment); + const size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - default_image_base + default_size_of_code, section_alignment); mem.writeIntLittle(u16, hdr_data[index..][0..2], optional_header_size); index += 2; @@ -234,11 +234,11 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio index += 4; // Image base address - mem.writeIntLittle(u32, hdr_data[index..][0..4], image_base); + mem.writeIntLittle(u32, hdr_data[index..][0..4], default_image_base); index += 4; } else { // Image base address - mem.writeIntLittle(u64, hdr_data[index..][0..8], image_base); + mem.writeIntLittle(u64, hdr_data[index..][0..8], default_image_base); index += 8; } @@ -328,7 +328,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio mem.writeIntLittle(u32, hdr_data[index..][0..4], default_offset_table_size); index += 4; // Virtual address (u32) - mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - image_base); + mem.writeIntLittle(u32, hdr_data[index..][0..4], self.offset_table_virtual_address - default_image_base); index += 4; } else { mem.set(u8, hdr_data[index..][0..8], 0); @@ -354,7 +354,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio mem.writeIntLittle(u32, hdr_data[index..][0..4], default_size_of_code); index += 4; // Virtual address (u32) - mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - image_base); + mem.writeIntLittle(u32, hdr_data[index..][0..4], self.text_section_virtual_address - default_image_base); index += 4; } else { mem.set(u8, hdr_data[index..][0..8], 0); @@ -601,7 +601,7 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { // Write .text new virtual address self.text_section_virtual_address = self.text_section_virtual_address + va_offset; - mem.writeIntLittle(u32, buf[0..4], self.text_section_virtual_address - image_base); + mem.writeIntLittle(u32, buf[0..4], self.text_section_virtual_address - default_image_base); try self.base.file.?.pwriteAll(buf[0..4], self.section_table_offset + 40 + 12); // Fix the VAs in the offset table @@ -716,7 +716,7 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, } } if (mem.eql(u8, exp.options.name, "_start")) { - self.entry_addr = decl.link.coff.getVAddr(self.*) - image_base; + self.entry_addr = decl.link.coff.getVAddr(self.*) - default_image_base; } else { try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.items().len + 1); module.failed_exports.putAssumeCapacityNoClobber( @@ -754,7 +754,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { } if (self.base.options.output_mode == .Exe and self.size_of_image_dirty) { - const new_size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - image_base + self.text_section_size, section_alignment); + const new_size_of_image = mem.alignForwardGeneric(u32, self.text_section_virtual_address - default_image_base + self.text_section_size, section_alignment); var buf: [4]u8 = undefined; mem.writeIntLittle(u32, &buf, new_size_of_image); try self.base.file.?.pwriteAll(&buf, self.optional_header_offset + 56); @@ -832,6 +832,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { } try man.addOptionalFile(module_obj_path); man.hash.addOptional(self.base.options.stack_size_override); + man.hash.addOptional(self.base.options.image_base_override); man.hash.addListOfBytes(self.base.options.extra_lld_args); man.hash.addListOfBytes(self.base.options.lib_dirs); man.hash.add(self.base.options.is_compiler_rt_or_libc); @@ -914,6 +915,9 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { const stack_size = self.base.options.stack_size_override orelse 16777216; try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size})); } + if (self.base.options.image_base_override) |image_base| { + try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{image_base})); + } if (target.cpu.arch == .i386) { try argv.append("-MACHINE:X86"); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 8e7a02114e..df56bb8bb4 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1284,6 +1284,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { // 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.add(stack_size); + man.hash.addOptional(self.base.options.image_base_override); man.hash.add(gc_sections); man.hash.add(self.base.options.eh_frame_hdr); man.hash.add(self.base.options.emit_relocs); @@ -1353,6 +1354,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { try argv.append(try std.fmt.allocPrint(arena, "stack-size={}", .{stack_size})); } + if (self.base.options.image_base_override) |image_base| { + try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base})); + } + if (self.base.options.linker_script) |linker_script| { try argv.append("-T"); try argv.append(linker_script); diff --git a/src/main.zig b/src/main.zig index 4fddf9ed21..acfe703291 100644 --- a/src/main.zig +++ b/src/main.zig @@ -279,6 +279,7 @@ const usage_build_generic = \\ -Bsymbolic Bind global references locally \\ --subsystem [subsystem] (windows) /SUBSYSTEM: to the linker\n" \\ --stack [size] Override default stack size + \\ --image-base [addr] Set base address for executable image \\ -framework [name] (darwin) link against framework \\ -F[dir] (darwin) add search path for frameworks \\ @@ -435,6 +436,7 @@ fn buildOutputType( var linker_z_defs = false; var test_evented_io = false; var stack_size_override: ?u64 = null; + var image_base_override: ?u64 = null; var use_llvm: ?bool = null; var use_lld: ?bool = null; var use_clang: ?bool = null; @@ -628,9 +630,11 @@ fn buildOutputType( } else if (mem.eql(u8, arg, "--stack")) { if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); i += 1; - stack_size_override = std.fmt.parseInt(u64, args[i], 10) catch |err| { - fatal("unable to parse '{}': {}", .{ arg, @errorName(err) }); - }; + stack_size_override = parseAnyBaseInt(args[i]); + } else if (mem.eql(u8, arg, "--image-base")) { + if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); + i += 1; + image_base_override = parseAnyBaseInt(args[i]); } else if (mem.eql(u8, arg, "--name")) { if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); i += 1; @@ -1147,9 +1151,13 @@ fn buildOutputType( if (i >= linker_args.items.len) { fatal("expected linker arg after '{}'", .{arg}); } - stack_size_override = std.fmt.parseInt(u64, linker_args.items[i], 10) catch |err| { - fatal("unable to parse '{}': {}", .{ arg, @errorName(err) }); - }; + stack_size_override = parseAnyBaseInt(linker_args.items[i]); + } else if (mem.eql(u8, arg, "--image-base")) { + i += 1; + if (i >= linker_args.items.len) { + fatal("expected linker arg after '{}'", .{arg}); + } + image_base_override = parseAnyBaseInt(linker_args.items[i]); } else { warn("unsupported linker arg: {}", .{arg}); } @@ -1595,6 +1603,7 @@ fn buildOutputType( .link_eh_frame_hdr = link_eh_frame_hdr, .link_emit_relocs = link_emit_relocs, .stack_size_override = stack_size_override, + .image_base_override = image_base_override, .strip = strip, .single_threaded = single_threaded, .function_sections = function_sections, @@ -3051,3 +3060,18 @@ pub fn cleanExit() void { process.exit(0); } } + +fn parseAnyBaseInt(prefixed_bytes: []const u8) u64 { + const base: u8 = if (mem.startsWith(u8, prefixed_bytes, "0x")) + 16 + else if (mem.startsWith(u8, prefixed_bytes, "0o")) + 8 + else if (mem.startsWith(u8, prefixed_bytes, "0b")) + 2 + else + @as(u8, 10); + const bytes = if (base == 10) prefixed_bytes else prefixed_bytes[2..]; + return std.fmt.parseInt(u64, bytes, base) catch |err| { + fatal("unable to parse '{}': {}", .{ prefixed_bytes, @errorName(err) }); + }; +} -- cgit v1.2.3 From dce74c31cc95cc75d8eecbe9894add2785fc10ed Mon Sep 17 00:00:00 2001 From: "Felix (xq) Queißner" Date: Wed, 30 Sep 2020 22:30:35 +0200 Subject: Depending on system libs only enforces libraries to require dynamic linking, but neither static libs nor object files. --- src/Compilation.zig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 1085e2d779..2ebc1b830d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -478,8 +478,12 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { { break :dl true; } - if (options.system_libs.len != 0) - break :dl true; + if (options.system_libs.len != 0) { + // when creating a executable that links to system libraries, + // we require dynamic linking, but we must not link static libraries + // or object files dynamically! + break :dl (options.output_mode == .Exe); + } break :dl false; }; -- cgit v1.2.3 From 55ac973953da88c3a108398849ee29f797c4ae52 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 4 Oct 2020 23:16:46 -0700 Subject: fix each-lib-rpath functionality It was regressed in 2 ways from the merge of #6250: * it was not being enabled by default when the target OS is native. * we were testing the libfoo.so file path existence with bogus format string ('{}' instead of '{s}') and so it ended up being something like "libstd.HashMap(K,V,...).Entry.so" instead of "libfoo.so". Using {} rather than {s} is a footgun, be careful! Previous functionality is now restored. closes #6523 --- src/Compilation.zig | 2 +- src/link/Elf.zig | 5 +++-- src/main.zig | 9 ++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 2ebc1b830d..f33ada9362 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -800,7 +800,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .llvm_cpu_features = llvm_cpu_features, .is_compiler_rt_or_libc = options.is_compiler_rt_or_libc, .parent_compilation_link_libc = options.parent_compilation_link_libc, - .each_lib_rpath = options.each_lib_rpath orelse false, + .each_lib_rpath = options.each_lib_rpath orelse options.is_native_os, .disable_lld_caching = options.disable_lld_caching, .subsystem = options.subsystem, .is_test = options.is_test, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index df56bb8bb4..26f3c8e70d 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1453,10 +1453,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { var test_path = std.ArrayList(u8).init(self.base.allocator); defer test_path.deinit(); for (self.base.options.lib_dirs) |lib_dir_path| { - for (self.base.options.system_libs.items()) |link_lib| { + for (self.base.options.system_libs.items()) |entry| { + const link_lib = entry.key; test_path.shrinkRetainingCapacity(0); const sep = fs.path.sep_str; - try test_path.writer().print("{}" ++ sep ++ "lib{}.so", .{ lib_dir_path, link_lib }); + try test_path.writer().print("{s}" ++ sep ++ "lib{s}.so", .{ lib_dir_path, link_lib }); fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { error.FileNotFound => continue, else => |e| return e, diff --git a/src/main.zig b/src/main.zig index acfe703291..cd8fefce87 100644 --- a/src/main.zig +++ b/src/main.zig @@ -268,10 +268,11 @@ const usage_build_generic = \\ -T[script], --script [script] Use a custom linker script \\ --version-script [path] Provide a version .map file \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so) - \\ --each-lib-rpath Add rpath for each used dynamic library \\ --version [ver] Dynamic library semver \\ -rdynamic Add all symbols to the dynamic symbol table \\ -rpath [path] Add directory to the runtime library search path + \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library + \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker \\ --emit-relocs Enable output of relocation sections for post build tools \\ -dynamic Force output to be dynamically linked @@ -442,7 +443,7 @@ fn buildOutputType( var use_clang: ?bool = null; var link_eh_frame_hdr = false; var link_emit_relocs = false; - var each_lib_rpath = false; + var each_lib_rpath: ?bool = null; var libc_paths_file: ?[]const u8 = null; var machine_code_model: std.builtin.CodeModel = .default; var runtime_args_start: ?usize = null; @@ -739,8 +740,10 @@ fn buildOutputType( if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); i += 1; override_lib_dir = args[i]; - } else if (mem.eql(u8, arg, "--each-lib-rpath")) { + } else if (mem.eql(u8, arg, "-feach-lib-rpath")) { each_lib_rpath = true; + } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) { + each_lib_rpath = false; } else if (mem.eql(u8, arg, "--enable-cache")) { enable_cache = true; } else if (mem.eql(u8, arg, "--test-cmd-bin")) { -- cgit v1.2.3 From dd4771a5d2815004a75a90895fe45addb3a015d1 Mon Sep 17 00:00:00 2001 From: travisstaloch Date: Tue, 6 Oct 2020 16:36:14 -0700 Subject: cache-hash: add test_filter and test_name_prefix (#6583) --- src/Compilation.zig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index f33ada9362..3e74df35af 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2590,6 +2590,8 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node man.hash.add(comp.emit_llvm_ir != null); man.hash.add(comp.emit_analysis != null); man.hash.add(comp.emit_docs != null); + man.hash.addOptionalBytes(comp.test_filter); + man.hash.addOptionalBytes(comp.test_name_prefix); // Capture the state in case we come back from this branch where the hash doesn't match. const prev_hash_state = man.hash.peekBin(); -- cgit v1.2.3