1. 17 Nov, 2015 1 commit
    • Tamar Christina's avatar
      Fix archive loading on Windows by the runtime loader · acce37f3
      Tamar Christina authored
      The runtime loader is unable to find archive files `.a` shipping
      with the inplace `GCC`.
      
      It seems the issue is caused by `findArchive` being unable to
      find any archives that are shipped using the in-place `GCC`.
      
      - It works on Linux because `findArchive` would search
        the standard Linux include path.
      - It works during compilation because `GCC` can find it's own libraries
        (we explicitly tell it where to look for libraries using the `gcc`
        wrapper around `realgcc`)
      
      So fixing the issue means using `searchForLibUsingGcc` in `findArchive`
      as well, which will then find the correct file.
      
      The reason for the error as it is, is because if we can't locate the
      library using any of the methods we have, we assume it is a system dll,
      or something on the system search path.  e.g. if trying to load
      `kernel32.dll`.
      
      There is a slight issue in that the `GHCi` code (incorrectly) favors
      `static archives` over `dynamic` ones
      
      ```
      findDll        `orElse`
      findArchive    `orElse`
      tryGcc         `orElse`
      tryGccPrefixed `orElse`
      assumeDll
      ```
      This has the unwanted effect of when `kernel32` is specified as a lib,
      it will try to load `kernel32.a` instead of `kernel32.dll`.
      
      To solve this I have added another search function that is able to
      search the Windows search paths using `SearchPath` in order to find if
      it is a dll on the system search path.
      
      The new search order is:
      
      ```
      findDll     `orElse`
      findSysDll  `orElse`
      tryGcc      `orElse`
      findArchive `orElse`
      assumeDll
      ```
      
      (`tryGccPrefixed` was rolled into `tryGcc` so it is no longer needed at
      top level)
      
      Test Plan: ./validate added new windows tests T3242
      
      Reviewers: thomie, erikd, hvr, austin, bgamari
      
      Reviewed By: thomie, erikd, bgamari
      
      Differential Revision: https://phabricator.haskell.org/D1455
      
      GHC Trac Issues: #3242
      acce37f3
  2. 07 Nov, 2015 1 commit
    • Tamar Christina's avatar
      Allow the GHCi Linker to resolve related dependencies when loading DLLs · 6e6438e1
      Tamar Christina authored
      Summary:
      GHCi does not correctly tell the Windows Loader how to handle dependencies to DLL's
      that are not on the standard Windows load path:
      
      1. The directory from which the application loaded.
      2. The current directory.
      3. The system directory. Use the GetSystemDirectory function to get the path of this directory.
      4. The 16-bit system directory. There is no function that obtains the path of this directory,
         but it is searched.
      5. The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
      6. The directories that are listed in the PATH environment variable.
         Note that this does not include the per-application path specified by the
         AppPaths registry key. The App Paths key is not used when computing the DLL search path.
      
      So what this means is given two DLLs `A` and `B` and `B` depending on `A`.
      If we put both DLLs into a new folder bin and then call GHC with:
      
      `ghc -L$(PWD)/bin -lB`
      
      the loading will fail as the Windows loader will try to load the dependency of `B` and fail
      since it cannot find `A`.
      
      *IMPORTANT* this patch drops XP Support.
      The  APIs being used were natively added to Windows 8+ and backported to Windows 7 and Vista
      via a mandatory security patch (in 2011). This means that there is a chance that KB2533623 has
      not been installed on certain machines. For those machines I display a warning and
      temporarily expand the `PATH` to allow it to load.
      
      This patch will make sure that paths provided by the user with `-L` *and* the folder in which a
      DLL is found are added to the search path. It does so using one of two methods depending upon how
      new of a Windows version we are running on:
      
      - If the APIs are available it will use `addDllDirectory` and `removeDllDirectory`.
         The order of which these directories are searched is nondeterministic.
      - If the APIs are not available it means that we're running on a pretty old unpatched machine.
        But if it's being used in an environment with no internet access it may be the case.
        So if the APIs are not available we temporarily extend the `PATH` with the directories.
        A warning is also displayed to the user informing them that the linking may fail,
        and if it does, install the needed patch. The `PATH` variable has limitations.
      
      Test Plan:
      ./validate
      
      Added two new test T10955 and T10955dyn
      
      Reviewers: erikd, bgamari, thomie, hvr, austin
      
      Reviewed By: erikd, thomie
      
      Subscribers: #ghc_windows_task_force
      
      Differential Revision: https://phabricator.haskell.org/D1340
      
      GHC Trac Issues: #10955
      6e6438e1
  3. 10 Oct, 2015 1 commit
    • Tamar Christina's avatar
      Add short library names support to Windows linker · 5d841108
      Tamar Christina authored
      Make Linker.hs try asking gcc for lib%s.dll as well, also changed tryGcc
      to pass -L to all components by using -B instead. These two fix
      shortnames linking on windows.
      
      re-enabled tests: ghcilink003, ghcilink006 and T3333
      Added two tests: load_short_name and enabled T1407 on windows.
      
      Reviewed By: thomie, bgamari
      
      Differential Revision: https://phabricator.haskell.org/D1310
      
      GHC Trac Issues: #9878, #1407, #1883, #5289
      5d841108