diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-05-12 16:41:20 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-05-12 16:41:20 -0700 |
| commit | c9cc09a3bfb45d93b84577238047cd69ef0a7d88 (patch) | |
| tree | 1686cda92ae0c5d9ae55c02e7755c55d4e6f3c18 /src/link | |
| parent | 71afc3088009944fcd8339ac71e69a0b77a781ab (diff) | |
| parent | 40a47eae65b918866abc9d745f89d837f6a1e591 (diff) | |
| download | zig-c9cc09a3bfb45d93b84577238047cd69ef0a7d88.tar.gz zig-c9cc09a3bfb45d93b84577238047cd69ef0a7d88.zip | |
Merge remote-tracking branch 'origin/master' into stage2-whole-file-astgen
Conflicts:
* lib/std/os/linux.zig
* lib/std/os/windows/bits.zig
* src/Module.zig
* src/Sema.zig
* test/stage2/test.zig
Mainly I wanted Jakub's new macOS code for respecting stack size, since
we now depend on it for debug builds able to pass one of the test cases
for recursive comptime function calls with `@setEvalBranchQuota`.
The conflicts were all trivial.
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Elf.zig | 25 | ||||
| -rw-r--r-- | src/link/MachO.zig | 5 | ||||
| -rw-r--r-- | src/link/MachO/Zld.zig | 18 | ||||
| -rw-r--r-- | src/link/MachO/reloc.zig | 11 | ||||
| -rw-r--r-- | src/link/MachO/reloc/x86_64.zig | 33 |
5 files changed, 53 insertions, 39 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 3f87fd390b..7b1c5474a7 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1648,19 +1648,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { // libc dep if (self.base.options.link_libc) { if (self.base.options.libc_installation != null) { - if (self.base.options.link_mode == .Static) { - try argv.append("--start-group"); - try argv.append("-lc"); - try argv.append("-lm"); - try argv.append("--end-group"); - } else { - try argv.append("-lc"); - try argv.append("-lm"); - } - - if (target.os.tag == .freebsd or target.os.tag == .netbsd or target.os.tag == .openbsd) { - try argv.append("-lpthread"); - } + const needs_grouping = self.base.options.link_mode == .Static; + if (needs_grouping) try argv.append("--start-group"); + // This matches the order of glibc.libs + try argv.appendSlice(&[_][]const u8{ + "-lm", + "-lpthread", + "-lc", + "-ldl", + "-lrt", + "-lutil", + }); + if (needs_grouping) try argv.append("--end-group"); } else if (target.isGnuLibC()) { try argv.append(comp.libunwind_static_lib.?.full_object_path); for (glibc.libs) |lib| { diff --git a/src/link/MachO.zig b/src/link/MachO.zig index dbb84a909c..03793060d3 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -442,6 +442,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; const main_cmd = &self.load_commands.items[self.main_cmd_index.?].Main; main_cmd.entryoff = addr - text_segment.inner.vmaddr; + main_cmd.stacksize = self.base.options.stack_size_override orelse 0; self.load_commands_dirty = true; } try self.writeRebaseInfoTable(); @@ -695,7 +696,9 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { Compilation.dump_argv(argv.items); } - try zld.link(input_files.items, full_out_path); + try zld.link(input_files.items, full_out_path, .{ + .stack_size = self.base.options.stack_size_override, + }); break :outer; } diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 4d19da1e97..c619d0634b 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -29,6 +29,10 @@ page_size: ?u16 = null, file: ?fs.File = null, out_path: ?[]const u8 = null, +// TODO these args will become obselete once Zld is coalesced with incremental +// linker. +stack_size: u64 = 0, + objects: std.ArrayListUnmanaged(*Object) = .{}, archives: std.ArrayListUnmanaged(*Archive) = .{}, @@ -172,7 +176,11 @@ pub fn closeFiles(self: Zld) void { if (self.file) |f| f.close(); } -pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { +const LinkArgs = struct { + stack_size: ?u64 = null, +}; + +pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: LinkArgs) !void { if (files.len == 0) return error.NoInputFiles; if (out_path.len == 0) return error.EmptyOutputPath; @@ -206,6 +214,7 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { .read = true, .mode = if (std.Target.current.os.tag == .windows) 0 else 0o777, }); + self.stack_size = args.stack_size orelse 0; try self.populateMetadata(); try self.parseInputFiles(files); @@ -1533,7 +1542,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { } if (rel.target == .section) { const source_sect = object.sections.items[rel.target.section]; - args.source_sect_addr = source_sect.inner.addr; + args.source_source_sect_addr = sect.inner.addr; + args.source_target_sect_addr = source_sect.inner.addr; } rebases: { @@ -1588,7 +1598,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { else => |tt| { if (tt == .signed and rel.target == .section) { const source_sect = object.sections.items[rel.target.section]; - args.source_sect_addr = source_sect.inner.addr; + args.source_source_sect_addr = sect.inner.addr; + args.source_target_sect_addr = source_sect.inner.addr; } args.target_addr = try self.relocTargetAddr(@intCast(u16, object_id), rel.target); }, @@ -2202,6 +2213,7 @@ fn setEntryPoint(self: *Zld) !void { const entry_sym = sym.cast(Symbol.Regular) orelse unreachable; const ec = &self.load_commands.items[self.main_cmd_index.?].Main; ec.entryoff = @intCast(u32, entry_sym.address - seg.inner.vmaddr); + ec.stacksize = self.stack_size; } fn writeRebaseInfoTable(self: *Zld) !void { diff --git a/src/link/MachO/reloc.zig b/src/link/MachO/reloc.zig index 1ce9fa2c2d..89b7aa4228 100644 --- a/src/link/MachO/reloc.zig +++ b/src/link/MachO/reloc.zig @@ -29,7 +29,8 @@ pub const Relocation = struct { source_addr: u64, target_addr: u64, subtractor: ?u64 = null, - source_sect_addr: ?u64 = null, + source_source_sect_addr: ?u64 = null, + source_target_sect_addr: ?u64 = null, }; pub fn resolve(base: *Relocation, args: ResolveArgs) !void { @@ -39,8 +40,10 @@ pub const Relocation = struct { log.debug(" | target address 0x{x}", .{args.target_addr}); if (args.subtractor) |sub| log.debug(" | subtractor address 0x{x}", .{sub}); - if (args.source_sect_addr) |addr| - log.debug(" | source section address 0x{x}", .{addr}); + if (args.source_source_sect_addr) |addr| + log.debug(" | source source section address 0x{x}", .{addr}); + if (args.source_target_sect_addr) |addr| + log.debug(" | source target section address 0x{x}", .{addr}); return switch (base.@"type") { .unsigned => @fieldParentPtr(Unsigned, "base", base).resolve(args), @@ -104,7 +107,7 @@ pub const Unsigned = struct { pub fn resolve(unsigned: Unsigned, args: Relocation.ResolveArgs) !void { const addend = if (unsigned.base.target == .section) - unsigned.addend - @intCast(i64, args.source_sect_addr.?) + unsigned.addend - @intCast(i64, args.source_target_sect_addr.?) else unsigned.addend; diff --git a/src/link/MachO/reloc/x86_64.zig b/src/link/MachO/reloc/x86_64.zig index 32f83924e8..a5e3ff2825 100644 --- a/src/link/MachO/reloc/x86_64.zig +++ b/src/link/MachO/reloc/x86_64.zig @@ -33,16 +33,19 @@ pub const Signed = struct { pub fn resolve(signed: Signed, args: Relocation.ResolveArgs) !void { const target_addr = target_addr: { if (signed.base.target == .section) { - const source_target = @intCast(i64, signed.base.offset) + signed.addend + 4 + signed.correction; - const source_disp = source_target - @intCast(i64, args.source_sect_addr.?); + const source_target = @intCast(i64, args.source_source_sect_addr.?) + @intCast(i64, signed.base.offset) + signed.addend + 4; + const source_disp = source_target - @intCast(i64, args.source_target_sect_addr.?); break :target_addr @intCast(i64, args.target_addr) + source_disp; } break :target_addr @intCast(i64, args.target_addr) + signed.addend; }; - const displacement = try math.cast(i32, target_addr - @intCast(i64, args.source_addr) - signed.correction - 4); + const displacement = try math.cast( + i32, + target_addr - @intCast(i64, args.source_addr) - signed.correction - 4, + ); - log.debug(" | calculated addend 0x{x}", .{signed.addend}); - log.debug(" | calculated correction 0x{x}", .{signed.correction}); + log.debug(" | addend 0x{x}", .{signed.addend}); + log.debug(" | correction 0x{x}", .{signed.correction}); log.debug(" | displacement 0x{x}", .{displacement}); mem.writeIntLittle(u32, signed.base.code[0..4], @bitCast(u32, displacement)); @@ -172,20 +175,14 @@ pub const Parser = struct { const offset = @intCast(u32, rel.r_address); const inst = parser.code[offset..][0..4]; - const addend = mem.readIntLittle(i32, inst); - - const correction: i4 = correction: { - if (is_extern) break :correction 0; - - const corr: i4 = switch (rel_type) { - .X86_64_RELOC_SIGNED => 0, - .X86_64_RELOC_SIGNED_1 => 1, - .X86_64_RELOC_SIGNED_2 => 2, - .X86_64_RELOC_SIGNED_4 => 4, - else => unreachable, - }; - break :correction corr; + const correction: i4 = switch (rel_type) { + .X86_64_RELOC_SIGNED => 0, + .X86_64_RELOC_SIGNED_1 => 1, + .X86_64_RELOC_SIGNED_2 => 2, + .X86_64_RELOC_SIGNED_4 => 4, + else => unreachable, }; + const addend = mem.readIntLittle(i32, inst) + correction; var signed = try parser.allocator.create(Signed); errdefer parser.allocator.destroy(signed); |
