Skip to content

LLVM generated object files should have their relocatable `.data.rel.ro` sections writable

Summary

Currently, the LLVM code generator can produce code with relocatable data in read-only .data.rel.ro sections. Those sections should be writable when building code. They will be protected once relocation has been done at the execution of the built program by the C runtime.

The reasons for marking those sections writable in GHC would be:

For the latter reason, because GHC produce code with read-only relocatable sections, what comes after it has to mark them as writable. The GNU assembler does that. So in a sense, there's a dependency to it. Is that voluntary? In any case, GHC might as well produce valid code as soon as possible.

The current LLVM pipeline uses the GNU assembler that automatically marks the .data.rel.ro sections as writable. The GNU ld does as well. Removing those could potentially result in segfaults (see #18076 (closed)). The gold linker does not enforce those sections to be writable so the resulting executables won't be valid.

That being said, the problem could only be observed with the deprecated -fast-llvm (see !3120 (closed)) flag and the gold linker. The problem cannot be reproduced with the Native Code Generator (it seems that it doesn't describe those sections, apart from the name, so the GNU assembler might just assume it is writable).

Steps to reproduce

  1. Create a simple RelocRoData.hs Haskell module with the following content:
module RelocRoData
    ( SomeData(..)
    )
where

data SomeData = SomeConstr
  1. Run inplace/bin/ghc-stage2 -v -split-sections -fllvm -c RelocRoData.hs -keep-tmp-files (the sections of interest are only generated with the -split-sections flag)
  2. Run grep data.rel.ro ghc_4.lm_s (where ghc_4.lm_s is actually the path to the generated Assembler file after mangling)

Observe the following output:

        .section        .data.rel.ro.RelocRoData_SomeData_closure_tbl,"a",@progbits

Expected behavior

Following the previous instruction, we should observe:

        .section        .data.rel.ro.RelocRoData_SomeData_closure_tbl,"aw",@progbits

There should be the w indicating that the .data.rel.ro section is writable.

Environment

  • GHC version used: 8.6.5 (as cross-compiler from x86_64 to armv6l, 8.11.0 (latest master version, on x86_64)
  • NixOS 19.09

Implementations

There's an initial (rather quick) implementation as a Haskell.nix patch. Manual testing confirmed it worked when producing armv6l programs with the deprecated fast-llvm flag (GHC 8.6.5).

I'm currently creating a PR in GHC. Without the fast-llvm flag, the issue can only be observed in the intermediary files, which is not ideal.

/cc @angerman @bgamari

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information