From 3940a1be18a8312dec9d521c6e30ec4d34c44bd6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 30 Aug 2021 19:22:04 -0700 Subject: rename std.zig.ast to std.zig.Ast; use top-level fields --- src/Compilation.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 7dc726aeb2..7ac75130f2 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -2408,7 +2408,7 @@ const AstGenSrc = union(enum) { root, import: struct { importing_file: *Module.Scope.File, - import_tok: std.zig.ast.TokenIndex, + import_tok: std.zig.Ast.TokenIndex, }, }; -- cgit v1.2.3 From eb5e4ac495356dd0dae680ca316e18b848c9efa3 Mon Sep 17 00:00:00 2001 From: Alex Rønne Petersen Date: Thu, 24 Jun 2021 10:44:16 +0200 Subject: link: Recognize -z origin|noexecstack|now|relro linker args. --- src/Compilation.zig | 8 ++++++++ src/link.zig | 4 ++++ src/link/Elf.zig | 20 ++++++++++++++++++++ src/main.zig | 16 ++++++++++++++++ 4 files changed, 48 insertions(+) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 7ac75130f2..26c8bf2a70 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -708,6 +708,10 @@ pub const InitOptions = struct { disable_c_depfile: bool = false, linker_z_nodelete: bool = false, linker_z_defs: bool = false, + linker_z_origin: bool = false, + linker_z_noexecstack: bool = false, + linker_z_now: bool = false, + linker_z_relro: bool = false, linker_tsaware: bool = false, linker_nxcompat: bool = false, linker_dynamicbase: bool = false, @@ -1382,6 +1386,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, .z_nodelete = options.linker_z_nodelete, .z_defs = options.linker_z_defs, + .z_origin = options.linker_z_origin, + .z_noexecstack = options.linker_z_noexecstack, + .z_now = options.linker_z_now, + .z_relro = options.linker_z_relro, .tsaware = options.linker_tsaware, .nxcompat = options.linker_nxcompat, .dynamicbase = options.linker_dynamicbase, diff --git a/src/link.zig b/src/link.zig index dbca4fc956..88159496f4 100644 --- a/src/link.zig +++ b/src/link.zig @@ -73,6 +73,10 @@ pub const Options = struct { rdynamic: bool, z_nodelete: bool, z_defs: bool, + z_origin: bool, + z_noexecstack: bool, + z_now: bool, + z_relro: bool, tsaware: bool, nxcompat: bool, dynamicbase: bool, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 938fede8ab..f8cf70104f 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1345,6 +1345,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { man.hash.add(self.base.options.skip_linker_dependencies); man.hash.add(self.base.options.z_nodelete); man.hash.add(self.base.options.z_defs); + man.hash.add(self.base.options.z_origin); + man.hash.add(self.base.options.z_noexecstack); + man.hash.add(self.base.options.z_now); + man.hash.add(self.base.options.z_relro); if (self.base.options.link_libc) { man.hash.add(self.base.options.libc_installation != null); if (self.base.options.libc_installation) |libc_installation| { @@ -1482,6 +1486,22 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { try argv.append("-z"); try argv.append("defs"); } + if (self.base.options.z_origin) { + try argv.append("-z"); + try argv.append("origin"); + } + if (self.base.options.z_noexecstack) { + try argv.append("-z"); + try argv.append("noexecstack"); + } + if (self.base.options.z_now) { + try argv.append("-z"); + try argv.append("now"); + } + if (self.base.options.z_relro) { + try argv.append("-z"); + try argv.append("relro"); + } if (getLDMOption(target)) |ldm| { // Any target ELF will use the freebsd osabi if suffixed with "_fbsd". diff --git a/src/main.zig b/src/main.zig index d58c3525c5..8b5fbba90d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -589,6 +589,10 @@ fn buildOutputType( var linker_bind_global_refs_locally: ?bool = null; var linker_z_nodelete = false; var linker_z_defs = false; + var linker_z_origin = false; + var linker_z_noexecstack = false; + var linker_z_now = false; + var linker_z_relro = false; var linker_tsaware = false; var linker_nxcompat = false; var linker_dynamicbase = false; @@ -1393,6 +1397,14 @@ fn buildOutputType( linker_z_nodelete = true; } else if (mem.eql(u8, z_arg, "defs")) { linker_z_defs = true; + } else if (mem.eql(u8, z_arg, "origin")) { + linker_z_origin = true; + } else if (mem.eql(u8, z_arg, "noexecstack")) { + linker_z_noexecstack = true; + } else if (mem.eql(u8, z_arg, "now")) { + linker_z_now = true; + } else if (mem.eql(u8, z_arg, "relro")) { + linker_z_relro = true; } else { warn("unsupported linker arg: -z {s}", .{z_arg}); } @@ -2077,6 +2089,10 @@ fn buildOutputType( .linker_bind_global_refs_locally = linker_bind_global_refs_locally, .linker_z_nodelete = linker_z_nodelete, .linker_z_defs = linker_z_defs, + .linker_z_origin = linker_z_origin, + .linker_z_noexecstack = linker_z_noexecstack, + .linker_z_now = linker_z_now, + .linker_z_relro = linker_z_relro, .linker_tsaware = linker_tsaware, .linker_nxcompat = linker_nxcompat, .linker_dynamicbase = linker_dynamicbase, -- cgit v1.2.3 From 5529febab056c870f7b2a123b0645b5e3b1146c9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 13 Sep 2021 20:08:44 -0700 Subject: stage2: implement Value.copy for structs and unions The stage2_os hack inside `@import("builtin")` is no longer needed. --- lib/std/start.zig | 2 +- src/Compilation.zig | 3 -- src/Sema.zig | 6 +-- src/value.zig | 105 +++++++++++++++++++++++++++++++++------------------- 4 files changed, 70 insertions(+), 46 deletions(-) (limited to 'src/Compilation.zig') diff --git a/lib/std/start.zig b/lib/std/start.zig index ac592e26ed..d8e5796d37 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -92,7 +92,7 @@ fn _start2() callconv(.Naked) noreturn { } fn exit2(code: usize) noreturn { - switch (builtin.stage2_os) { + switch (native_os) { .linux => switch (builtin.stage2_arch) { .x86_64 => { asm volatile ("syscall" diff --git a/src/Compilation.zig b/src/Compilation.zig index 26c8bf2a70..b13aabe272 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3671,8 +3671,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc \\pub const zig_is_stage2 = {}; \\/// Temporary until self-hosted supports the `cpu.arch` value. \\pub const stage2_arch: std.Target.Cpu.Arch = .{}; - \\/// Temporary until self-hosted supports the `os.tag` value. - \\pub const stage2_os: std.Target.Os.Tag = .{}; \\ \\pub const output_mode = std.builtin.OutputMode.{}; \\pub const link_mode = std.builtin.LinkMode.{}; @@ -3688,7 +3686,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc build_options.version, !use_stage1, std.zig.fmtId(@tagName(target.cpu.arch)), - std.zig.fmtId(@tagName(target.os.tag)), std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)), std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)), comp.bin_file.options.is_test, diff --git a/src/Sema.zig b/src/Sema.zig index 46c1f1122e..136a687774 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6313,7 +6313,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr sema.arena, @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn), ), - .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr), + .val = try Value.Tag.@"struct".create(sema.arena, field_values), }), ); }, @@ -6335,7 +6335,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr sema.arena, @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Int), ), - .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr), + .val = try Value.Tag.@"struct".create(sema.arena, field_values), }), ); }, @@ -6943,7 +6943,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: for (field_inits) |field_init, i| { values[i] = (sema.resolveMaybeUndefVal(block, src, field_init) catch unreachable).?; } - return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr)); + return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values)); } return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); diff --git a/src/value.zig b/src/value.zig index 8aaf70c428..885ce28856 100644 --- a/src/value.zig +++ b/src/value.zig @@ -344,7 +344,9 @@ pub const Value = extern union { return null; } - pub fn copy(self: Value, allocator: *Allocator) error{OutOfMemory}!Value { + /// It's intentional that this function is not passed a corresponding Type, so that + /// a Value can be copied from a Sema to a Decl prior to resolving struct/union field types. + pub fn copy(self: Value, arena: *Allocator) error{OutOfMemory}!Value { if (self.tag_if_small_enough < Tag.no_payload_count) { return Value{ .tag_if_small_enough = self.tag_if_small_enough }; } else switch (self.ptr_otherwise.tag) { @@ -421,37 +423,37 @@ pub const Value = extern union { .ty => { const payload = self.castTag(.ty).?; - const new_payload = try allocator.create(Payload.Ty); + const new_payload = try arena.create(Payload.Ty); new_payload.* = .{ .base = payload.base, - .data = try payload.data.copy(allocator), + .data = try payload.data.copy(arena), }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .int_type => return self.copyPayloadShallow(allocator, Payload.IntType), - .int_u64 => return self.copyPayloadShallow(allocator, Payload.U64), - .int_i64 => return self.copyPayloadShallow(allocator, Payload.I64), + .int_type => return self.copyPayloadShallow(arena, Payload.IntType), + .int_u64 => return self.copyPayloadShallow(arena, Payload.U64), + .int_i64 => return self.copyPayloadShallow(arena, Payload.I64), .int_big_positive, .int_big_negative => { const old_payload = self.cast(Payload.BigInt).?; - const new_payload = try allocator.create(Payload.BigInt); + const new_payload = try arena.create(Payload.BigInt); new_payload.* = .{ .base = .{ .tag = self.ptr_otherwise.tag }, - .data = try allocator.dupe(std.math.big.Limb, old_payload.data), + .data = try arena.dupe(std.math.big.Limb, old_payload.data), }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .function => return self.copyPayloadShallow(allocator, Payload.Function), - .extern_fn => return self.copyPayloadShallow(allocator, Payload.Decl), - .variable => return self.copyPayloadShallow(allocator, Payload.Variable), - .decl_ref => return self.copyPayloadShallow(allocator, Payload.Decl), - .decl_ref_mut => return self.copyPayloadShallow(allocator, Payload.DeclRefMut), + .function => return self.copyPayloadShallow(arena, Payload.Function), + .extern_fn => return self.copyPayloadShallow(arena, Payload.Decl), + .variable => return self.copyPayloadShallow(arena, Payload.Variable), + .decl_ref => return self.copyPayloadShallow(arena, Payload.Decl), + .decl_ref_mut => return self.copyPayloadShallow(arena, Payload.DeclRefMut), .elem_ptr => { const payload = self.castTag(.elem_ptr).?; - const new_payload = try allocator.create(Payload.ElemPtr); + const new_payload = try arena.create(Payload.ElemPtr); new_payload.* = .{ .base = payload.base, .data = .{ - .array_ptr = try payload.data.array_ptr.copy(allocator), + .array_ptr = try payload.data.array_ptr.copy(arena), .index = payload.data.index, }, }; @@ -459,17 +461,17 @@ pub const Value = extern union { }, .field_ptr => { const payload = self.castTag(.field_ptr).?; - const new_payload = try allocator.create(Payload.FieldPtr); + const new_payload = try arena.create(Payload.FieldPtr); new_payload.* = .{ .base = payload.base, .data = .{ - .container_ptr = try payload.data.container_ptr.copy(allocator), + .container_ptr = try payload.data.container_ptr.copy(arena), .field_index = payload.data.field_index, }, }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .bytes => return self.copyPayloadShallow(allocator, Payload.Bytes), + .bytes => return self.copyPayloadShallow(arena, Payload.Bytes), .repeated, .eu_payload, .eu_payload_ptr, @@ -477,61 +479,85 @@ pub const Value = extern union { .opt_payload_ptr, => { const payload = self.cast(Payload.SubValue).?; - const new_payload = try allocator.create(Payload.SubValue); + const new_payload = try arena.create(Payload.SubValue); new_payload.* = .{ .base = payload.base, - .data = try payload.data.copy(allocator), + .data = try payload.data.copy(arena), }; return Value{ .ptr_otherwise = &new_payload.base }; }, .array => { const payload = self.castTag(.array).?; - const new_payload = try allocator.create(Payload.Array); + const new_payload = try arena.create(Payload.Array); new_payload.* = .{ .base = payload.base, - .data = try allocator.alloc(Value, payload.data.len), + .data = try arena.alloc(Value, payload.data.len), }; std.mem.copy(Value, new_payload.data, payload.data); return Value{ .ptr_otherwise = &new_payload.base }; }, .slice => { const payload = self.castTag(.slice).?; - const new_payload = try allocator.create(Payload.Slice); + const new_payload = try arena.create(Payload.Slice); new_payload.* = .{ .base = payload.base, .data = .{ - .ptr = try payload.data.ptr.copy(allocator), - .len = try payload.data.len.copy(allocator), + .ptr = try payload.data.ptr.copy(arena), + .len = try payload.data.len.copy(arena), }, }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .float_16 => return self.copyPayloadShallow(allocator, Payload.Float_16), - .float_32 => return self.copyPayloadShallow(allocator, Payload.Float_32), - .float_64 => return self.copyPayloadShallow(allocator, Payload.Float_64), - .float_128 => return self.copyPayloadShallow(allocator, Payload.Float_128), + .float_16 => return self.copyPayloadShallow(arena, Payload.Float_16), + .float_32 => return self.copyPayloadShallow(arena, Payload.Float_32), + .float_64 => return self.copyPayloadShallow(arena, Payload.Float_64), + .float_128 => return self.copyPayloadShallow(arena, Payload.Float_128), .enum_literal => { const payload = self.castTag(.enum_literal).?; - const new_payload = try allocator.create(Payload.Bytes); + const new_payload = try arena.create(Payload.Bytes); new_payload.* = .{ .base = payload.base, - .data = try allocator.dupe(u8, payload.data), + .data = try arena.dupe(u8, payload.data), + }; + return Value{ .ptr_otherwise = &new_payload.base }; + }, + .enum_field_index => return self.copyPayloadShallow(arena, Payload.U32), + .@"error" => return self.copyPayloadShallow(arena, Payload.Error), + + .@"struct" => { + const old_field_values = self.castTag(.@"struct").?.data; + const new_payload = try arena.create(Payload.Struct); + new_payload.* = .{ + .base = .{ .tag = .@"struct" }, + .data = try arena.alloc(Value, old_field_values.len), + }; + for (old_field_values) |old_field_val, i| { + new_payload.data[i] = try old_field_val.copy(arena); + } + return Value{ .ptr_otherwise = &new_payload.base }; + }, + + .@"union" => { + const tag_and_val = self.castTag(.@"union").?.data; + const new_payload = try arena.create(Payload.Union); + new_payload.* = .{ + .base = .{ .tag = .@"union" }, + .data = .{ + .tag = try tag_and_val.tag.copy(arena), + .val = try tag_and_val.val.copy(arena), + }, }; return Value{ .ptr_otherwise = &new_payload.base }; }, - .enum_field_index => return self.copyPayloadShallow(allocator, Payload.U32), - .@"error" => return self.copyPayloadShallow(allocator, Payload.Error), - .@"struct" => @panic("TODO can't copy struct value without knowing the type"), - .@"union" => @panic("TODO can't copy union value without knowing the type"), .inferred_alloc => unreachable, .inferred_alloc_comptime => unreachable, } } - fn copyPayloadShallow(self: Value, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Value { + fn copyPayloadShallow(self: Value, arena: *Allocator, comptime T: type) error{OutOfMemory}!Value { const payload = self.cast(T).?; - const new_payload = try allocator.create(T); + const new_payload = try arena.create(T); new_payload.* = payload.*; return Value{ .ptr_otherwise = &new_payload.base }; } @@ -1932,8 +1958,9 @@ pub const Value = extern union { pub const base_tag = Tag.@"struct"; base: Payload = .{ .tag = base_tag }, - /// Field values. The number and type are according to the struct type. - data: [*]Value, + /// Field values. The types are according to the struct type. + /// The length is provided here so that copying a Value does not depend on the Type. + data: []Value, }; pub const Union = struct { -- cgit v1.2.3