[Git][ghc/ghc][wip/T22011] rts: Add generator for RtsSymbols from libgcc

Ben Gamari (@bgamari) gitlab at gitlab.haskell.org
Thu Jul 13 15:38:34 UTC 2023



Ben Gamari pushed to branch wip/T22011 at Glasgow Haskell Compiler / GHC


Commits:
b7a3b3b2 by Ben Gamari at 2023-07-13T11:36:46-04:00
rts: Add generator for RtsSymbols from libgcc

- - - - -


6 changed files:

- hadrian/src/Flavour.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Register.hs
- − rts/AArch64Symbols.h
- rts/RtsSymbols.c
- + rts/gen_libgcc_symbols.py


Changes:

=====================================
hadrian/src/Flavour.hs
=====================================
@@ -142,6 +142,8 @@ werror =
           [ arg "-optc-Werror"
             -- clang complains about #pragma GCC pragmas
           , arg "-optc-Wno-error=unknown-pragmas"
+            -- RtsSymbols.c ascribes the wrong type to some builtins
+          , arg "-optc-Wno-error=builtin-declaration-mismatch"
             -- rejected inlinings are highly dependent upon toolchain and way
           , arg "-optc-Wno-error=inline"
           ]


=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -59,21 +59,26 @@ rtsDependencies = do
     jsTarget <- expr isJsTarget
     useSystemFfi <- expr (flag UseSystemFfi)
 
-    let -- headers common to native and JS RTS
+    let in_include file = rtsPath -/- "include" -/- file
+
+        -- headers common to native and JS RTS
         common_headers =
+            map in_include
             [ "ghcautoconf.h", "ghcplatform.h"
             , "DerivedConstants.h"
             ]
         -- headers specific to the native RTS
         native_headers =
+            map in_include
             [ "rts" -/- "EventTypes.h"
             , "rts" -/- "EventLogConstants.h"
             ]
-            ++ (if useSystemFfi then [] else libffiHeaderFiles)
+            ++ (if useSystemFfi then [] else map in_include libffiHeaderFiles)
+            ++ [ in_include $ rtsPath -/- "LibgccSymbols.h" ]
         headers
           | jsTarget  = common_headers
           | otherwise = common_headers ++ native_headers
-    pure $ ((rtsPath -/- "include") -/-) <$> headers
+    pure headers
 
 genapplyDependencies :: Expr [FilePath]
 genapplyDependencies = do
@@ -166,7 +171,7 @@ generatePackageCode context@(Context stage pkg _ _) = do
               [accessOpsSource, "addr-access-ops", file]
               [] []
         root -/- primopsTxt stage %> \file -> do
-            need $ [primopsSource, ba_ops_txt, addr_ops_txt]
+            need [primopsSource, ba_ops_txt, addr_ops_txt]
             -- ba_ops_txt and addr_ops_txt get #include-d
             build $ target context HsCpp [primopsSource] [file]
 
@@ -180,13 +185,49 @@ generatePackageCode context@(Context stage pkg _ _) = do
         root -/- "**" -/- dir -/- "include/DerivedConstants.h" %> genPlatformConstantsHeader context
         root -/- "**" -/- dir -/- "include/rts/EventLogConstants.h" %> genEventTypes "--event-types-defines"
         root -/- "**" -/- dir -/- "include/rts/EventTypes.h" %> genEventTypes "--event-types-array"
+        root -/- "**" -/- dir -/- "LibgccSymbols.h" %> genLibgccSymbols context
+
+genLibgccSymbols :: Context -> FilePath -> Action ()
+genLibgccSymbols (Context stage _ _ _) outFile = do
+    libgcc <- getLibgccPath
+    need [script]
+    runBuilder Python [script, libgcc, "-o", outFile] [] []
+  where
+    script = "rts" -/- "gen_libgcc_symbols.py"
+
+    getLibgccPath :: Action FilePath
+    getLibgccPath = do
+      let builder = Cc CompileC stage
+      needBuilders [builder]
+      path <- builderPath builder
+      StdoutTrim libgcc <- quietly $ cmd [path] ["-print-libgcc-file-name"]
+
+      -- Annoyingly, Apple's toolchain returns the non-existent
+      -- libclang_rt.builtins-aarch64.a when asked to -print-libgcc-file-name.
+      -- However, the file is actually called libclang_rt.osx.a. Moreover,
+      -- on some more recent XCodes the directory is also wrong.
+      --
+      -- e.g. on Darwin -print-libgcc-file-name tells us:
+      --   /Library/Developer/CommandLineTools/usr/lib/clang/12.0.5/lib/darwin20.5.0/libclang_rt.builtins-aarch64.a
+      -- yet the path is in fact
+      --
+      --   /Library/Developer/CommandLineTools/usr/lib/clang/12.0.5/lib/darwin/libclang_rt.osx.a
+      -- We workaround this with this horrible hack.
+      os <- setting TargetOs
+      pure $
+        case os of
+          "darwin" -> let libDir = takeDirectory $ takeDirectory libgcc
+                      in libDir </> "darwin" </> "libclang_rt.osx.a"
+          "ios" -> let libDir = takeDirectory $ takeDirectory libgcc
+                   in libDir </> "darwin" </> "libclang_rt.osx.a"
+          _ -> libgcc
 
 genEventTypes :: String -> FilePath -> Action ()
 genEventTypes flag file = do
