authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-17 15:07:19+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-21 17:34:05+01:00
log333eec557f8ab89d74e9d66e55eea037ba0433cb
tree2a9b0b1506c63be44836144322f55a7cad32c663
parent4d54e9a4fbb899a18f1d7b9e83bbb65f0973a0cb

Initial support for static PIE executables


12 files changed, 296 insertions(+), 43 deletions(-)

lib/std/dynamic_library.zig+27-27
......@@ -24,7 +24,7 @@ pub const DynLib = switch (builtin.os) {
2424// fashion.
2525const LinkMap = extern struct {
2626 l_addr: usize,
27 l_name: [*]const u8,
27 l_name: [*:0]const u8,
2828 l_ld: ?*elf.Dyn,
2929 l_next: ?*LinkMap,
3030 l_prev: ?*LinkMap,
......@@ -53,48 +53,48 @@ const RDebug = extern struct {
5353 r_ldbase: usize,
5454};
5555
56fn elf_get_va_offset(phdrs: []elf.Phdr) !usize {
57 for (phdrs) |*phdr| {
58 if (phdr.p_type == elf.PT_LOAD) {
59 return @ptrToInt(phdr) - phdr.p_vaddr;
60 }
56// XXX: This should be weak (#1917)
57extern var _DYNAMIC: [128]elf.Dyn;
58
59comptime {
60 if (builtin.os == .linux) {
61 asm (
62 \\ .weak _DYNAMIC
63 \\ .hidden _DYNAMIC
64 );
6165 }
62 return error.InvalidExe;
6366}
6467
6568pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
66 const va_offset = try elf_get_va_offset(phdrs);
67
68 const dyn_table = init: {
69 for (phdrs) |*phdr| {
70 if (phdr.p_type == elf.PT_DYNAMIC) {
71 const ptr = @intToPtr([*]elf.Dyn, va_offset + phdr.p_vaddr);
72 break :init ptr[0 .. phdr.p_memsz / @sizeOf(elf.Dyn)];
73 }
74 }
69 if (@ptrToInt(&_DYNAMIC[0]) == 0) {
7570 // No PT_DYNAMIC means this is either a statically-linked program or a
7671 // badly corrupted one
7772 return LinkMap.Iterator{ .current = null };
78 };
73 }
7974
8075 const link_map_ptr = init: {
81 for (dyn_table) |*dyn| {
82 switch (dyn.d_tag) {
76 var i: usize = 0;
77 while (_DYNAMIC[i].d_tag != elf.DT_NULL) : (i += 1) {
78 switch (_DYNAMIC[i].d_tag) {
8379 elf.DT_DEBUG => {
84 const r_debug = @intToPtr(*RDebug, dyn.d_un.d_ptr);
85 if (r_debug.r_version != 1) return error.InvalidExe;
86 break :init r_debug.r_map;
80 const ptr = @intToPtr(?*RDebug, _DYNAMIC[i].d_un.d_ptr);
81 if (ptr) |r_debug| {
82 if (r_debug.r_version != 1) return error.InvalidExe;
83 break :init r_debug.r_map;
84 }
8785 },
8886 elf.DT_PLTGOT => {
89 const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr);
90 // The address to the link_map structure is stored in the
91 // second slot
92 break :init @intToPtr(?*LinkMap, got_table[1]);
87 const ptr = @intToPtr(?[*]usize, _DYNAMIC[i].d_un.d_ptr);
88 if (ptr) |got_table| {
89 // The address to the link_map structure is stored in
90 // the second slot
91 break :init @intToPtr(?*LinkMap, got_table[1]);
92 }
9393 },
9494 else => {},
9595 }
9696 }
97 return error.InvalidExe;
97 return LinkMap.Iterator{ .current = null };
9898 };
9999
100100 return LinkMap.Iterator{ .current = link_map_ptr };
lib/std/elf.zig+38
......@@ -640,20 +640,48 @@ pub const Elf64_Syminfo = extern struct {
640640pub const Elf32_Rel = extern struct {
641641 r_offset: Elf32_Addr,
642642 r_info: Elf32_Word,
643
644 pub inline fn r_sym(self: @This()) u24 {
645 return @truncate(u24, self.r_info >> 8);
646 }
647 pub inline fn r_type(self: @This()) u8 {
648 return @truncate(u8, self.r_info & 0xff);
649 }
643650};
644651pub const Elf64_Rel = extern struct {
645652 r_offset: Elf64_Addr,
646653 r_info: Elf64_Xword,
654
655 pub inline fn r_sym(self: @This()) u32 {
656 return @truncate(u32, self.r_info >> 32);
657 }
658 pub inline fn r_type(self: @This()) u32 {
659 return @truncate(u32, self.r_info & 0xffffffff);
660 }
647661};
648662pub const Elf32_Rela = extern struct {
649663 r_offset: Elf32_Addr,
650664 r_info: Elf32_Word,
651665 r_addend: Elf32_Sword,
666
667 pub inline fn r_sym(self: @This()) u24 {
668 return @truncate(u24, self.r_info >> 8);
669 }
670 pub inline fn r_type(self: @This()) u8 {
671 return @truncate(u8, self.r_info & 0xff);
672 }
652673};
653674pub const Elf64_Rela = extern struct {
654675 r_offset: Elf64_Addr,
655676 r_info: Elf64_Xword,
656677 r_addend: Elf64_Sxword,
678
679 pub inline fn r_sym(self: @This()) u32 {
680 return @truncate(u32, self.r_info >> 32);
681 }
682 pub inline fn r_type(self: @This()) u32 {
683 return @truncate(u32, self.r_info & 0xffffffff);
684 }
657685};
658686pub const Elf32_Phdr = extern struct {
659687 p_type: Elf32_Word,
......@@ -853,6 +881,16 @@ pub const Dyn = switch (@sizeOf(usize)) {
853881 8 => Elf64_Dyn,
854882 else => @compileError("expected pointer size of 32 or 64"),
855883};
884pub const Rel = switch (@sizeOf(usize)) {
885 4 => Elf32_Rel,
886 8 => Elf64_Rel,
887 else => @compileError("expected pointer size of 32 or 64"),
888};
889pub const Rela = switch (@sizeOf(usize)) {
890 4 => Elf32_Rela,
891 8 => Elf64_Rela,
892 else => @compileError("expected pointer size of 32 or 64"),
893};
856894pub const Shdr = switch (@sizeOf(usize)) {
857895 4 => Elf32_Shdr,
858896 8 => Elf64_Shdr,
lib/std/os/bits/linux.zig+1-1
......@@ -996,7 +996,7 @@ pub const dirent64 = extern struct {
996996
997997pub const dl_phdr_info = extern struct {
998998 dlpi_addr: usize,
999 dlpi_name: ?[*]const u8,
999 dlpi_name: ?[*:0]const u8,
10001000 dlpi_phdr: [*]std.elf.Phdr,
10011001 dlpi_phnum: u16,
10021002};
lib/std/os/linux/start_pie.zig created+138
......@@ -0,0 +1,138 @@
1const std = @import("std");
2const elf = std.elf;
3const builtin = @import("builtin");
4const assert = std.debug.assert;
5
6const R_AMD64_RELATIVE = 8;
7const R_386_RELATIVE = 8;
8const R_ARM_RELATIVE = 23;
9const R_AARCH64_RELATIVE = 1027;
10const R_RISCV_RELATIVE = 3;
11
12const ARCH_RELATIVE_RELOC = switch (builtin.arch) {
13 .i386 => R_386_RELATIVE,
14 .x86_64 => R_AMD64_RELATIVE,
15 .arm => R_ARM_RELATIVE,
16 .aarch64 => R_AARCH64_RELATIVE,
17 .riscv64 => R_RISCV_RELATIVE,
18 else => @compileError("unsupported architecture"),
19};
20
21// Just a convoluted (but necessary) way to obtain the address of the _DYNAMIC[]
22// vector as PC-relative so that we can use it before any relocation is applied
23fn getDynamicSymbol() [*]elf.Dyn {
24 const addr = switch (builtin.arch) {
25 .i386 => asm volatile (
26 \\ .weak _DYNAMIC
27 \\ .hidden _DYNAMIC
28 \\ call 1f
29 \\ 1: pop %[ret]
30 \\ lea _DYNAMIC-1b(%[ret]), %[ret]
31 : [ret] "=r" (-> usize)
32 ),
33 .x86_64 => asm volatile (
34 \\ .weak _DYNAMIC
35 \\ .hidden _DYNAMIC
36 \\ lea _DYNAMIC(%%rip), %[ret]
37 : [ret] "=r" (-> usize)
38 ),
39 // Work around the limited offset range of `ldr`
40 .arm => asm volatile (
41 \\ .weak _DYNAMIC
42 \\ .hidden _DYNAMIC
43 \\ ldr %[ret], 1f
44 \\ add %[ret], pc
45 \\ b 2f
46 \\ 1: .word _DYNAMIC-1b
47 \\ 2:
48 : [ret] "=r" (-> usize)
49 ),
50 // A simple `adr` is not enough as it has a limited offset range
51 .aarch64 => asm volatile (
52 \\ .weak _DYNAMIC
53 \\ .hidden _DYNAMIC
54 \\ adrp %[ret], _DYNAMIC
55 \\ add %[ret], %[ret], #:lo12:_DYNAMIC
56 : [ret] "=r" (-> usize)
57 ),
58 .riscv64 => asm volatile (
59 \\ lla %[ret], _DYNAMIC
60 : [ret] "=r" (-> usize)
61 ),
62 else => @compileError("???"),
63 };
64 if (addr == 0) unreachable;
65 return @intToPtr([*]elf.Dyn, addr);
66}
67
68pub fn apply_relocations() void {
69 @setRuntimeSafety(false);
70
71 const dynv = getDynamicSymbol();
72 const auxv = std.os.linux.elf_aux_maybe.?;
73 var at_phent: usize = undefined;
74 var at_phnum: usize = undefined;
75 var at_phdr: usize = undefined;
76 var at_hwcap: usize = undefined;
77
78 {
79 var i: usize = 0;
80 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
81 switch (auxv[i].a_type) {
82 elf.AT_PHENT => at_phent = auxv[i].a_un.a_val,
83 elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
84 elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
85 else => continue,
86 }
87 }
88 }
89
90 // Sanity check
91 assert(at_phent == @sizeOf(elf.Phdr));
92
93 // Search the TLS section
94 const phdrs = (@intToPtr([*]elf.Phdr, at_phdr))[0..at_phnum];
95
96 const base_addr = blk: {
97 for (phdrs) |*phdr| {
98 if (phdr.p_type == elf.PT_DYNAMIC) {
99 break :blk @ptrToInt(&dynv[0]) - phdr.p_vaddr;
100 }
101 }
102 unreachable;
103 };
104
105 var rel_addr: usize = 0;
106 var rela_addr: usize = 0;
107 var rel_size: usize = 0;
108 var rela_size: usize = 0;
109
110 {
111 var i: usize = 0;
112 while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) {
113 switch (dynv[i].d_tag) {
114 elf.DT_REL => rel_addr = base_addr + dynv[i].d_un.d_ptr,
115 elf.DT_RELA => rela_addr = base_addr + dynv[i].d_un.d_ptr,
116 elf.DT_RELSZ => rel_size = dynv[i].d_un.d_val,
117 elf.DT_RELASZ => rela_size = dynv[i].d_un.d_val,
118 else => {},
119 }
120 }
121 }
122
123 // Perform the relocations
124 if (rel_addr != 0) {
125 const rel = @bytesToSlice(elf.Rel, @intToPtr([*]u8, rel_addr)[0..rel_size]);
126 for (rel) |r| {
127 if (r.r_type() != ARCH_RELATIVE_RELOC) continue;
128 @intToPtr(*usize, base_addr + r.r_offset).* += base_addr;
129 }
130 }
131 if (rela_addr != 0) {
132 const rela = @bytesToSlice(elf.Rela, @intToPtr([*]u8, rela_addr)[0..rela_size]);
133 for (rela) |r| {
134 if (r.r_type() != ARCH_RELATIVE_RELOC) continue;
135 @intToPtr(*usize, base_addr + r.r_offset).* += base_addr + @bitCast(usize, r.r_addend);
136 }
137 }
138}
lib/std/os/test.zig+2
......@@ -205,6 +205,8 @@ export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
205205test "dl_iterate_phdr" {
206206 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
207207 return error.SkipZigTest;
208 if (builtin.position_independent_executable)
209 return error.SkipZigTest;
208210
209211 var counter: usize = 0;
210212 expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
lib/std/start.zig+6
......@@ -155,6 +155,12 @@ fn posixCallMainAndExit() noreturn {
155155 // Find the beginning of the auxiliary vector
156156 const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
157157 std.os.linux.elf_aux_maybe = auxv;
158
159 // Do this as early as possible, the aux vector is needed
160 if (builtin.position_independent_executable) {
161 @import("os/linux/start_pie.zig").apply_relocations();
162 }
163
158164 // Initialize the TLS area
159165 const gnu_stack_phdr = std.os.linux.tls.initTLS() orelse @panic("ELF missing stack size");
160166
src/all_types.hpp+8
......@@ -1922,6 +1922,12 @@ enum WantPIC {
19221922 WantPICEnabled,
19231923};
19241924
1925enum WantPIE {
1926 WantPIEAuto,
1927 WantPIEDisabled,
1928 WantPIEEnabled,
1929};
1930
19251931enum WantStackCheck {
19261932 WantStackCheckAuto,
19271933 WantStackCheckDisabled,
......@@ -2101,6 +2107,7 @@ struct CodeGen {
21012107 Stage2ProgressNode *sub_progress_node;
21022108
21032109 WantPIC want_pic;
2110 WantPIE want_pie;
21042111 WantStackCheck want_stack_check;
21052112 WantCSanitize want_sanitize_c;
21062113 CacheHash cache_hash;
......@@ -2175,6 +2182,7 @@ struct CodeGen {
21752182 bool disable_gen_h;
21762183 bool bundle_compiler_rt;
21772184 bool have_pic;
2185 bool have_pie;
21782186 bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic
21792187 bool have_stack_probing;
21802188 bool have_sanitize_c;
src/codegen.cpp+45-10
......@@ -8233,18 +8233,39 @@ static bool detect_dynamic_link(CodeGen *g) {
82338233 return false;
82348234}
82358235
8236static bool detect_pic(CodeGen *g) {
8237 if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr))
8238 return true;
8236static void detect_pic_pie(CodeGen *g) {
8237 const bool requires_pic = target_requires_pic(g->zig_target, g->libc_link_lib != nullptr);
8238 const bool requires_pie = target_requires_pie(g->zig_target);
8239
8240 bool have_pic = false;
8241 bool have_pie = false;
8242
8243 switch (g->want_pie) {
8244 case WantPIEDisabled:
8245 have_pie = false;
8246 break;
8247 case WantPIEEnabled:
8248 have_pie = true;
8249 break;
8250 case WantPIEAuto:
8251 have_pie = requires_pie;
8252 break;
8253 }
8254
82398255 switch (g->want_pic) {
82408256 case WantPICDisabled:
8241 return false;
8257 have_pic = false;
8258 break;
82428259 case WantPICEnabled:
8243 return true;
8260 have_pic = true;
8261 break;
82448262 case WantPICAuto:
8245 return g->have_dynamic_link;
8263 have_pic = have_pie || g->have_dynamic_link || requires_pic;
8264 break;
82468265 }
8247 zig_unreachable();
8266
8267 g->have_pic = have_pic;
8268 g->have_pie = have_pie;
82488269}
82498270
82508271static bool detect_stack_probing(CodeGen *g) {
......@@ -8309,7 +8330,7 @@ static bool detect_err_ret_tracing(CodeGen *g) {
83098330
83108331Buf *codegen_generate_builtin_source(CodeGen *g) {
83118332 g->have_dynamic_link = detect_dynamic_link(g);
8312 g->have_pic = detect_pic(g);
8333 detect_pic_pie(g);
83138334 g->have_stack_probing = detect_stack_probing(g);
83148335 g->have_sanitize_c = detect_sanitize_c(g);
83158336 g->is_single_threaded = detect_single_threaded(g);
......@@ -8465,6 +8486,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
84658486 buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));
84668487 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
84678488 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
8489 buf_appendf(contents, "pub const position_independent_executable = %s;\n", bool_to_str(g->have_pie));
84688490 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
84698491
84708492 {
......@@ -8526,6 +8548,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
85268548 cache_bool(&cache_hash, g->libc_link_lib != nullptr);
85278549 cache_bool(&cache_hash, g->valgrind_support);
85288550 cache_int(&cache_hash, detect_subsystem(g));
8551 cache_bool(&cache_hash, g->have_pic);
8552 cache_bool(&cache_hash, g->have_pie);
85298553
85308554 Buf digest = BUF_INIT;
85318555 buf_resize(&digest, 0);
......@@ -8595,7 +8619,7 @@ static void init(CodeGen *g) {
85958619 return;
85968620
85978621 g->have_dynamic_link = detect_dynamic_link(g);
8598 g->have_pic = detect_pic(g);
8622 detect_pic_pie(g);
85998623 g->have_stack_probing = detect_stack_probing(g);
86008624 g->have_sanitize_c = detect_sanitize_c(g);
86018625 g->is_single_threaded = detect_single_threaded(g);
......@@ -8640,6 +8664,14 @@ static void init(CodeGen *g) {
86408664 reloc_mode = LLVMRelocStatic;
86418665 }
86428666
8667 if (g->have_pic) {
8668 ZigLLVMSetModulePICLevel(g->module);
8669 }
8670
8671 if (g->have_pie) {
8672 ZigLLVMSetModulePIELevel(g->module);
8673 }
8674
86438675 const char *target_specific_cpu_args;
86448676 const char *target_specific_features;
86458677 if (g->zig_target->is_native) {
......@@ -9327,6 +9359,7 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
93279359 cache_bool(cache_hash, g->strip_debug_symbols);
93289360 cache_int(cache_hash, g->build_mode);
93299361 cache_bool(cache_hash, g->have_pic);
9362 cache_bool(cache_hash, g->have_pie);
93309363 cache_bool(cache_hash, g->have_sanitize_c);
93319364 cache_bool(cache_hash, want_valgrind_support(g));
93329365 cache_bool(cache_hash, g->function_sections);
......@@ -10104,6 +10137,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1010410137 cache_bool(ch, g->bundle_compiler_rt);
1010510138 cache_bool(ch, want_valgrind_support(g));
1010610139 cache_bool(ch, g->have_pic);
10140 cache_bool(ch, g->have_pie);
1010710141 cache_bool(ch, g->have_dynamic_link);
1010810142 cache_bool(ch, g->have_stack_probing);
1010910143 cache_bool(ch, g->have_sanitize_c);
......@@ -10224,7 +10258,7 @@ void codegen_build_and_link(CodeGen *g) {
1022410258 }
1022510259
1022610260 g->have_dynamic_link = detect_dynamic_link(g);
10227 g->have_pic = detect_pic(g);
10261 detect_pic_pie(g);
1022810262 g->is_single_threaded = detect_single_threaded(g);
1022910263 g->have_err_ret_tracing = detect_err_ret_tracing(g);
1023010264 g->have_sanitize_c = detect_sanitize_c(g);
......@@ -10429,6 +10463,7 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
1042910463
1043010464 codegen_set_strip(child_gen, parent_gen->strip_debug_symbols);
1043110465 child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled;
10466 child_gen->want_pie = parent_gen->have_pie ? WantPIEEnabled : WantPIEDisabled;
1043210467 child_gen->valgrind_support = ValgrindSupportDisabled;
1043310468
1043410469 codegen_set_errmsg_color(child_gen, parent_gen->err_color);
src/link.cpp+14-5
......@@ -1469,6 +1469,14 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
14691469 c_file->args.append("-fno-stack-protector");
14701470 c_file->args.append("-DCRT");
14711471 return build_libc_object(parent, "crt1", c_file, progress_node);
1472 } else if (strcmp(file, "rcrt1.o") == 0) {
1473 CFile *c_file = allocate<CFile>(1);
1474 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "rcrt1.c");
1475 musl_add_cc_args(parent, c_file, false);
1476 c_file->args.append("-fno-stack-protector");
1477 c_file->args.append("-DCRT");
1478 c_file->args.append("-fPIC");
1479 return build_libc_object(parent, "rcrt1", c_file, progress_node);
14721480 } else if (strcmp(file, "Scrt1.o") == 0) {
14731481 CFile *c_file = allocate<CFile>(1);
14741482 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
......@@ -1661,6 +1669,11 @@ static void construct_linker_job_elf(LinkJob *lj) {
16611669 } else {
16621670 lj->args.append("-static");
16631671 }
1672
1673 if (g->out_type == OutTypeExe && g->have_pie) {
1674 lj->args.append("-pie");
1675 lj->args.append("--no-dynamic-linker");
1676 }
16641677 } else if (is_dyn_lib) {
16651678 lj->args.append("-shared");
16661679
......@@ -1668,10 +1681,6 @@ static void construct_linker_job_elf(LinkJob *lj) {
16681681 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
16691682 }
16701683
1671 if (target_requires_pie(g->zig_target) && g->out_type == OutTypeExe) {
1672 lj->args.append("-pie");
1673 }
1674
16751684 lj->args.append("-o");
16761685 lj->args.append(buf_ptr(&g->output_file_path));
16771686
......@@ -1686,7 +1695,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
16861695 crt1o = "crtbegin_static.o";
16871696 }
16881697 } else if (!g->have_dynamic_link) {
1689 crt1o = "crt1.o";
1698 crt1o = g->have_pie ? "rcrt1.o" : "crt1.o";
16901699 } else {
16911700 crt1o = "Scrt1.o";
16921701 }
src/main.cpp+7
......@@ -525,6 +525,7 @@ int main(int argc, char **argv) {
525525 Buf *main_pkg_path = nullptr;
526526 ValgrindSupport valgrind_support = ValgrindSupportAuto;
527527 WantPIC want_pic = WantPICAuto;
528 WantPIE want_pie = WantPIEAuto;
528529 WantStackCheck want_stack_check = WantStackCheckAuto;
529530 WantCSanitize want_sanitize_c = WantCSanitizeAuto;
530531 bool function_sections = false;
......@@ -721,6 +722,10 @@ int main(int argc, char **argv) {
721722 want_pic = WantPICEnabled;
722723 } else if (strcmp(arg, "-fno-PIC") == 0) {
723724 want_pic = WantPICDisabled;
725 } else if (strcmp(arg, "-fPIE") == 0) {
726 want_pie = WantPIEEnabled;
727 } else if (strcmp(arg, "-fno-PIE") == 0) {
728 want_pie = WantPIEDisabled;
724729 } else if (strcmp(arg, "-fstack-check") == 0) {
725730 want_stack_check = WantStackCheckEnabled;
726731 } else if (strcmp(arg, "-fno-stack-check") == 0) {
......@@ -1099,6 +1104,7 @@ int main(int argc, char **argv) {
10991104 g->subsystem = subsystem;
11001105 g->valgrind_support = valgrind_support;
11011106 g->want_pic = want_pic;
1107 g->want_pie = want_pie;
11021108 g->want_stack_check = want_stack_check;
11031109 g->want_sanitize_c = want_sanitize_c;
11041110 g->want_single_threaded = want_single_threaded;
......@@ -1199,6 +1205,7 @@ int main(int argc, char **argv) {
11991205 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
12001206 g->valgrind_support = valgrind_support;
12011207 g->want_pic = want_pic;
1208 g->want_pie = want_pie;
12021209 g->want_stack_check = want_stack_check;
12031210 g->want_sanitize_c = want_sanitize_c;
12041211 g->subsystem = subsystem;
src/zig_llvm.cpp+8
......@@ -877,6 +877,14 @@ void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
877877 unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
878878}
879879
880void ZigLLVMSetModulePICLevel(LLVMModuleRef module) {
881 unwrap(module)->setPICLevel(PICLevel::Level::BigPIC);
882}
883
884void ZigLLVMSetModulePIELevel(LLVMModuleRef module) {
885 unwrap(module)->setPIELevel(PIELevel::Level::Large);
886}
887
880888static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
881889 switch (Ordering) {
882890 case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
src/zig_llvm.h+2
......@@ -158,6 +158,8 @@ ZIG_EXTERN_C struct ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef modul
158158ZIG_EXTERN_C void ZigLLVMDisposeDIBuilder(struct ZigLLVMDIBuilder *dbuilder);
159159ZIG_EXTERN_C void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module);
160160ZIG_EXTERN_C void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module);
161ZIG_EXTERN_C void ZigLLVMSetModulePICLevel(LLVMModuleRef module);
162ZIG_EXTERN_C void ZigLLVMSetModulePIELevel(LLVMModuleRef module);
161163
162164ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column,
163165 struct ZigLLVMDIScope *scope);