[GHC] #12031: GHCi segfaults on Windows when compiling C code using extern-declared variable

GHC ghc-devs at haskell.org
Sun Jun 12 11:39:48 UTC 2016


#12031: GHCi segfaults on Windows when compiling C code using extern-declared
variable
-------------------------------------+-------------------------------------
        Reporter:  RyanGlScott       |                Owner:  Phyx-
            Type:  bug               |               Status:  patch
        Priority:  high              |            Milestone:  8.0.2
       Component:  Runtime System    |              Version:  8.0.1
  (Linker)                           |
      Resolution:                    |             Keywords:
Operating System:  Windows           |         Architecture:  x86_64
                                     |  (amd64)
 Type of failure:  GHCi crash        |            Test Case:  T12031
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D2316
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by Tamar Christina <tamar@…>):

 In [changeset:"b40e1b4c6746bdc34e6a53548a3925d309201c4d/ghc"
 b40e1b4c/ghc]:
 {{{
 #!CommitTicketReference repository="ghc"
 revision="b40e1b4c6746bdc34e6a53548a3925d309201c4d"
 Fix incorrect calculated relocations on Windows x86_64

 Summary:
 See #12031 for analysis, but essentially what happens is:

 To sum up the issue, the reason this seems to go wrong is because
 of how we initialize the `.bss` section for Windows in the runtime linker.

 The first issue is where we calculate the zero space for the section:

 ```
 zspace = stgCallocBytes(1, bss_sz, "ocGetNames_PEi386(anonymous bss)");
 sectab_i->PointerToRawData = ((UChar*)zspace) - ((UChar*)(oc->image));
 ```

 Where
 ```
 UInt32 PointerToRawData;
 ```

 This means we're stuffing a `64-bit` value into a `32-bit` one. Also
 `zspace`
 can be larger than `oc->image`. In which case it'll overflow and
 then get truncated in the cast.

 The address of a value in the `.bss` section is then calculated as:

 ```
 addr = ((UChar*)(oc->image))
      + (sectabent->PointerToRawData
      + symtab_i->Value);
 ```

 If it does truncate then this calculation won't be correct (which is what
 is happening).

 We then later use the value of `addr` as the `S` (Symbol) value for the
 relocations

 ```
 S = (size_t) lookupSymbol_( (char*)symbol );
 ```

 Now the majority of the relocations are `R_X86_64_PC32` etc.
 e.g. They are guaranteed to fit in a `32-bit` value.

 The `R_X86_64_64` introduced for these pseudo-relocations so they can use
 the full `48-bit` addressing space isn't as lucky.
 As for why it sometimes work has to do on whether the value is truncated
 or not.

 `PointerToRawData` can't be changed because it's size is fixed by the PE
 specification.

 Instead just like with the other platforms, we now use `section` on
 Windows as well.
 This gives us a `start` parameter of type `void*` which solves the issue.

 This refactors the code to use `section.start` and to fix the issues.

 Test Plan: ./validate and new test added T12031

 Reviewers: RyanGlScott, erikd, bgamari, austin, simonmar

 Reviewed By: simonmar

 Subscribers: thomie, #ghc_windows_task_force

 Differential Revision: https://phabricator.haskell.org/D2316

 GHC Trac Issues: #12031, #11317
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12031#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list