aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-05-12 16:41:20 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-05-12 16:41:20 -0700
commitc9cc09a3bfb45d93b84577238047cd69ef0a7d88 (patch)
tree1686cda92ae0c5d9ae55c02e7755c55d4e6f3c18 /src/link
parent71afc3088009944fcd8339ac71e69a0b77a781ab (diff)
parent40a47eae65b918866abc9d745f89d837f6a1e591 (diff)
downloadzig-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.zig25
-rw-r--r--src/link/MachO.zig5
-rw-r--r--src/link/MachO/Zld.zig18
-rw-r--r--src/link/MachO/reloc.zig11
-rw-r--r--src/link/MachO/reloc/x86_64.zig33
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);