From 35f1b0f11ebb97910f3b4c82abd4a87dd52985f9 Mon Sep 17 00:00:00 2001 From: 0dminnimda <0dminnimda@gmail.com> Date: Mon, 4 Nov 2024 02:17:21 +0300 Subject: [PATCH 1/4] Add support for linking as pie --- src/build_settings.cpp | 9 ++++++++- src/linker.cpp | 24 ++++++++++++++++++++++-- src/main.cpp | 21 +++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index e365d032417..c37f24f1268 100644 --- a/src/build_settings.cpp +++ b/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; diff --git a/src/linker.cpp b/src/linker.cpp index 2ed0987ac12..6b16c648954 100644 --- a/src/linker.cpp +++ b/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(), ""); diff --git a/src/main.cpp b/src/main.cpp index 1574ac54468..5d017d51a31 100644 --- a/src/main.cpp +++ b/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 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 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; From c26e7e17a18bac7f188535749240c6cc2709a633 Mon Sep 17 00:00:00 2001 From: 0dminnimda <0dminnimda@gmail.com> Date: Mon, 4 Nov 2024 15:39:06 +0300 Subject: [PATCH 2/4] Simplify use of pie --- src/build_settings.cpp | 7 ------- src/linker.cpp | 29 +++++++++-------------------- src/main.cpp | 21 --------------------- 3 files changed, 9 insertions(+), 48 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index c37f24f1268..e4413b1fea3 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -257,12 +257,6 @@ 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:`. @@ -473,7 +467,6 @@ struct BuildContext { bool print_linker_flags; RelocMode reloc_mode; - LinkPIE link_pie; bool disable_red_zone; isize max_error_count; diff --git a/src/linker.cpp b/src/linker.cpp index 6b16c648954..1ffec3bf716 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -607,27 +607,16 @@ gb_internal i32 linker_stage(LinkerData *gen) { } - 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)"); + if (build_context.build_mode == BuildMode_Executable && build_context.reloc_mode == RelocMode_PIC) { + // Do not disable PIE, let the linker choose. (most likely you want it enabled) + } else 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 "); } - 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(), ""); diff --git a/src/main.cpp b/src/main.cpp index 5d017d51a31..1574ac54468 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -360,7 +360,6 @@ enum BuildFlagKind { BuildFlag_NoThreadLocal, BuildFlag_RelocMode, - BuildFlag_LinkPIE, BuildFlag_DisableRedZone, BuildFlag_DisallowDo, @@ -571,7 +570,6 @@ gb_internal bool parse_build_flags(Array 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); @@ -1334,25 +1332,6 @@ gb_internal bool parse_build_flags(Array 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; From 8ad5e46ff89a94397afa32d84baa1686e2f09702 Mon Sep 17 00:00:00 2001 From: 0dminnimda <0dminnimda@gmail.com> Date: Mon, 4 Nov 2024 15:44:07 +0300 Subject: [PATCH 3/4] Simplify further --- src/linker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linker.cpp b/src/linker.cpp index 1ffec3bf716..1fb5631d41b 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -607,7 +607,7 @@ gb_internal i32 linker_stage(LinkerData *gen) { } - if (build_context.build_mode == BuildMode_Executable && build_context.reloc_mode == RelocMode_PIC) { + if (build_context.build_mode == BuildMode_Executable) { // Do not disable PIE, let the linker choose. (most likely you want it enabled) } else if (build_context.build_mode != BuildMode_DynamicLibrary) { if (build_context.metrics.os != TargetOs_openbsd From 5e308cef5e60a8d50c8d751f50f69534c6c85454 Mon Sep 17 00:00:00 2001 From: 0dminnimda <0dminnimda@gmail.com> Date: Mon, 4 Nov 2024 15:50:28 +0300 Subject: [PATCH 4/4] Revert further simplifiction --- src/linker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linker.cpp b/src/linker.cpp index 1fb5631d41b..1ffec3bf716 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -607,7 +607,7 @@ gb_internal i32 linker_stage(LinkerData *gen) { } - if (build_context.build_mode == BuildMode_Executable) { + if (build_context.build_mode == BuildMode_Executable && build_context.reloc_mode == RelocMode_PIC) { // Do not disable PIE, let the linker choose. (most likely you want it enabled) } else if (build_context.build_mode != BuildMode_DynamicLibrary) { if (build_context.metrics.os != TargetOs_openbsd