-    need ["rts" -/- "gen_event_types.py"]
-    runBuilder Python
-      ["rts" -/- "gen_event_types.py", flag, file]
-      [] []
+    need [script]
+    runBuilder Python [script, flag, file] [] []
+  where
+    script = "rts" -/- "gen_event_types.py"
 
 genPrimopCode :: Context -> FilePath -> Action ()
 genPrimopCode context@(Context stage _pkg _ _) file = do


=====================================
hadrian/src/Rules/Register.hs
=====================================
@@ -212,6 +212,7 @@ buildConfInplace rs context at Context {..} _conf = do
              , path -/- "include/ghcplatform.h"
              , path -/- "include/rts/EventLogConstants.h"
              , path -/- "include/rts/EventTypes.h"
+             , path -/- "LibgccSymbols.h"
              ]
 
     -- we need to generate this file for GMP


=====================================
rts/AArch64Symbols.h deleted
=====================================
@@ -1,100 +0,0 @@
-    SymE_NeedsProto(__aarch64_cas8_acq),
-    SymE_NeedsProto(__aarch64_cas8_acq),
-    SymE_NeedsProto(__aarch64_cas8_acq),
-    SymE_NeedsProto(__aarch64_cas8_acq),
-    SymE_NeedsProto(__aarch64_cas8_acq),
-    SymE_NeedsProto(__aarch64_cas8_acq_rel),
-    SymE_NeedsProto(__aarch64_cas8_acq_rel),
-    SymE_NeedsProto(__aarch64_cas8_acq_rel),
-    SymE_NeedsProto(__aarch64_cas8_acq_rel),
-    SymE_NeedsProto(__aarch64_cas8_acq_rel),
-    SymE_NeedsProto(__aarch64_cas8_rel),
-    SymE_NeedsProto(__aarch64_cas8_rel),
-    SymE_NeedsProto(__aarch64_cas8_rel),
-    SymE_NeedsProto(__aarch64_cas8_rel),
-    SymE_NeedsProto(__aarch64_cas8_rel),
-    SymE_NeedsProto(__aarch64_cas8_relax),
-    SymE_NeedsProto(__aarch64_cas8_relax),
-    SymE_NeedsProto(__aarch64_cas8_relax),
-    SymE_NeedsProto(__aarch64_cas8_relax),
-    SymE_NeedsProto(__aarch64_cas8_relax),
-    SymE_NeedsProto(__aarch64_ldadd1_acq),
-    SymE_NeedsProto(__aarch64_ldadd1_acq_rel),
-    SymE_NeedsProto(__aarch64_ldadd1_rel),
-    SymE_NeedsProto(__aarch64_ldadd1_relax),
-    SymE_NeedsProto(__aarch64_ldadd2_acq),
-    SymE_NeedsProto(__aarch64_ldadd2_acq_rel),
-    SymE_NeedsProto(__aarch64_ldadd2_rel),
-    SymE_NeedsProto(__aarch64_ldadd2_relax),
-    SymE_NeedsProto(__aarch64_ldadd4_acq),
-    SymE_NeedsProto(__aarch64_ldadd4_acq_rel),
-    SymE_NeedsProto(__aarch64_ldadd4_rel),
-    SymE_NeedsProto(__aarch64_ldadd4_relax),
-    SymE_NeedsProto(__aarch64_ldadd8_acq),
-    SymE_NeedsProto(__aarch64_ldadd8_acq_rel),
-    SymE_NeedsProto(__aarch64_ldadd8_rel),
-    SymE_NeedsProto(__aarch64_ldadd8_relax),
-    SymE_NeedsProto(__aarch64_ldclr1_acq),
-    SymE_NeedsProto(__aarch64_ldclr1_acq_rel),
-    SymE_NeedsProto(__aarch64_ldclr1_rel),
-    SymE_NeedsProto(__aarch64_ldclr1_relax),
-    SymE_NeedsProto(__aarch64_ldclr2_acq),
-    SymE_NeedsProto(__aarch64_ldclr2_acq_rel),
-    SymE_NeedsProto(__aarch64_ldclr2_rel),
-    SymE_NeedsProto(__aarch64_ldclr2_relax),
-    SymE_NeedsProto(__aarch64_ldclr4_acq),
-    SymE_NeedsProto(__aarch64_ldclr4_acq_rel),
-    SymE_NeedsProto(__aarch64_ldclr4_rel),
-    SymE_NeedsProto(__aarch64_ldclr4_relax),
-    SymE_NeedsProto(__aarch64_ldclr8_acq),
-    SymE_NeedsProto(__aarch64_ldclr8_acq_rel),
-    SymE_NeedsProto(__aarch64_ldclr8_rel),
-    SymE_NeedsProto(__aarch64_ldclr8_relax),
-    SymE_NeedsProto(__aarch64_ldeor1_acq),
-    SymE_NeedsProto(__aarch64_ldeor1_acq_rel),
-    SymE_NeedsProto(__aarch64_ldeor1_rel),
-    SymE_NeedsProto(__aarch64_ldeor1_relax),
-    SymE_NeedsProto(__aarch64_ldeor2_acq),
-    SymE_NeedsProto(__aarch64_ldeor2_acq_rel),
-    SymE_NeedsProto(__aarch64_ldeor2_rel),
-    SymE_NeedsProto(__aarch64_ldeor2_relax),
-    SymE_NeedsProto(__aarch64_ldeor4_acq),
-    SymE_NeedsProto(__aarch64_ldeor4_acq_rel),
-    SymE_NeedsProto(__aarch64_ldeor4_rel),
-    SymE_NeedsProto(__aarch64_ldeor4_relax),
-    SymE_NeedsProto(__aarch64_ldeor8_acq),
-    SymE_NeedsProto(__aarch64_ldeor8_acq_rel),
-    SymE_NeedsProto(__aarch64_ldeor8_rel),
-    SymE_NeedsProto(__aarch64_ldeor8_relax),
-    SymE_NeedsProto(__aarch64_ldset1_acq),
-    SymE_NeedsProto(__aarch64_ldset1_acq_rel),
-    SymE_NeedsProto(__aarch64_ldset1_rel),
-    SymE_NeedsProto(__aarch64_ldset1_relax),
-    SymE_NeedsProto(__aarch64_ldset2_acq),
-    SymE_NeedsProto(__aarch64_ldset2_acq_rel),
-    SymE_NeedsProto(__aarch64_ldset2_rel),
-    SymE_NeedsProto(__aarch64_ldset2_relax),
-    SymE_NeedsProto(__aarch64_ldset4_acq),
-    SymE_NeedsProto(__aarch64_ldset4_acq_rel),
-    SymE_NeedsProto(__aarch64_ldset4_rel),
-    SymE_NeedsProto(__aarch64_ldset4_relax),
-    SymE_NeedsProto(__aarch64_ldset8_acq),
-    SymE_NeedsProto(__aarch64_ldset8_acq_rel),
-    SymE_NeedsProto(__aarch64_ldset8_rel),
-    SymE_NeedsProto(__aarch64_ldset8_relax),
-    SymE_NeedsProto(__aarch64_swp1_acq),
-    SymE_NeedsProto(__aarch64_swp1_acq_rel),
-    SymE_NeedsProto(__aarch64_swp1_rel),
-    SymE_NeedsProto(__aarch64_swp1_relax),
-    SymE_NeedsProto(__aarch64_swp2_acq),
-    SymE_NeedsProto(__aarch64_swp2_acq_rel),
-    SymE_NeedsProto(__aarch64_swp2_rel),
-    SymE_NeedsProto(__aarch64_swp2_relax),
-    SymE_NeedsProto(__aarch64_swp4_acq),
-    SymE_NeedsProto(__aarch64_swp4_acq_rel),
-    SymE_NeedsProto(__aarch64_swp4_rel),
-    SymE_NeedsProto(__aarch64_swp4_relax),
-    SymE_NeedsProto(__aarch64_swp8_acq),
-    SymE_NeedsProto(__aarch64_swp8_acq_rel),
-    SymE_NeedsProto(__aarch64_swp8_rel),
-    SymE_NeedsProto(__aarch64_swp8_relax),


