| author | |
| committer | |
| log | 7daf0b6f4660245ac518c663f8971aad7e540da8 |
| tree | 44e6d449219d848aa6c8da136512c96c8e76cc6f |
| parent | a996a75e06193d377c3071042ece1c3af5cfdc6c |
| signature |
It has been observed in practice on powerpc64(le)-linux that zig.o (in various
stages and build modes) is large enough that the +/- 32MB branch range of
PowerPC is insufficient to reach from one end of the code section to the other.
With LLVM 21, this leads to silent miscompiles that then crash at runtime. With
LLVM 22, it will at least lead to branch range errors that fail the compilation,
but that gets us no closer to a working compiler.
By using these options, we give the linker much greater flexibility to move code
and data around to satisfy these range constraints; without them, the linker is
not allowed to split up the huge code and data sections of zig.o to do so.
Similar issues have also been observed on powerpc-linux (32-bit), hexagon-linux,
and some variations of mips(64)(el)-linux. But let's be conservative for now;
those other targets can be added to the condition later.
As a data point to support this change, it's worth noting that LLD started
enabling these options for LTO precisely because the resulting large compilation
units ran into these range issues. In some abstract sense, Zig can be seen as
doing a limited form of "LTO" in the frontend, so it's not surprising that we
would hit the same issues.2 files changed, 11 insertions(+), 0 deletions(-)
CMakeLists.txt+5| ... | @@ -787,6 +787,11 @@ else() | ... | @@ -787,6 +787,11 @@ else() |
| 787 | set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2") | 787 | set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2") |
| 788 | set(ZIG1_COMPILE_FLAGS "-std=c99 -Os") | 788 | set(ZIG1_COMPILE_FLAGS "-std=c99 -Os") |
| 789 | set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector") | 789 | set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector") |
| 790 | # Must match the condition in build.zig. | ||
| 791 | if(ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$") | ||
| 792 | set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections") | ||
| 793 | set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -ffunction-sections -fdata-sections") | ||
| 794 | endif() | ||
| 790 | if(APPLE) | 795 | if(APPLE) |
| 791 | set(ZIG2_LINK_FLAGS "-Wl,-stack_size,0x10000000") | 796 | set(ZIG2_LINK_FLAGS "-Wl,-stack_size,0x10000000") |
| 792 | elseif(MINGW) | 797 | elseif(MINGW) |
build.zig+6| ... | @@ -838,6 +838,12 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Ste | ... | @@ -838,6 +838,12 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Ste |
| 838 | }); | 838 | }); |
| 839 | exe.stack_size = stack_size; | 839 | exe.stack_size = stack_size; |
| 840 | 840 | ||
| 841 | // Must match the condition in CMakeLists.txt. | ||
| 842 | const function_data_sections = options.target.result.cpu.arch.isPowerPC(); | ||
| 843 | |||
| 844 | exe.link_function_sections = function_data_sections; | ||
| 845 | exe.link_data_sections = function_data_sections; | ||
| 846 | |||
| 841 | return exe; | 847 | return exe; |
| 842 | } | 848 | } |
| 843 | 849 |