authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-08 04:12:52+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-08 04:12:52+02:00
log41f8858304bb58b9f5c0a444d9705aed20aa66ed
tree9382e594bae922e9accd28ae9e606ae1e85ca620
parent54a25d82566393adad3befbe80a5113cb1f980c9
parent399eaa3d410da35de6f5d1869932a7c0e8ca46b2

Merge pull request 'compiler: lift some PIC restrictions and change the default' (#36532) from alexrp/zig:pic-stuff into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36532

4 files changed, 21 insertions(+), 18 deletions(-)

src/Module.zig+8-6
......@@ -174,7 +174,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module {
174174 };
175175
176176 const pic = b: {
177 if (target_util.requiresPic(target, options.global.link_libc)) {
177 if (target_util.requiresPic(target)) {
178178 if (options.inherited.pic == false)
179179 return error.TargetRequiresPic;
180180 break :b true;
......@@ -184,7 +184,10 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module {
184184 return error.PieRequiresPic;
185185 break :b true;
186186 }
187 if (options.global.link_mode == .dynamic and target_util.requiresPicForDynamicLink(target)) {
187 if (options.global.output_mode == .Lib and
188 options.global.link_mode == .dynamic and
189 target_util.requiresPicForDynamicLink(target))
190 {
188191 if (options.inherited.pic == false)
189192 return error.DynamicLinkingRequiresPic;
190193 break :b true;
......@@ -192,10 +195,9 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Module {
192195 if (options.inherited.pic) |x| break :b x;
193196 if (options.parent) |p| break :b p.pic;
194197
195 // Default to PIC on targets where we default to producing PIEs to make
196 // the common case of linking objects and static libraries into an
197 // executable work out of the box.
198 break :b target_util.defaultPie(target);
198 // Default to PIC for objects and static libraries to make the common
199 // cases of linking those into a PIE or a shared library just work.
200 break :b options.global.output_mode != .Exe;
199201 };
200202
201203 const red_zone = b: {
src/libs/glibc.zig+6-2
......@@ -243,7 +243,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
243243 };
244244 var files = [_]Compilation.CSourceFile{ start_o, abi_note_o, init_o };
245245 const basename = if (comp.config.output_mode == .Exe and !comp.config.pie) "crt1" else "Scrt1";
246 return comp.build_crt_file(basename, .Obj, .@"glibc Scrt1.o", prog_node, &files, .{});
246 return comp.build_crt_file(basename, .Obj, .@"glibc Scrt1.o", prog_node, &files, .{
247 .pic = true,
248 });
247249 },
248250 .libc_nonshared_a => {
249251 const s = path.sep_str;
......@@ -356,7 +358,9 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
356358 files_index += 1;
357359 }
358360 const files = files_buf[0..files_index];
359 return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files, .{});
361 return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files, .{
362 .pic = true,
363 });
360364 },
361365 }
362366}
src/link/Elf2.zig+5-6
......@@ -9070,11 +9070,10 @@ fn addRelocAssumeCapacity(
90709070 .PLT32 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"32", .cast = .unsigned, .shift = .@"0" })),
90719071 .PLT64 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"64", .cast = .unsigned, .shift = .@"0" })),
90729072
9073 .WDISP30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })),
9074 .WPLT30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })),
9075 .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })),
9076 .H44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"22" })),
9077 .M44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"12" })),
9073 .WDISP30, .WPLT30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })),
9074 .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })),
9075 .H44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"22" })),
9076 .M44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"12" })),
90789077
90799078 .TLS_LDO_HIX22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.dtpoff, .{ .dest = .@"32[21:0]", .cast = .trunc, .shift = .@"10" })),
90809079 .TLS_LE_HIX22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .special(.sparc_le_hix22)),
......@@ -11944,7 +11943,7 @@ fn ensurePltEntry(elf: *Elf, gsi: Symbol.Global.Index) Error!bool {
1194411943 // sethi (. - .plt[0]), %g1
1194511944 .{ .imm22 = .{ .imm = @truncate(got_plt_offset), .op = 0b0000001100 } },
1194611945 // ba,a %xcc, .plt[1]
11947 .{ .disp19 = .{ .disp = @truncate((got_plt_offset + 4 - 32) >> 2), .op = 0b0011000001101 } },
11946 .{ .disp19 = .{ .disp = @truncate((32 -% (got_plt_offset + 4)) >> 2), .op = 0b0011000001101 } },
1194811947 // nop
1194911948 .{ .raw = 0x0100_0000 },
1195011949 // nop
src/target.zig+2-4
......@@ -72,10 +72,8 @@ pub fn requiresPie(target: *const std.Target, link_mode: std.lang.LinkMode) bool
7272}
7373
7474/// This function returns whether non-pic code is completely invalid on the given target.
75pub fn requiresPic(target: *const std.Target, linking_libc: bool) bool {
76 return ((target.os.tag == .windows or target.os.tag == .uefi) and (target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64)) or
77 target.requiresLibC() or
78 (linking_libc and target.isGnuLibC());
75pub fn requiresPic(target: *const std.Target) bool {
76 return (target.os.tag == .windows or target.os.tag == .uefi) and (target.cpu.arch == .aarch64 or target.cpu.arch == .x86_64);
7977}
8078
8179pub fn requiresPicForDynamicLink(target: *const std.Target) bool {