=====================================
rts/RtsSymbols.c
=====================================
@@ -947,26 +947,6 @@ extern char **environ;
       RTS_USER_SIGNALS_SYMBOLS                                          \
       RTS_INTCHAR_SYMBOLS
 
-// 64-bit support functions in libgcc.a
-#if defined(__GNUC__) && SIZEOF_VOID_P <= 4 && !defined(_ABIN32)
-#define RTS_LIBGCC_SYMBOLS                             \
-      SymI_NeedsProto(__divdi3)                        \
-      SymI_NeedsProto(__udivdi3)                       \
-      SymI_NeedsProto(__moddi3)                        \
-      SymI_NeedsProto(__umoddi3)                       \
-      SymI_NeedsProto(__muldi3)                        \
-      SymI_NeedsProto(__ashldi3)                       \
-      SymI_NeedsProto(__ashrdi3)                       \
-      SymI_NeedsProto(__lshrdi3)                       \
-      SymI_NeedsProto(__fixunsdfdi)
-#elif defined(__GNUC__) && SIZEOF_VOID_P == 8
-#define RTS_LIBGCC_SYMBOLS                             \
-      SymI_NeedsProto(__udivti3)                       \
-      SymI_NeedsProto(__umodti3)
-#else
-#define RTS_LIBGCC_SYMBOLS
-#endif
-
 // Symbols defined by libc
 #define RTS_LIBC_SYMBOLS                               \
       SymI_HasProto_redirect(atexit, atexit, STRENGTH_STRONG, CODE_TYPE_CODE) /* See Note [Strong symbols] */ \
