Browse Source

Add support for linking as pie

0dminnimda 10 tháng trước cách đây
mục cha
commit
480f32586e
3 tập tin đã thay đổi với 51 bổ sung3 xóa
  1. 8 1
      src/build_settings.cpp
  2. 22 2
      src/linker.cpp
  3. 21 0
      src/main.cpp

+ 8 - 1
src/build_settings.cpp

@@ -257,6 +257,12 @@ enum RelocMode : u8 {
 	RelocMode_DynamicNoPIC,
 };
 
+enum LinkPIE : u8 {
+	LinkPIE_Default,
+	LinkPIE_No,
+	LinkPIE_Yes,
+};
+
 enum BuildPath : u8 {
 	BuildPath_Main_Package,     // Input  Path to the package directory (or file) we're building.
 	BuildPath_RC,               // Input  Path for .rc  file, can be set with `-resource:`.
@@ -453,7 +459,7 @@ struct BuildContext {
 	bool   no_threaded_checker;
 
 	bool   show_debug_messages;
-	
+
 	bool   copy_file_contents;
 
 	bool   no_rtti;
@@ -467,6 +473,7 @@ struct BuildContext {
 	bool   print_linker_flags;
 
 	RelocMode reloc_mode;
+	LinkPIE link_pie;
 	bool   disable_red_zone;
 
 	isize max_error_count;

+ 22 - 2
src/linker.cpp

@@ -605,9 +605,29 @@ gb_internal i32 linker_stage(LinkerData *gen) {
 					link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' ");
 				}
 
-			} else if (build_context.metrics.os != TargetOs_openbsd && build_context.metrics.os != TargetOs_haiku && build_context.metrics.arch != TargetArch_riscv64) {
-				// OpenBSD and Haiku default to PIE executable. do not pass -no-pie for it.
+			}
+
+			switch (build_context.link_pie) {
+			case (LinkPIE_Default):
+				if (build_context.build_mode != BuildMode_DynamicLibrary) {
+					if (build_context.metrics.os != TargetOs_openbsd
+				        && build_context.metrics.os != TargetOs_haiku
+						&& build_context.metrics.arch != TargetArch_riscv64
+					) {
+						// OpenBSD and Haiku default to PIE executable. do not pass -no-pie for it.
+						link_settings = gb_string_appendc(link_settings, "-no-pie ");
+					}
+				}
+				break;
+			case (LinkPIE_Yes):
+				if (build_context.build_mode != BuildMode_Executable) {
+					compiler_error("linking NON-EXECUTABLE as pie (position independent EXECUTABLE)");
+				}
+				link_settings = gb_string_appendc(link_settings, "-pie ");
+				break;
+			case (LinkPIE_No):
 				link_settings = gb_string_appendc(link_settings, "-no-pie ");
+				break;
 			}
 
 			gbString platform_lib_str = gb_string_make(heap_allocator(), "");

+ 21 - 0
src/main.cpp

@@ -360,6 +360,7 @@ enum BuildFlagKind {
 	BuildFlag_NoThreadLocal,
 
 	BuildFlag_RelocMode,
+	BuildFlag_LinkPIE,
 	BuildFlag_DisableRedZone,
 
 	BuildFlag_DisallowDo,
@@ -570,6 +571,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_MinimumOSVersion,        str_lit("minimum-os-version"),        BuildFlagParam_String,  Command__does_build);
 
 	add_flag(&build_flags, BuildFlag_RelocMode,               str_lit("reloc-mode"),                BuildFlagParam_String,  Command__does_build);
+	add_flag(&build_flags, BuildFlag_LinkPIE,                 str_lit("link-pie"),                  BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_DisableRedZone,          str_lit("disable-red-zone"),          BuildFlagParam_None,    Command__does_build);
 
 	add_flag(&build_flags, BuildFlag_DisallowDo,              str_lit("disallow-do"),               BuildFlagParam_None,    Command__does_check);
@@ -1332,6 +1334,25 @@ gb_internal bool parse_build_flags(Array<String> args) {
 
 							break;
 						}
+						case BuildFlag_LinkPIE: {
+							GB_ASSERT(value.kind == ExactValue_String);
+							String v = value.value_string;
+							if (v == "default") {
+								build_context.link_pie = LinkPIE_Default;
+							} else if (v == "yes" || v == "true") {
+								build_context.link_pie = LinkPIE_Yes;
+							} else if (v == "no" || v == "false") {
+								build_context.link_pie = LinkPIE_No;
+							} else {
+								gb_printf_err("-link-pie flag expected one of the following\n");
+								gb_printf_err("\tdefault\n");
+								gb_printf_err("\tyes, true\n");
+								gb_printf_err("\tno, false\n");
+								bad_flags = true;
+							}
+
+							break;
+						}
 						case BuildFlag_DisableRedZone:
 							build_context.disable_red_zone = true;
 							break;