| author | |
| committer | |
| log | abc717f203060f7ab16d36f2afe681d838b46801 |
| tree | bc15d848e784a0a19e24ec3d6645585550bd0432 |
| parent | 55ab50efbd5e475442ac9c3b841e461ee331ee2c |
This is the part of #3960 that has to be rewritten to apply to latest
master branch code.18 files changed, 272 insertions(+), 15 deletions(-)
lib/libc/musl/ldso/dlstart.c created+148| ... | ... | @@ -0,0 +1,148 @@ |
| 1 | #include <stddef.h> | |
| 2 | #include "dynlink.h" | |
| 3 | #include "libc.h" | |
| 4 | ||
| 5 | #ifndef START | |
| 6 | #define START "_dlstart" | |
| 7 | #endif | |
| 8 | ||
| 9 | #define SHARED | |
| 10 | ||
| 11 | #include "crt_arch.h" | |
| 12 | ||
| 13 | #ifndef GETFUNCSYM | |
| 14 | #define GETFUNCSYM(fp, sym, got) do { \ | |
| 15 | 	hidden void sym(); \ | |
| 16 | 	static void (*static_func_ptr)() = sym; \ | |
| 17 | 	__asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \ | |
| 18 | 	*(fp) = static_func_ptr; } while(0) | |
| 19 | #endif | |
| 20 | ||
| 21 | hidden void _dlstart_c(size_t *sp, size_t *dynv) | |
| 22 | { | |
| 23 | 	size_t i, aux[AUX_CNT], dyn[DYN_CNT]; | |
| 24 | 	size_t *rel, rel_size, base; | |
| 25 | ||
| 26 | 	int argc = *sp; | |
| 27 | 	char **argv = (void *)(sp+1); | |
| 28 | ||
| 29 | 	for (i=argc+1; argv[i]; i++); | |
| 30 | 	size_t *auxv = (void *)(argv+i+1); | |
| 31 | ||
| 32 | 	for (i=0; i<AUX_CNT; i++) aux[i] = 0; | |
| 33 | 	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) | |
| 34 | 		aux[auxv[i]] = auxv[i+1]; | |
| 35 | ||
| 36 | #if DL_FDPIC | |
| 37 | 	struct fdpic_loadseg *segs, fakeseg; | |
| 38 | 	size_t j; | |
| 39 | 	if (dynv) { | |
| 40 | 		/* crt_arch.h entry point asm is responsible for reserving | |
| 41 | 		 * space and moving the extra fdpic arguments to the stack | |
| 42 | 		 * vector where they are easily accessible from C. */ | |
| 43 | 		segs = ((struct fdpic_loadmap *)(sp[-1] ? sp[-1] : sp[-2]))->segs; | |
| 44 | 	} else { | |
| 45 | 		/* If dynv is null, the entry point was started from loader | |
| 46 | 		 * that is not fdpic-aware. We can assume normal fixed- | |
| 47 | 		 * displacement ELF loading was performed, but when ldso was | |
| 48 | 		 * run as a command, finding the Ehdr is a heursitic: we | |
| 49 | 		 * have to assume Phdrs start in the first 4k of the file. */ | |
| 50 | 		base = aux[AT_BASE]; | |
| 51 | 		if (!base) base = aux[AT_PHDR] & -4096; | |
| 52 | 		segs = &fakeseg; | |
| 53 | 		segs[0].addr = base; | |
| 54 | 		segs[0].p_vaddr = 0; | |
| 55 | 		segs[0].p_memsz = -1; | |
| 56 | 		Ehdr *eh = (void *)base; | |
| 57 | 		Phdr *ph = (void *)(base + eh->e_phoff); | |
| 58 | 		size_t phnum = eh->e_phnum; | |
| 59 | 		size_t phent = eh->e_phentsize; | |
| 60 | 		while (phnum-- && ph->p_type != PT_DYNAMIC) | |
| 61 | 			ph = (void *)((size_t)ph + phent); | |
| 62 | 		dynv = (void *)(base + ph->p_vaddr); | |
| 63 | 	} | |
| 64 | #endif | |
| 65 | ||
| 66 | 	for (i=0; i<DYN_CNT; i++) dyn[i] = 0; | |
| 67 | 	for (i=0; dynv[i]; i+=2) if (dynv[i]<DYN_CNT) | |
| 68 | 		dyn[dynv[i]] = dynv[i+1]; | |
| 69 | ||
| 70 | #if DL_FDPIC | |
| 71 | 	for (i=0; i<DYN_CNT; i++) { | |
| 72 | 		if (i==DT_RELASZ || i==DT_RELSZ) continue; | |
| 73 | 		if (!dyn[i]) continue; | |
| 74 | 		for (j=0; dyn[i]-segs[j].p_vaddr >= segs[j].p_memsz; j++); | |
| 75 | 		dyn[i] += segs[j].addr - segs[j].p_vaddr; | |
| 76 | 	} | |
| 77 | 	base = 0; | |
| 78 | ||
| 79 | 	const Sym *syms = (void *)dyn[DT_SYMTAB]; | |
| 80 | ||
| 81 | 	rel = (void *)dyn[DT_RELA]; | |
| 82 | 	rel_size = dyn[DT_RELASZ]; | |
| 83 | 	for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) { | |
| 84 | 		if (!IS_RELATIVE(rel[1], syms)) continue; | |
| 85 | 		for (j=0; rel[0]-segs[j].p_vaddr >= segs[j].p_memsz; j++); | |
| 86 | 		size_t *rel_addr = (void *) | |
| 87 | 			(rel[0] + segs[j].addr - segs[j].p_vaddr); | |
| 88 | 		if (R_TYPE(rel[1]) == REL_FUNCDESC_VAL) { | |
| 89 | 			*rel_addr += segs[rel_addr[1]].addr | |
| 90 | 				- segs[rel_addr[1]].p_vaddr | |
| 91 | 				+ syms[R_SYM(rel[1])].st_value; | |
| 92 | 			rel_addr[1] = dyn[DT_PLTGOT]; | |
| 93 | 		} else { | |
| 94 | 			size_t val = syms[R_SYM(rel[1])].st_value; | |
| 95 | 			for (j=0; val-segs[j].p_vaddr >= segs[j].p_memsz; j++); | |
| 96 | 			*rel_addr = rel[2] + segs[j].addr - segs[j].p_vaddr + val; | |
| 97 | 		} | |
| 98 | 	} | |
| 99 | #else | |
| 100 | 	/* If the dynamic linker is invoked as a command, its load | |
| 101 | 	 * address is not available in the aux vector. Instead, compute | |
| 102 | 	 * the load address as the difference between &_DYNAMIC and the | |
| 103 | 	 * virtual address in the PT_DYNAMIC program header. */ | |
| 104 | 	base = aux[AT_BASE]; | |
| 105 | 	if (!base) { | |
| 106 | 		size_t phnum = aux[AT_PHNUM]; | |
| 107 | 		size_t phentsize = aux[AT_PHENT]; | |
| 108 | 		Phdr *ph = (void *)aux[AT_PHDR]; | |
| 109 | 		for (i=phnum; i--; ph = (void *)((char *)ph + phentsize)) { | |
| 110 | 			if (ph->p_type == PT_DYNAMIC) { | |
| 111 | 				base = (size_t)dynv - ph->p_vaddr; | |
| 112 | 				break; | |
| 113 | 			} | |
| 114 | 		} | |
| 115 | 	} | |
| 116 | ||
| 117 | 	/* MIPS uses an ugly packed form for GOT relocations. Since we | |
| 118 | 	 * can't make function calls yet and the code is tiny anyway, | |
| 119 | 	 * it's simply inlined here. */ | |
| 120 | 	if (NEED_MIPS_GOT_RELOCS) { | |
| 121 | 		size_t local_cnt = 0; | |
| 122 | 		size_t *got = (void *)(base + dyn[DT_PLTGOT]); | |
| 123 | 		for (i=0; dynv[i]; i+=2) if (dynv[i]==DT_MIPS_LOCAL_GOTNO) | |
| 124 | 			local_cnt = dynv[i+1]; | |
| 125 | 		for (i=0; i<local_cnt; i++) got[i] += base; | |
| 126 | 	} | |
| 127 | ||
| 128 | 	rel = (void *)(base+dyn[DT_REL]); | |
| 129 | 	rel_size = dyn[DT_RELSZ]; | |
| 130 | 	for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) { | |
| 131 | 		if (!IS_RELATIVE(rel[1], 0)) continue; | |
| 132 | 		size_t *rel_addr = (void *)(base + rel[0]); | |
| 133 | 		*rel_addr += base; | |
| 134 | 	} | |
| 135 | ||
| 136 | 	rel = (void *)(base+dyn[DT_RELA]); | |
| 137 | 	rel_size = dyn[DT_RELASZ]; | |
| 138 | 	for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) { | |
| 139 | 		if (!IS_RELATIVE(rel[1], 0)) continue; | |
| 140 | 		size_t *rel_addr = (void *)(base + rel[0]); | |
| 141 | 		*rel_addr = base + rel[2]; | |
| 142 | 	} | |
| 143 | #endif | |
| 144 | ||
| 145 | 	stage2_func dls2; | |
| 146 | 	GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]); | |
| 147 | 	dls2((void *)base, sp); | |
| 148 | } |
lib/std/build.zig+11| ... | ... | @@ -1286,6 +1286,9 @@ pub const LibExeObjStep = struct { |
| 1286 | 1286 | /// Position Independent Code |
| 1287 | 1287 | force_pic: ?bool = null, |
| 1288 | 1288 | |
| 1289 | /// Position Independent Executable | |
| 1290 | pie: ?bool = null, | |
| 1291 | ||
| 1289 | 1292 | subsystem: ?builtin.SubSystem = null, |
| 1290 | 1293 | |
| 1291 | 1294 | const LinkObject = union(enum) { |
| ... | ... | @@ -2307,6 +2310,14 @@ pub const LibExeObjStep = struct { |
| 2307 | 2310 | } |
| 2308 | 2311 | } |
| 2309 | 2312 | |
| 2313 | if (self.pie) |pie| { | |
| 2314 | if (pie) { | |
| 2315 | try zig_args.append("-fPIE"); | |
| 2316 | } else { | |
| 2317 | try zig_args.append("-fno-PIE"); | |
| 2318 | } | |
| 2319 | } | |
| 2320 | ||
| 2310 | 2321 | if (self.subsystem) |subsystem| { |
| 2311 | 2322 | try zig_args.append("--subsystem"); |
| 2312 | 2323 | try zig_args.append(switch (subsystem) { |
lib/std/dynamic_library.zig+1-1| ... | ... | @@ -63,7 +63,7 @@ const RDebug = extern struct { |
| 63 | 63 | extern var _DYNAMIC: [128]elf.Dyn; |
| 64 | 64 | |
| 65 | 65 | comptime { |
| 66 | if (builtin.os == .linux) { | |
| 66 | if (std.Target.current.os.tag == .linux) { | |
| 67 | 67 | asm ( |
| 68 | 68 | \\ .weak _DYNAMIC |
| 69 | 69 | \\ .hidden _DYNAMIC |
lib/std/os/linux/start_pie.zig+6-6| ... | ... | @@ -111,10 +111,10 @@ pub fn apply_relocations() void { |
| 111 | 111 | var i: usize = 0; |
| 112 | 112 | while (dynv[i].d_tag != elf.DT_NULL) : (i += 1) { |
| 113 | 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, | |
| 114 | elf.DT_REL => rel_addr = base_addr + dynv[i].d_val, | |
| 115 | elf.DT_RELA => rela_addr = base_addr + dynv[i].d_val, | |
| 116 | elf.DT_RELSZ => rel_size = dynv[i].d_val, | |
| 117 | elf.DT_RELASZ => rela_size = dynv[i].d_val, | |
| 118 | 118 | else => {}, |
| 119 | 119 | } |
| 120 | 120 | } |
| ... | ... | @@ -122,14 +122,14 @@ pub fn apply_relocations() void { |
| 122 | 122 | |
| 123 | 123 | // Perform the relocations |
| 124 | 124 | if (rel_addr != 0) { |
| 125 | const rel = @bytesToSlice(elf.Rel, @intToPtr([*]u8, rel_addr)[0..rel_size]); | |
| 125 | const rel = std.mem.bytesAsSlice(elf.Rel, @intToPtr([*]u8, rel_addr)[0..rel_size]); | |
| 126 | 126 | for (rel) |r| { |
| 127 | 127 | if (r.r_type() != ARCH_RELATIVE_RELOC) continue; |
| 128 | 128 | @intToPtr(*usize, base_addr + r.r_offset).* += base_addr; |
| 129 | 129 | } |
| 130 | 130 | } |
| 131 | 131 | if (rela_addr != 0) { |
| 132 | const rela = @bytesToSlice(elf.Rela, @intToPtr([*]u8, rela_addr)[0..rela_size]); | |
| 132 | const rela = std.mem.bytesAsSlice(elf.Rela, @intToPtr([*]u8, rela_addr)[0..rela_size]); | |
| 133 | 133 | for (rela) |r| { |
| 134 | 134 | if (r.r_type() != ARCH_RELATIVE_RELOC) continue; |
| 135 | 135 | @intToPtr(*usize, base_addr + r.r_offset).* += base_addr + @bitCast(usize, r.r_addend); |
src/Compilation.zig+29-4| ... | ... | @@ -343,6 +343,10 @@ pub const InitOptions = struct { |
| 343 | 343 | link_libc: bool = false, |
| 344 | 344 | link_libcpp: bool = false, |
| 345 | 345 | want_pic: ?bool = null, |
| 346 | /// This means that if the output mode is an executable it will be a | |
| 347 | /// Position Independent Executable. If the output mode is not an | |
| 348 | /// executable this field is ignored. | |
| 349 | want_pie: ?bool = null, | |
| 346 | 350 | want_sanitize_c: ?bool = null, |
| 347 | 351 | want_stack_check: ?bool = null, |
| 348 | 352 | want_valgrind: ?bool = null, |
| ... | ... | @@ -527,17 +531,30 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 527 | 531 | options.libc_installation, |
| 528 | 532 | ); |
| 529 | 533 | |
| 534 | const must_pie = target_util.requiresPIE(options.target); | |
| 535 | const pie = if (options.want_pie) |explicit| pie: { | |
| 536 | if (!explicit and must_pie) { | |
| 537 | return error.TargetRequiresPIE; | |
| 538 | } | |
| 539 | break :pie explicit; | |
| 540 | } else must_pie; | |
| 541 | ||
| 530 | 542 | const must_pic: bool = b: { |
| 531 | 543 | if (target_util.requiresPIC(options.target, link_libc)) |
| 532 | 544 | break :b true; |
| 533 | 545 | break :b link_mode == .Dynamic; |
| 534 | 546 | }; |
| 535 | 547 | const pic = if (options.want_pic) |explicit| pic: { |
| 536 | if (!explicit and must_pic) { | |
| 537 | return error.TargetRequiresPIC; | |
| 548 | if (!explicit) { | |
| 549 | if (must_pic) { | |
| 550 | return error.TargetRequiresPIC; | |
| 551 | } | |
| 552 | if (pie) { | |
| 553 | return error.PIERequiresPIC; | |
| 554 | } | |
| 538 | 555 | } |
| 539 | 556 | break :pic explicit; |
| 540 | } else must_pic; | |
| 557 | } else pie or must_pic; | |
| 541 | 558 | |
| 542 | 559 | // Make a decision on whether to use Clang for translate-c and compiling C files. |
| 543 | 560 | const use_clang = if (options.use_clang) |explicit| explicit else blk: { |
| ... | ... | @@ -618,6 +635,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 618 | 635 | cache.hash.add(options.target.abi); |
| 619 | 636 | cache.hash.add(ofmt); |
| 620 | 637 | cache.hash.add(pic); |
| 638 | cache.hash.add(pie); | |
| 621 | 639 | cache.hash.add(stack_check); |
| 622 | 640 | cache.hash.add(link_mode); |
| 623 | 641 | cache.hash.add(options.function_sections); |
| ... | ... | @@ -814,6 +832,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 814 | 832 | .version = options.version, |
| 815 | 833 | .libc_installation = libc_dirs.libc_installation, |
| 816 | 834 | .pic = pic, |
| 835 | .pie = pie, | |
| 817 | 836 | .valgrind = valgrind, |
| 818 | 837 | .stack_check = stack_check, |
| 819 | 838 | .single_threaded = single_threaded, |
| ... | ... | @@ -898,7 +917,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 898 | 917 | try comp.addBuildingGLibCJobs(); |
| 899 | 918 | } |
| 900 | 919 | if (comp.wantBuildMuslFromSource()) { |
| 901 | try comp.work_queue.ensureUnusedCapacity(5); | |
| 920 | try comp.work_queue.ensureUnusedCapacity(6); | |
| 902 | 921 | if (target_util.libc_needs_crti_crtn(comp.getTarget())) { |
| 903 | 922 | comp.work_queue.writeAssumeCapacity(&[_]Job{ |
| 904 | 923 | .{ .musl_crt_file = .crti_o }, |
| ... | ... | @@ -908,6 +927,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 908 | 927 | comp.work_queue.writeAssumeCapacity(&[_]Job{ |
| 909 | 928 | .{ .musl_crt_file = .crt1_o }, |
| 910 | 929 | .{ .musl_crt_file = .scrt1_o }, |
| 930 | .{ .musl_crt_file = .rcrt1_o }, | |
| 911 | 931 | .{ .musl_crt_file = .libc_a }, |
| 912 | 932 | }); |
| 913 | 933 | } |
| ... | ... | @@ -2473,6 +2493,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2473 | 2493 | \\pub const have_error_return_tracing = {}; |
| 2474 | 2494 | \\pub const valgrind_support = {}; |
| 2475 | 2495 | \\pub const position_independent_code = {}; |
| 2496 | \\pub const position_independent_executable = {}; | |
| 2476 | 2497 | \\pub const strip_debug_info = {}; |
| 2477 | 2498 | \\pub const code_model = CodeModel.{}; |
| 2478 | 2499 | \\ |
| ... | ... | @@ -2484,6 +2505,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 |
| 2484 | 2505 | comp.bin_file.options.error_return_tracing, |
| 2485 | 2506 | comp.bin_file.options.valgrind, |
| 2486 | 2507 | comp.bin_file.options.pic, |
| 2508 | comp.bin_file.options.pie, | |
| 2487 | 2509 | comp.bin_file.options.strip, |
| 2488 | 2510 | @tagName(comp.bin_file.options.machine_code_model), |
| 2489 | 2511 | }); |
| ... | ... | @@ -2587,6 +2609,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR |
| 2587 | 2609 | .want_stack_check = false, |
| 2588 | 2610 | .want_valgrind = false, |
| 2589 | 2611 | .want_pic = comp.bin_file.options.pic, |
| 2612 | .want_pie = comp.bin_file.options.pie, | |
| 2590 | 2613 | .emit_h = null, |
| 2591 | 2614 | .strip = comp.bin_file.options.strip, |
| 2592 | 2615 | .is_native_os = comp.bin_file.options.is_native_os, |
| ... | ... | @@ -2795,6 +2818,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node |
| 2795 | 2818 | .subsystem = subsystem, |
| 2796 | 2819 | .err_color = @enumToInt(comp.color), |
| 2797 | 2820 | .pic = comp.bin_file.options.pic, |
| 2821 | .pie = comp.bin_file.options.pie, | |
| 2798 | 2822 | .link_libc = comp.bin_file.options.link_libc, |
| 2799 | 2823 | .link_libcpp = comp.bin_file.options.link_libcpp, |
| 2800 | 2824 | .strip = comp.bin_file.options.strip, |
| ... | ... | @@ -2950,6 +2974,7 @@ pub fn build_crt_file( |
| 2950 | 2974 | .want_stack_check = false, |
| 2951 | 2975 | .want_valgrind = false, |
| 2952 | 2976 | .want_pic = comp.bin_file.options.pic, |
| 2977 | .want_pie = comp.bin_file.options.pie, | |
| 2953 | 2978 | .emit_h = null, |
| 2954 | 2979 | .strip = comp.bin_file.options.strip, |
| 2955 | 2980 | .is_native_os = comp.bin_file.options.is_native_os, |
src/clang_options_data.zig+16-2| ... | ... | @@ -2460,7 +2460,14 @@ sepd1("exported_symbols_list"), |
| 2460 | 2460 | .pd2 = false, |
| 2461 | 2461 | .psl = false, |
| 2462 | 2462 | }, |
| 2463 | flagpd1("fPIE"), | |
| 2463 | .{ | |
| 2464 | .name = "fPIE", | |
| 2465 | .syntax = .flag, | |
| 2466 | .zig_equivalent = .pie, | |
| 2467 | .pd1 = true, | |
| 2468 | .pd2 = false, | |
| 2469 | .psl = false, | |
| 2470 | }, | |
| 2464 | 2471 | flagpd1("fno-access-control"), |
| 2465 | 2472 | flagpd1("faddrsig"), |
| 2466 | 2473 | flagpd1("faggressive-function-elimination"), |
| ... | ... | @@ -2775,7 +2782,14 @@ flagpd1("fnext-runtime"), |
| 2775 | 2782 | .pd2 = false, |
| 2776 | 2783 | .psl = false, |
| 2777 | 2784 | }, |
| 2778 | flagpd1("fno-PIE"), | |
| 2785 | .{ | |
| 2786 | .name = "fno-PIE", | |
| 2787 | .syntax = .flag, | |
| 2788 | .zig_equivalent = .no_pie, | |
| 2789 | .pd1 = true, | |
| 2790 | .pd2 = false, | |
| 2791 | .psl = false, | |
| 2792 | }, | |
| 2779 | 2793 | flagpd1("fno-no-access-control"), |
| 2780 | 2794 | flagpd1("fno-addrsig"), |
| 2781 | 2795 | flagpd1("fno-aggressive-function-elimination"), |
src/libcxx.zig+2| ... | ... | @@ -171,6 +171,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { |
| 171 | 171 | .want_stack_check = false, |
| 172 | 172 | .want_valgrind = false, |
| 173 | 173 | .want_pic = comp.bin_file.options.pic, |
| 174 | .want_pie = comp.bin_file.options.pie, | |
| 174 | 175 | .emit_h = null, |
| 175 | 176 | .strip = comp.bin_file.options.strip, |
| 176 | 177 | .is_native_os = comp.bin_file.options.is_native_os, |
| ... | ... | @@ -288,6 +289,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { |
| 288 | 289 | .want_stack_check = false, |
| 289 | 290 | .want_valgrind = false, |
| 290 | 291 | .want_pic = comp.bin_file.options.pic, |
| 292 | .want_pie = comp.bin_file.options.pie, | |
| 291 | 293 | .emit_h = null, |
| 292 | 294 | .strip = comp.bin_file.options.strip, |
| 293 | 295 | .is_native_os = comp.bin_file.options.is_native_os, |
src/libunwind.zig+1| ... | ... | @@ -104,6 +104,7 @@ pub fn buildStaticLib(comp: *Compilation) !void { |
| 104 | 104 | .want_stack_check = false, |
| 105 | 105 | .want_valgrind = false, |
| 106 | 106 | .want_pic = comp.bin_file.options.pic, |
| 107 | .want_pie = comp.bin_file.options.pie, | |
| 107 | 108 | .emit_h = null, |
| 108 | 109 | .strip = comp.bin_file.options.strip, |
| 109 | 110 | .is_native_os = comp.bin_file.options.is_native_os, |
src/link.zig+1| ... | ... | @@ -71,6 +71,7 @@ pub const Options = struct { |
| 71 | 71 | bind_global_refs_locally: bool, |
| 72 | 72 | is_native_os: bool, |
| 73 | 73 | pic: bool, |
| 74 | pie: bool, | |
| 74 | 75 | valgrind: bool, |
| 75 | 76 | stack_check: bool, |
| 76 | 77 | single_threaded: bool, |
src/link/Elf.zig+6-2| ... | ... | @@ -1425,7 +1425,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1425 | 1425 | try argv.append("-shared"); |
| 1426 | 1426 | } |
| 1427 | 1427 | |
| 1428 | if (target_util.requiresPIE(target) and self.base.options.output_mode == .Exe) { | |
| 1428 | if (self.base.options.pie and self.base.options.output_mode == .Exe) { | |
| 1429 | 1429 | try argv.append("-pie"); |
| 1430 | 1430 | } |
| 1431 | 1431 | |
| ... | ... | @@ -1444,7 +1444,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1444 | 1444 | break :o "crtbegin_static.o"; |
| 1445 | 1445 | } |
| 1446 | 1446 | } else if (self.base.options.link_mode == .Static) { |
| 1447 | break :o "crt1.o"; | |
| 1447 | if (self.base.options.pie) { | |
| 1448 | break :o "rcrt1.o"; | |
| 1449 | } else { | |
| 1450 | break :o "crt1.o"; | |
| 1451 | } | |
| 1448 | 1452 | } else { |
| 1449 | 1453 | break :o "Scrt1.o"; |
| 1450 | 1454 | } |
src/main.zig+12| ... | ... | @@ -270,6 +270,8 @@ const usage_build_generic = |
| 270 | 270 | \\ --main-pkg-path Set the directory of the root package |
| 271 | 271 | \\ -fPIC Force-enable Position Independent Code |
| 272 | 272 | \\ -fno-PIC Force-disable Position Independent Code |
| 273 | \\ -fPIE Force-enable Position Independent Executable | |
| 274 | \\ -fno-PIE Force-disable Position Independent Executable | |
| 273 | 275 | \\ -fstack-check Enable stack probing in unsafe builds |
| 274 | 276 | \\ -fno-stack-check Disable stack probing in safe builds |
| 275 | 277 | \\ -fsanitize-c Enable C undefined behavior detection in unsafe builds |
| ... | ... | @@ -457,6 +459,7 @@ fn buildOutputType( |
| 457 | 459 | var want_native_include_dirs = false; |
| 458 | 460 | var enable_cache: ?bool = null; |
| 459 | 461 | var want_pic: ?bool = null; |
| 462 | var want_pie: ?bool = null; | |
| 460 | 463 | var want_sanitize_c: ?bool = null; |
| 461 | 464 | var want_stack_check: ?bool = null; |
| 462 | 465 | var want_valgrind: ?bool = null; |
| ... | ... | @@ -795,6 +798,10 @@ fn buildOutputType( |
| 795 | 798 | want_pic = true; |
| 796 | 799 | } else if (mem.eql(u8, arg, "-fno-PIC")) { |
| 797 | 800 | want_pic = false; |
| 801 | } else if (mem.eql(u8, arg, "-fPIE")) { | |
| 802 | want_pie = true; | |
| 803 | } else if (mem.eql(u8, arg, "-fno-PIE")) { | |
| 804 | want_pie = false; | |
| 798 | 805 | } else if (mem.eql(u8, arg, "-fstack-check")) { |
| 799 | 806 | want_stack_check = true; |
| 800 | 807 | } else if (mem.eql(u8, arg, "-fno-stack-check")) { |
| ... | ... | @@ -1006,6 +1013,8 @@ fn buildOutputType( |
| 1006 | 1013 | }, |
| 1007 | 1014 | .pic => want_pic = true, |
| 1008 | 1015 | .no_pic => want_pic = false, |
| 1016 | .pie => want_pie = true, | |
| 1017 | .no_pie => want_pie = false, | |
| 1009 | 1018 | .nostdlib => ensure_libc_on_non_freestanding = false, |
| 1010 | 1019 | .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false, |
| 1011 | 1020 | .shared => { |
| ... | ... | @@ -1640,6 +1649,7 @@ fn buildOutputType( |
| 1640 | 1649 | .link_libc = link_libc, |
| 1641 | 1650 | .link_libcpp = link_libcpp, |
| 1642 | 1651 | .want_pic = want_pic, |
| 1652 | .want_pie = want_pie, | |
| 1643 | 1653 | .want_sanitize_c = want_sanitize_c, |
| 1644 | 1654 | .want_stack_check = want_stack_check, |
| 1645 | 1655 | .want_valgrind = want_valgrind, |
| ... | ... | @@ -2773,6 +2783,8 @@ pub const ClangArgIterator = struct { |
| 2773 | 2783 | driver_punt, |
| 2774 | 2784 | pic, |
| 2775 | 2785 | no_pic, |
| 2786 | pie, | |
| 2787 | no_pie, | |
| 2776 | 2788 | nostdlib, |
| 2777 | 2789 | nostdlib_cpp, |
| 2778 | 2790 | shared, |
src/musl.zig+18| ... | ... | @@ -12,6 +12,7 @@ pub const CRTFile = enum { |
| 12 | 12 | crti_o, |
| 13 | 13 | crtn_o, |
| 14 | 14 | crt1_o, |
| 15 | rcrt1_o, | |
| 15 | 16 | scrt1_o, |
| 16 | 17 | libc_a, |
| 17 | 18 | }; |
| ... | ... | @@ -68,6 +69,23 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { |
| 68 | 69 | }, |
| 69 | 70 | }); |
| 70 | 71 | }, |
| 72 | .rcrt1_o => { | |
| 73 | var args = std.ArrayList([]const u8).init(arena); | |
| 74 | try add_cc_args(comp, arena, &args, false); | |
| 75 | try args.appendSlice(&[_][]const u8{ | |
| 76 | "-fPIC", | |
| 77 | "-fno-stack-protector", | |
| 78 | "-DCRT", | |
| 79 | }); | |
| 80 | return comp.build_crt_file("rcrt1", .Obj, &[1]Compilation.CSourceFile{ | |
| 81 | .{ | |
| 82 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | |
| 83 | "libc", "musl", "crt", "rcrt1.c", | |
| 84 | }), | |
| 85 | .extra_flags = args.items, | |
| 86 | }, | |
| 87 | }); | |
| 88 | }, | |
| 71 | 89 | .scrt1_o => { |
| 72 | 90 | var args = std.ArrayList([]const u8).init(arena); |
| 73 | 91 | try add_cc_args(comp, arena, &args, false); |
src/stage1.zig+1| ... | ... | @@ -108,6 +108,7 @@ pub const Module = extern struct { |
| 108 | 108 | subsystem: TargetSubsystem, |
| 109 | 109 | err_color: ErrColor, |
| 110 | 110 | pic: bool, |
| 111 | pie: bool, | |
| 111 | 112 | link_libc: bool, |
| 112 | 113 | link_libcpp: bool, |
| 113 | 114 | strip: bool, |
src/stage1/all_types.hpp+1| ... | ... | @@ -2177,6 +2177,7 @@ struct CodeGen { |
| 2177 | 2177 | bool is_test_build; |
| 2178 | 2178 | bool is_single_threaded; |
| 2179 | 2179 | bool have_pic; |
| 2180 | bool have_pie; | |
| 2180 | 2181 | bool link_mode_dynamic; |
| 2181 | 2182 | bool dll_export_fns; |
| 2182 | 2183 | bool have_stack_probing; |
src/stage1/codegen.cpp+9| ... | ... | @@ -9043,6 +9043,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 9043 | 9043 | buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); |
| 9044 | 9044 | buf_appendf(contents, "pub const valgrind_support = false;\n"); |
| 9045 | 9045 | buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); |
| 9046 | buf_appendf(contents, "pub const position_independent_executable = %s;\n", bool_to_str(g->have_pie)); | |
| 9046 | 9047 | buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols)); |
| 9047 | 9048 | buf_appendf(contents, "pub const code_model = CodeModel.default;\n"); |
| 9048 | 9049 | |
| ... | ... | @@ -9170,6 +9171,14 @@ static void init(CodeGen *g) { |
| 9170 | 9171 | reloc_mode = LLVMRelocStatic; |
| 9171 | 9172 | } |
| 9172 | 9173 | |
| 9174 | if (g->have_pic) { | |
| 9175 | ZigLLVMSetModulePICLevel(g->module); | |
| 9176 | } | |
| 9177 | ||
| 9178 | if (g->have_pie) { | |
| 9179 | ZigLLVMSetModulePIELevel(g->module); | |
| 9180 | } | |
| 9181 | ||
| 9173 | 9182 | const char *target_specific_cpu_args = ""; |
| 9174 | 9183 | const char *target_specific_features = ""; |
| 9175 | 9184 |
src/stage1/stage1.cpp+1| ... | ... | @@ -89,6 +89,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { |
| 89 | 89 | g->link_mode_dynamic = stage1->link_mode_dynamic; |
| 90 | 90 | g->dll_export_fns = stage1->dll_export_fns; |
| 91 | 91 | g->have_pic = stage1->pic; |
| 92 | g->have_pie = stage1->pie; | |
| 92 | 93 | g->have_stack_probing = stage1->enable_stack_probing; |
| 93 | 94 | g->is_single_threaded = stage1->is_single_threaded; |
| 94 | 95 | g->valgrind_enabled = stage1->valgrind_enabled; |
src/stage1/stage1.h+1| ... | ... | @@ -177,6 +177,7 @@ struct ZigStage1 { |
| 177 | 177 | enum ErrColor err_color; |
| 178 | 178 | |
| 179 | 179 | bool pic; |
| 180 | bool pie; | |
| 180 | 181 | bool link_libc; |
| 181 | 182 | bool link_libcpp; |
| 182 | 183 | bool strip; |
tools/update_clang_options.zig+8| ... | ... | @@ -54,6 +54,14 @@ const known_options = [_]KnownOpt{ |
| 54 | 54 | .name = "fno-PIC", |
| 55 | 55 | .ident = "no_pic", |
| 56 | 56 | }, |
| 57 | .{ | |
| 58 | .name = "fPIE", | |
| 59 | .ident = "pie", | |
| 60 | }, | |
| 61 | .{ | |
| 62 | .name = "fno-PIE", | |
| 63 | .ident = "no_pie", | |
| 64 | }, | |
| 57 | 65 | .{ |
| 58 | 66 | .name = "nolibc", |
| 59 | 67 | .ident = "nostdlib", |