Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,389
    • Issues 4,389
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 373
    • Merge Requests 373
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #18076

Closed
Open
Opened Apr 20, 2020 by Le Tuan@michivi

Fast LLVM with the gold linker results in segfaults

Summary

In a cross-compiling scenario (from x86_64 to armv6l, GHC 8.6.5 with Haskell.nix), using the gold linker with the fast-llvm flag, built Haskell program were segfaulting at startup. Compiling without the fast-llvm flag solves the issue.

Steps to reproduce

The issue manifests itself when trying to execute any program cross-compiled with this building environment, even the remote-iserv program built by Haskell.nix for the target platform (armv6l), or when trying to cross-compile any program requiring remote-iserv (e.g. using TH).

Expected behavior

Built cross-compiled programs should work as expected, without having to remove the fast-llvm flag.

Environment

The issue were encountered with the following environment:

  • Cross-copmpilation from x86_64 to armv6l using Haskell.nix (ref: d1102d342c2f5720a10d77d520d37858af103bf6)
  • GHC 8.6.5
  • GLIBC 2.27
  • The gold linker 1.16 (binutils 2.31.1)
  • NixOS 19.09 (x86_64)

Analysis

The following is what I've found while analyzing the issue. I couldn't find any info related to it in the issue tracker. Note that I've only tested it in an Armv6l + LLVM + GLIBC + GHC 8.6.5 environment, but I haven't tested it on other configurations.

The segfault is happening because the produced Haskell programs have some relocatable data (.data.rel.ro section) in a read-only segment, when they should actually be in a read-write segment segment, that will be write-protected after relocation (GNU_RELRO segment) by GLIBC. Updating the relocatable data then ends up in segfault.

Compiling Haskell code may produce relocatable data (in the .data.rel.ro section) that needs relocation. However, when using the LLVM backend with the fast-llvm flag, the LLVM mangler and GNU assembler are bypassed. And it turns out the LLVM backend alone considers the relocatable data as constant, marking the associated section as read-only. The gold linker seeing that section being read-only then act accordingly, ending up in segfault at startup. Using the ld linker instead of the gold linker, it seems that ld recognizes the .data.rel.ro section as special by name, and marks it writable anyway.

After removing the fast-llvm flag, the GNU assembler is the one producing the object code. However, when seeing the .data.rel.ro section, it recognizes it as special (like the ld linker) and automatically marks it as writeable. The gold linker then recognizes it as containing relocatable data, and thus use a GNU_RELRO segment, ending up in a functional compiled program.

References

This issue was originally described in this Haskell.nix PR, where the workaround was to not use fast-llvm.

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#18076