authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-14 10:42:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-14 10:42:29-07:00
log04f6a26955bbb947983cbf3e0681d9092aaaa13f
tree000d28126a84a4e191305f03f9ce2319789fc0c7
parentc58e9951effddacfd5cef6c05019bc3f312747f8

fix stage1 regressions in this branch

also prepare for supporting linking into archives

9 files changed, 64 insertions(+), 28 deletions(-)

src-self-hosted/Compilation.zig+8-1
...@@ -305,6 +305,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -305,6 +305,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
305 options.system_libs.len != 0 or305 options.system_libs.len != 0 or
306 options.link_libc or options.link_libcpp or306 options.link_libc or options.link_libcpp or
307 options.link_eh_frame_hdr or307 options.link_eh_frame_hdr or
308 options.output_mode == .Lib or
309 options.lld_argv.len != 0 or
308 options.linker_script != null or options.version_script != null)310 options.linker_script != null or options.version_script != null)
309 {311 {
310 break :blk true;312 break :blk true;
...@@ -320,12 +322,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -320,12 +322,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
320 break :blk false;322 break :blk false;
321 };323 };
322324
325 const is_exe_or_dyn_lib = switch (options.output_mode) {
326 .Obj => false,
327 .Lib => (options.link_mode orelse .Static) == .Dynamic,
328 .Exe => true,
329 };
323 const must_dynamic_link = dl: {330 const must_dynamic_link = dl: {
324 if (target_util.cannotDynamicLink(options.target))331 if (target_util.cannotDynamicLink(options.target))
325 break :dl false;332 break :dl false;
326 if (target_util.osRequiresLibC(options.target))333 if (target_util.osRequiresLibC(options.target))
327 break :dl true;334 break :dl true;
328 if (options.link_libc and options.target.isGnuLibC())335 if (is_exe_or_dyn_lib and options.link_libc and options.target.isGnuLibC())
329 break :dl true;336 break :dl true;
330 if (options.system_libs.len != 0)337 if (options.system_libs.len != 0)
331 break :dl true;338 break :dl true;
src-self-hosted/link.zig+24-15
...@@ -279,16 +279,19 @@ pub const File = struct {...@@ -279,16 +279,19 @@ pub const File = struct {
279 }279 }
280280
281 pub fn flush(base: *File, comp: *Compilation) !void {281 pub fn flush(base: *File, comp: *Compilation) !void {
282 const tracy = trace(@src());282 const use_lld = build_options.have_llvm and base.options.use_lld;
283 defer tracy.end();283 if (base.options.output_mode == .Lib and base.options.link_mode == .Static and
284284 !base.options.target.isWasm())
285 try switch (base.tag) {285 {
286 .coff => @fieldParentPtr(Coff, "base", base).flush(comp),286 return base.linkAsArchive(comp);
287 .elf => @fieldParentPtr(Elf, "base", base).flush(comp),287 }
288 .macho => @fieldParentPtr(MachO, "base", base).flush(comp),288 switch (base.tag) {
289 .c => @fieldParentPtr(C, "base", base).flush(comp),289 .coff => return @fieldParentPtr(Coff, "base", base).flush(comp),
290 .wasm => @fieldParentPtr(Wasm, "base", base).flush(comp),290 .elf => return @fieldParentPtr(Elf, "base", base).flush(comp),
291 };291 .macho => return @fieldParentPtr(MachO, "base", base).flush(comp),
292 .c => return @fieldParentPtr(C, "base", base).flush(comp),
293 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp),
294 }
292 }295 }
293296
294 pub fn freeDecl(base: *File, decl: *Module.Decl) void {297 pub fn freeDecl(base: *File, decl: *Module.Decl) void {
...@@ -302,13 +305,13 @@ pub const File = struct {...@@ -302,13 +305,13 @@ pub const File = struct {
302 }305 }
303306
304 pub fn errorFlags(base: *File) ErrorFlags {307 pub fn errorFlags(base: *File) ErrorFlags {
305 return switch (base.tag) {308 switch (base.tag) {
306 .coff => @fieldParentPtr(Coff, "base", base).error_flags,309 .coff => return @fieldParentPtr(Coff, "base", base).error_flags,
307 .elf => @fieldParentPtr(Elf, "base", base).error_flags,310 .elf => return @fieldParentPtr(Elf, "base", base).error_flags,
308 .macho => @fieldParentPtr(MachO, "base", base).error_flags,311 .macho => return @fieldParentPtr(MachO, "base", base).error_flags,
309 .c => return .{ .no_entry_point_found = false },312 .c => return .{ .no_entry_point_found = false },
310 .wasm => return ErrorFlags{},313 .wasm => return ErrorFlags{},
311 };314 }
312 }315 }
313316
314 /// May be called before or after updateDecl, but must be called after317 /// May be called before or after updateDecl, but must be called after
...@@ -338,6 +341,12 @@ pub const File = struct {...@@ -338,6 +341,12 @@ pub const File = struct {
338 }341 }
339 }342 }
340343
344 fn linkAsArchive(base: *File, comp: *Compilation) !void {
345 // TODO follow pattern from ELF linkWithLLD
346 // ZigLLVMWriteArchive
347 return error.TODOMakeArchive;
348 }
349
341 pub const Tag = enum {350 pub const Tag = enum {
342 coff,351 coff,
343 elf,352 elf,
src-self-hosted/link/C.zig+4
...@@ -7,6 +7,7 @@ const Compilation = @import("../Compilation.zig");...@@ -7,6 +7,7 @@ const Compilation = @import("../Compilation.zig");
7const fs = std.fs;7const fs = std.fs;
8const codegen = @import("../codegen/c.zig");8const codegen = @import("../codegen/c.zig");
9const link = @import("../link.zig");9const link = @import("../link.zig");
10const trace = @import("../tracy.zig").trace;
10const File = link.File;11const File = link.File;
11const C = @This();12const C = @This();
1213
...@@ -73,6 +74,9 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {...@@ -73,6 +74,9 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
73}74}
7475
75pub fn flush(self: *C, comp: *Compilation) !void {76pub fn flush(self: *C, comp: *Compilation) !void {
77 const tracy = trace(@src());
78 defer tracy.end();
79
76 const writer = self.base.file.?.writer();80 const writer = self.base.file.?.writer();
77 try writer.writeAll(@embedFile("cbe.h"));81 try writer.writeAll(@embedFile("cbe.h"));
78 var includes = false;82 var includes = false;
src-self-hosted/link/Coff.zig+3
...@@ -724,6 +724,9 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl,...@@ -724,6 +724,9 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl,
724}724}
725725
726pub fn flush(self: *Coff, comp: *Compilation) !void {726pub fn flush(self: *Coff, comp: *Compilation) !void {
727 const tracy = trace(@src());
728 defer tracy.end();
729
727 if (self.text_section_size_dirty) {730 if (self.text_section_size_dirty) {
728 // Write the new raw size in the .text header731 // Write the new raw size in the .text header
729 var buf: [4]u8 = undefined;732 var buf: [4]u8 = undefined;
src-self-hosted/link/Elf.zig+8-9
...@@ -725,6 +725,9 @@ pub fn flush(self: *Elf, comp: *Compilation) !void {...@@ -725,6 +725,9 @@ pub fn flush(self: *Elf, comp: *Compilation) !void {
725725
726/// Commit pending changes and write headers.726/// Commit pending changes and write headers.
727fn flushInner(self: *Elf, comp: *Compilation) !void {727fn flushInner(self: *Elf, comp: *Compilation) !void {
728 const tracy = trace(@src());
729 defer tracy.end();
730
728 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the731 // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the
729 // Zig source code.732 // Zig source code.
730 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;733 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
...@@ -1206,6 +1209,9 @@ fn flushInner(self: *Elf, comp: *Compilation) !void {...@@ -1206,6 +1209,9 @@ fn flushInner(self: *Elf, comp: *Compilation) !void {
1206}1209}
12071210
1208fn linkWithLLD(self: *Elf, comp: *Compilation) !void {1211fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1212 const tracy = trace(@src());
1213 defer tracy.end();
1214
1209 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);1215 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
1210 defer arena_allocator.deinit();1216 defer arena_allocator.deinit();
1211 const arena = &arena_allocator.allocator;1217 const arena = &arena_allocator.allocator;
...@@ -1315,13 +1321,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1315,13 +1321,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1315 if (is_obj) {1321 if (is_obj) {
1316 try argv.append("-r");1322 try argv.append("-r");
1317 }1323 }
1318 if (self.base.options.output_mode == .Lib and
1319 self.base.options.link_mode == .Static and
1320 !target.isWasm())
1321 {
1322 // TODO port the code from link.cpp
1323 return error.TODOMakeArchive;
1324 }
1325 const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe;1324 const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe;
13261325
1327 try argv.append("-error-limit=0");1326 try argv.append("-error-limit=0");
...@@ -1581,8 +1580,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1581,8 +1580,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1581 new_argv[i] = try arena.dupeZ(u8, arg);1580 new_argv[i] = try arena.dupeZ(u8, arg);
1582 }1581 }
15831582
1584 const ZigLLDLink = @import("../llvm.zig").ZigLLDLink;1583 const llvm = @import("../llvm.zig");
1585 const ok = ZigLLDLink(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0);1584 const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0);
1586 if (!ok) return error.LLDReportedFailure;1585 if (!ok) return error.LLDReportedFailure;
15871586
1588 // Update the dangling symlink "id.txt" with the digest. If it fails we can continue; it only1587 // Update the dangling symlink "id.txt" with the digest. If it fails we can continue; it only
src-self-hosted/link/MachO.zig+3
...@@ -178,6 +178,9 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO {...@@ -178,6 +178,9 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO {
178}178}
179179
180pub fn flush(self: *MachO, comp: *Compilation) !void {180pub fn flush(self: *MachO, comp: *Compilation) !void {
181 const tracy = trace(@src());
182 defer tracy.end();
183
181 switch (self.base.options.output_mode) {184 switch (self.base.options.output_mode) {
182 .Exe => {185 .Exe => {
183 var last_cmd_offset: usize = @sizeOf(macho.mach_header_64);186 var last_cmd_offset: usize = @sizeOf(macho.mach_header_64);
src-self-hosted/link/Wasm.zig+4
...@@ -10,6 +10,7 @@ const Module = @import("../Module.zig");...@@ -10,6 +10,7 @@ const Module = @import("../Module.zig");
10const Compilation = @import("../Compilation.zig");10const Compilation = @import("../Compilation.zig");
11const codegen = @import("../codegen/wasm.zig");11const codegen = @import("../codegen/wasm.zig");
12const link = @import("../link.zig");12const link = @import("../link.zig");
13const trace = @import("../tracy.zig").trace;
1314
14/// Various magic numbers defined by the wasm spec15/// Various magic numbers defined by the wasm spec
15const spec = struct {16const spec = struct {
...@@ -134,6 +135,9 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {...@@ -134,6 +135,9 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {
134}135}
135136
136pub fn flush(self: *Wasm, comp: *Compilation) !void {137pub fn flush(self: *Wasm, comp: *Compilation) !void {
138 const tracy = trace(@src());
139 defer tracy.end();
140
137 const file = self.base.file.?;141 const file = self.base.file.?;
138 const header_size = 5 + 1;142 const header_size = 5 + 1;
139143
src-self-hosted/llvm.zig+9-2
...@@ -1,8 +1,9 @@...@@ -1,8 +1,9 @@
1//! We do this instead of @cImport because the self-hosted compiler is easier1//! We do this instead of @cImport because the self-hosted compiler is easier
2//! to bootstrap if it does not depend on translate-c.2//! to bootstrap if it does not depend on translate-c.
33
4pub const Link = ZigLLDLink;
4pub extern fn ZigLLDLink(5pub extern fn ZigLLDLink(
5 oformat: ZigLLVM_ObjectFormatType,6 oformat: ObjectFormatType,
6 args: [*:null]const ?[*:0]const u8,7 args: [*:null]const ?[*:0]const u8,
7 arg_count: usize,8 arg_count: usize,
8 append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void,9 append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void,
...@@ -10,7 +11,7 @@ pub extern fn ZigLLDLink(...@@ -10,7 +11,7 @@ pub extern fn ZigLLDLink(
10 context_stderr: usize,11 context_stderr: usize,
11) bool;12) bool;
1213
13pub const ZigLLVM_ObjectFormatType = extern enum(c_int) {14pub const ObjectFormatType = extern enum(c_int) {
14 Unknown,15 Unknown,
15 COFF,16 COFF,
16 ELF,17 ELF,
...@@ -18,3 +19,9 @@ pub const ZigLLVM_ObjectFormatType = extern enum(c_int) {...@@ -18,3 +19,9 @@ pub const ZigLLVM_ObjectFormatType = extern enum(c_int) {
18 Wasm,19 Wasm,
19 XCOFF,20 XCOFF,
20};21};
22
23pub const GetHostCPUName = LLVMGetHostCPUName;
24extern fn LLVMGetHostCPUName() ?[*:0]u8;
25
26pub const GetNativeFeatures = ZigLLVMGetNativeFeatures;
27extern fn ZigLLVMGetNativeFeatures() ?[*:0]u8;
src/codegen.cpp+1-1
...@@ -9013,7 +9013,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -9013,7 +9013,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
9013 if (g->zig_target->os_builtin_str != nullptr) {9013 if (g->zig_target->os_builtin_str != nullptr) {
9014 buf_append_str(contents, g->zig_target->os_builtin_str);9014 buf_append_str(contents, g->zig_target->os_builtin_str);
9015 } else {9015 } else {
9016 buf_appendf(contents, "Target.Os.defaultVersionRange(.%s);\n", cur_os);9016 buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
9017 }9017 }
9018 }9018 }
9019 buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);9019 buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);