@@ -983,6 +963,10 @@ extern char **environ;
 #define RTS_FINI_ARRAY_SYMBOLS
 #endif
 
+// Symbols defined by libgcc/compiler-rt. This file is generated by
+// gen_libgcc_symbols.py.
+#include "LibgccSymbols.h"
+
 /* entirely bogus claims about types of these symbols */
 #define SymI_NeedsProto(vvv)  extern void vvv(void);
 #define SymI_NeedsDataProto(vvv)  extern StgWord vvv[];
@@ -1055,9 +1039,6 @@ RtsSymbolVal rtsSyms[] = {
       RTS_LIBGCC_SYMBOLS
       RTS_FINI_ARRAY_SYMBOLS
       RTS_LIBFFI_SYMBOLS
-#if defined(linux_HOST_OS) && defined(aarch64_HOST_ARCH)
-#include "AArch64Symbols.h"
-#endif
       SymI_HasDataProto(nonmoving_write_barrier_enabled)
 #if defined(darwin_HOST_OS) && defined(i386_HOST_ARCH)
       // dyld stub code contains references to this,


=====================================
rts/gen_libgcc_symbols.py
=====================================
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+
+"""
+Uses the POSIX nm tool to export the list of symbols exposed by a library
+to a format which can be included in RtsSymbols.c.
+"""
+
+import sys
+import subprocess
+import argparse
+from typing import Set
+from pathlib import Path
+
+def list_symbols(lib: Path) -> Set[str]:
+    out = subprocess.check_output([
+        'nm', '--format=posix', '--extern-only', '--defined-only', lib
+    ], encoding='ASCII')
+    syms = set()
+    for l in out.split('\n'):
+        parts = l.split(' ')
+        if len(parts) == 4:
+            syms.add(parts[0])
+
+    return syms
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('libgcc', type=Path, help='path to libgcc')
+    parser.add_argument('-o', '--output', default=sys.stdout, type=argparse.FileType('w'), help='output file name')
+    args = parser.parse_args()
+
+    syms = list_symbols(args.libgcc)
+    lines = [ '#define RTS_LIBGCC_SYMBOLS' ]
+    lines += [ f'    SymE_NeedsProto({sym})' for sym in sorted(syms) ]
+    print(' \\\n'.join(lines), file=args.output)
+
+if __name__ == '__main__':
+    main()



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7a3b3b2fcdc7eefe80df6994c347310f29e18ef

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7a3b3b2fcdc7eefe80df6994c347310f29e18ef
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230713/6fec5fe5/attachment-0001.html>


More information about the ghc-commits mailing list