Duncan Coutts pushed to branch wip/dcoutts/windows-dlls at Glasgow Haskell Compiler / GHC
Commits:
8f9918c5 by Duncan Coutts at 2026-02-02T10:05:41+00:00
Try using response files for hadrian linking with ghc.
On windows, the link command line for ghc-internal is well over 32kb.
We did not encounter this before for static libs, since we already use
ar's @file feature (if available, which it is for the llvm toolchain).
We encounter this now on windows for linking dll files (which uses ghc
calling (l)ld rather than ar).
- - - - -
0d53e47b by Duncan Coutts at 2026-02-02T10:05:42+00:00
Use __attribute__(dllimport)) for external RTS symbol declarations
This is needed to be hygenic about DLL symbol imports and exports.
The attribute is ignored on platforms other than Windows.
Use of the attribute however means that external data symbols do not
have a compile-time constant address (they are loaded using an
indirection). This means we have to adjust the rtsSyms initial linker
table so that it is a local constant in a function, rather than a global
constant. We now define it within a function that pre-populates the
symbol table with the RTS symbols.
- - - - -
c07584ba by Duncan Coutts at 2026-02-02T10:05:42+00:00
Experiment with listing RTS symbols
- - - - -
48f4736b by Duncan Coutts at 2026-02-02T10:14:56+00:00
Experimental mingw .refptr mechanism support
- - - - -
8 changed files:
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/CmmToAsm/PIC.hs
- compiler/GHC/StgToCmm/Lit.hs
- hadrian/src/Builder.hs
- rts/Linker.c
- rts/RtsSymbols.c
- rts/RtsSymbols.h
- + utils/rts-syms/rts-syms.c
Changes:
=====================================
compiler/GHC/Cmm/CLabel.hs
=====================================
@@ -117,6 +117,7 @@ module GHC.Cmm.CLabel (
hasIdLabelInfo,
isBytesLabel,
isForeignLabel,
+ isForeignLabelUnknownPackage,
isSomeRODataLabel,
isStaticClosureLabel,
@@ -448,8 +449,33 @@ data ForeignLabelSource
-- contain compiled Haskell code, and is not associated with any .hi files.
-- We don't have to worry about Haskell code being inlined from
-- external packages. It is safe to treat the RTS package as "external".
+ --
+ -- On Windows in particular, we assume the label is definately in an
+ -- external DLL and expect to link it against a __imp_* symbol. Thus it
+ -- will /not/ link correctly if the symbol is actually in the same DLL.
| ForeignLabelInExternalPackage
+ -- | The label is somewhere, but we do not know if it is in this package or
+ -- an external package. This is the case we end up with for Haskell FFI
+ -- declarations like @foreign import ccall@. There is not enough
+ -- information to tell us if the label is from the same package (e.g. in
+ -- a local @cbits/blah.c@ file) or is from an external foreign library.
+ --
+ -- On ELF, this is not a problem and the symbol can be resolved without
+ -- knowing if its local or external.
+ --
+ -- On Windows/PE, this is a bit of a problem. On Windows one normally
+ -- needs to know if it's local or external since the symbol names and
+ -- ABI differ. However, GCC & LLVM have extensions to help porting Unix
+ -- software (that is used to not making these distinctions). There are a
+ -- number of useful mechanisms including \"auto import\" (to import
+ -- symbols found in DLLs automatically), a @.refptr@ mechanism to load
+ -- data via an indirection (which the linker can relocate) and
+ -- \"pseudo relocations\" which is a runtime feature to do additional
+ -- relocations beyond what the Win32 native linker does.
+ -- See Note [Mingw .refptr mechanism]
+ | ForeignLabelInUnknownPackage
+
-- | Label is in the package currently being compiled.
-- This is only used for creating hacky tmp labels during code generation.
-- Don't use it in any code that might be inlined across a package boundary
@@ -600,6 +626,8 @@ data CmmLabelInfo
data DynamicLinkerLabelInfo
= CodeStub -- MachO: Lfoo$stub, ELF: foo@plt
| SymbolPtr -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
+ | DataRefPtr -- Windows: .refptr.foo
+ -- see Note [Mingw .refptr mechanism]
| GotSymbolPtr -- ELF: foo@got
| GotSymbolOffset -- ELF: foo@gotoff
@@ -778,6 +806,10 @@ isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _) = True
isForeignLabel _lbl = False
+isForeignLabelUnknownPackage :: CLabel -> Bool
+isForeignLabelUnknownPackage (ForeignLabel _ ForeignLabelInUnknownPackage _) = True
+isForeignLabelUnknownPackage _lbl = False
+
-- | Whether label is a static closure label (can come from haskell or cmm)
isStaticClosureLabel :: CLabel -> Bool
-- Closure defined in haskell (.hs)
@@ -1308,9 +1340,9 @@ labelDynamic this_mod platform external_dynamic_refs lbl =
LocalBlockLabel _ -> False
- ForeignLabel _ source _ ->
- if os == OSMinGW32
- then case source of
+ ForeignLabel _ source _
+ | os == OSMinGW32 ->
+ case source of
-- Foreign label is in some un-named foreign package (or DLL).
ForeignLabelInExternalPackage -> True
@@ -1318,16 +1350,23 @@ labelDynamic this_mod platform external_dynamic_refs lbl =
-- source file currently being compiled.
ForeignLabelInThisPackage -> False
+ -- Foreign label is either in the same package or is in some
+ -- foreign package/DLL/DSO. Neither yes nor no is the correct
+ -- answer here, because on Windows these are a distinct case
+ -- that need special treatment in the code generator.
+ -- See Note [Mingw .refptr mechanism]
+ ForeignLabelInUnknownPackage -> True
+
-- Foreign label is in some named package.
-- When compiling in the "dyn" way, each package is to be
-- linked into its own DLL.
ForeignLabelInPackage pkgId ->
external_dynamic_refs && (this_unit /= pkgId)
- else -- On Mac OS X and on ELF platforms, false positives are OK,
- -- so we claim that all foreign imports come from dynamic
- -- libraries
- True
+ -- On Mac OS X and on ELF platforms, false positives are OK,
+ -- so we claim that all foreign imports come from dynamic
+ -- libraries
+ | otherwise -> True
CC_Label cc ->
external_dynamic_refs && not (ccFromThisModule cc this_mod)
@@ -1678,6 +1717,7 @@ instance Outputable ForeignLabelSource where
ForeignLabelInPackage pkgId -> parens $ text "package: " <> ppr pkgId
ForeignLabelInThisPackage -> parens $ text "this package"
ForeignLabelInExternalPackage -> parens $ text "external package"
+ ForeignLabelInUnknownPackage -> parens $ text "unknown package"
-- -----------------------------------------------------------------------------
-- Machine-dependent knowledge about labels.
@@ -1698,6 +1738,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
SymbolPtr -> char 'L' <> ppLbl <> text "$non_lazy_ptr"
GotSymbolPtr -> ppLbl <> text "@GOTPCREL"
GotSymbolOffset -> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
| platformArch platform == ArchAArch64 -> ppLbl
| otherwise -> panic "pprDynamicLinkerAsmLabel"
@@ -1710,8 +1751,9 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
OSMinGW32 ->
case dllInfo of
- SymbolPtr -> text "__imp_" <> ppLbl
- _ -> panic "pprDynamicLinkerAsmLabel"
+ SymbolPtr -> text "__imp_" <> ppLbl
+ DataRefPtr -> text ".refptr." <> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
_ -> panic "pprDynamicLinkerAsmLabel"
where
@@ -1738,6 +1780,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
GotSymbolPtr -> ppLbl <> text "@gotpcrel"
GotSymbolOffset -> ppLbl
SymbolPtr -> text ".LC_" <> ppLbl
+ _ -> panic "pprDynamicLinkerAsmLabel"
| platformArch platform == ArchPPC_64 ELF_V1
|| platformArch platform == ArchPPC_64 ELF_V2
@@ -1753,6 +1796,7 @@ pprDynamicLinkerAsmLabel !platform dllInfo ppLbl =
SymbolPtr -> text ".LC_" <> ppLbl
GotSymbolPtr -> ppLbl <> text "@got"
GotSymbolOffset -> ppLbl <> text "@gotoff"
+ _ -> panic "pprDynamicLinkerAsmLabel"
-- Figure out whether `symbol` may serve as an alias
-- to `target` within one compilation unit.
=====================================
compiler/GHC/CmmToAsm/PIC.hs
=====================================
@@ -152,6 +152,12 @@ cmmMakeDynamicReference config referenceKind lbl
AccessDirectly | ArchWasm32 <- platformArch platform ->
pure $ CmmLit $ CmmLabel lbl
+ -- See Note [Mingw .refptr mechanism]
+ AccessViaRefPtr -> do
+ let refPtr = mkDynamicLinkerLabel DataRefPtr lbl
+ addImport refPtr
+ return $ cmmLoadBWord platform (cmmMakePicReference config refPtr)
+
AccessDirectly -> case referenceKind of
-- for data, we might have to make some calculations:
DataReference -> return $ cmmMakePicReference config lbl
@@ -244,6 +250,7 @@ ncgLabelDynamic config = labelDynamic (ncgThisModule config)
data LabelAccessStyle
= AccessViaStub
| AccessViaSymbolPtr
+ | AccessViaRefPtr -- See Note [Mingw .refptr mechanism]
| AccessDirectly
howToAccessLabel :: NCGConfig -> Arch -> OS -> ReferenceKind -> CLabel -> LabelAccessStyle
@@ -271,6 +278,18 @@ howToAccessLabel :: NCGConfig -> Arch -> OS -> ReferenceKind -> CLabel -> LabelA
--
howToAccessLabel config _arch OSMinGW32 _kind lbl
+ -- If we have a data symbol where it is not known if it is in the same
+ -- PE or another PE, then we resort to the .refptr mechanism.
+ -- See Note [Mingw .refptr mechanism]
+ --
+ -- Note that we do this _even when_ not ncgExternalDynamicRefs, because
+ -- -fexternal-dynamic-refs is about Haskell code being built as DLLs.
+ -- But ForeignLabelInUnknownPackage is about where foreign/C symbols
+ -- come from, which can always be from external DLLs (or static libs).
+ | isForeignLabelUnknownPackage lbl
+ , not (isCFunctionLabel lbl)
+ = AccessViaRefPtr
+
-- Assume all symbols will be in the same PE, so just access them directly.
| not (ncgExternalDynamicRefs config)
= AccessDirectly
@@ -627,6 +646,18 @@ pprImportedSymbol config importedLbl = case (arch,os) of
text "\t.long" <+> ppr_lbl lbl ]
_ -> empty
+ -- See Note [Mingw .refptr mechanism]
+ (_, OSMinGW32) -> case dynamicLinkerLabelInfo importedLbl of
+ Just (DataRefPtr, lbl)
+ -> lines_ [
+ text "\t.section\t.rdata$.refptr." <> ppr_lbl lbl
+ <> text ",\"dr\",discard,.refptr." <> ppr_lbl lbl,
+ text "\t.p2align\t3",
+ text ".globl\t" <> text ".refptr." <> ppr_lbl lbl,
+ text ".refptr." <> ppr_lbl lbl <> char ':',
+ text "\t.quad" <+> ppr_lbl lbl ]
+ _ -> empty
+
-- ELF / Linux
--
-- In theory, we don't need to generate any stubs or symbol pointers
=====================================
compiler/GHC/StgToCmm/Lit.hs
=====================================
@@ -97,8 +97,7 @@ mkSimpleLit platform = \case
(LitNumber LitNumWord64 i) -> CmmInt i W64
(LitFloat r) -> CmmFloat r W32
(LitDouble r) -> CmmFloat r W64
- (LitLabel fs fod)
- -> let -- TODO: Literal labels might not actually be in the current package...
- labelSrc = ForeignLabelInThisPackage
- in CmmLabel (mkForeignLabel fs labelSrc fod)
- other -> pprPanic "mkSimpleLit" (ppr other)
+ (LitLabel fs fod) -> CmmLabel (mkForeignLabel fs labelSrc fod)
+ -- See Note [Mingw .refptr mechanism]
+ where labelSrc = ForeignLabelInUnknownPackage
+ other -> pprPanic "mkSimpleLit" (ppr other)
=====================================
hadrian/src/Builder.hs
=====================================
@@ -356,6 +356,10 @@ instance H.Builder Builder where
Ghc FindHsDependencies _ -> do
runGhcWithResponse path buildArgs buildInputs
+ Ghc LinkHs _ -> do
+ runGhcWithResponse path [ "-v" | verbosity >= Diagnostic ]
+ buildArgs
+
HsCpp -> captureStdout
Make dir -> cmd' buildOptions path ["-C", dir] buildArgs
=====================================
rts/Linker.c
=====================================
@@ -232,7 +232,7 @@ static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key,
static const char *
symbolTypeString (SymType type)
{
- switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN)) {
+ switch (type & ~(SYM_TYPE_DUP_DISCARD | SYM_TYPE_HIDDEN | SYM_TYPE_RTS_DEF)) {
case SYM_TYPE_CODE: return "code";
case SYM_TYPE_DATA: return "data";
case SYM_TYPE_INDIRECT_DATA: return "indirect-data";
@@ -270,6 +270,9 @@ int ghciInsertSymbolTable(
SymType type,
ObjectCode *owner)
{
+ /* mask out SYM_TYPE_RTS_DEF, see Note [RTS symbol exports] */
+ type &= ~SYM_TYPE_RTS_DEF;
+
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
if (!pinfo) /* new entry */
{
@@ -472,16 +475,7 @@ initLinker_ (int retain_cafs)
symhash = allocStrHashTable();
/* populate the symbol table with stuff from the RTS */
- IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
- for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
- IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
- if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
- symhash, sym->lbl, sym->addr,
- sym->strength, sym->type, NULL)) {
- barf("ghciInsertSymbolTable failed");
- }
- }
- IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+ initLinkerRtsSyms(symhash);
/* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
* that can be overrided by linking in an object with a corresponding
=====================================
rts/RtsSymbols.c
=====================================
@@ -9,6 +9,7 @@
#include "ghcplatform.h"
#include "Rts.h"
#include "RtsSymbols.h"
+#include "LinkerInternals.h"
#include "TopHandler.h"
#include "HsFFI.h"
@@ -50,6 +51,18 @@ extern char **environ;
/* -----------------------------------------------------------------------------
* Symbols to be inserted into the RTS symbol table.
+ *
+ * Note [Naming Scheme for Symbol Macros]
+ *
+ * SymI_*: symbol is internal to the RTS. It resides in an object
+ * file/library that is statically.
+ * SymE_*: symbol is external to the RTS library. It might be linked
+ * dynamically.
+ *
+ * Sym*_HasProto : the symbol prototype is imported in an include file
+ * or defined explicitly
+ * Sym*_NeedsProto: the symbol is undefined and we add a dummy
+ * default proto extern void sym(void);
*/
#define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
@@ -1127,12 +1140,21 @@ extern char **environ;
SymI_HasProto(hs_word2float64)
-/* entirely bogus claims about types of these symbols */
-#define SymI_NeedsProto(vvv) extern void vvv(void);
-#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
-#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
-#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
-#define SymE_HasProto(vvv) SymI_HasProto(vvv);
+/* Declare prototypes for the symbols that need it, so we can refer
+ * to them in the rtsSyms table below.
+ *
+ * In particular, for the external ones (SymE_*) we use the dllimport attribute
+ * to indicate that (on Windows) they come from external DLLs. This attribute
+ * is ignored on other platforms.
+ *
+ * The claims about the types of these symbols are entirely bogus.
+ */
+#define SymI_NeedsProto(vvv) extern void vvv(void);
+#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
+#define SymE_NeedsProto(vvv) extern __attribute__((dllimport)) void vvv(void);
+#define SymE_NeedsDataProto(vvv) extern __attribute__((dllimport)) StgWord vvv[];
+
+#define SymE_HasProto(vvv) /**/
#define SymI_HasProto(vvv) /**/
#define SymI_HasDataProto(vvv) /**/
#define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
@@ -1161,17 +1183,23 @@ RTS_SYMBOLS_PRIM
#undef SymE_NeedsProto
#undef SymE_NeedsDataProto
+/* See Note [Naming Scheme for Symbol Macros] */
+
#define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
+ (void*)(&(vvv)), STRENGTH_NORMAL, \
+ SYM_TYPE_CODE | SYM_TYPE_RTS_DEF },
#define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
+ (void*)(&(vvv)), STRENGTH_NORMAL, \
+ SYM_TYPE_DATA | SYM_TYPE_RTS_DEF },
#define SymE_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
#define SymE_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
-#define SymI_NeedsProto(vvv) SymI_HasProto(vvv)
-#define SymI_NeedsDataProto(vvv) SymI_HasDataProto(vvv)
+#define SymI_NeedsProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+ (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
+#define SymI_NeedsDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+ (void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_DATA },
#define SymE_NeedsProto(vvv) SymE_HasProto(vvv)
#define SymE_NeedsDataProto(vvv) SymE_HasDataProto(vvv)
@@ -1181,7 +1209,16 @@ RTS_SYMBOLS_PRIM
{ MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(xxx)), strength, ty },
-RtsSymbolVal rtsSyms[] = {
+
+/* Populate the symbol table with stuff from the RTS. */
+void initLinkerRtsSyms (StrHashTable *symhash) {
+
+ /* The address of data symbols with the dllimport attribute are not
+ * compile-time constants and so cannot be used in constant initialisers.
+ * For this reason, rtsSyms is a local variable within this function
+ * rather than a global constant (as it was historically).
+ */
+ const RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS
RTS_RET_SYMBOLS
RTS_POSIX_ONLY_SYMBOLS
@@ -1196,7 +1233,19 @@ RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS_PRIM
SymI_HasDataProto(nonmoving_write_barrier_enabled)
{ 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
-};
+ };
+
+ IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
+ for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
+ IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
+ if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
+ symhash, sym->lbl, sym->addr,
+ sym->strength, sym->type, NULL)) {
+ barf("ghciInsertSymbolTable failed");
+ }
+ }
+ IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+}
// Note [Extra RTS symbols]
=====================================
rts/RtsSymbols.h
=====================================
@@ -9,6 +9,7 @@
#pragma once
#include "ghcautoconf.h"
+#include "Hash.h"
#if defined(LEADING_UNDERSCORE)
#define MAYBE_LEADING_UNDERSCORE_STR(s) ("_" s)
@@ -21,8 +22,8 @@ typedef char SymbolName;
/* What kind of thing a symbol identifies. We need to know this to determine how
* to process overflowing relocations. See Note [Processing overflowed relocations].
- * This is bitfield however only the option SYM_TYPE_DUP_DISCARD can be combined
- * with the other values. */
+ * This is bitfield however only the option SYM_TYPE_DUP_DISCARD and
+ * SYM_TYPE_RTS_DEF can be combined with the other values. */
typedef enum _SymType {
SYM_TYPE_CODE = 1 << 0, /* the symbol is a function and can be relocated via a jump island */
SYM_TYPE_DATA = 1 << 1, /* the symbol is data */
@@ -31,8 +32,34 @@ typedef enum _SymType {
however if a duplicate is found with a mismatching
SymType then discard this one. */
SYM_TYPE_HIDDEN = 1 << 4, /* the symbol is hidden and should not be exported */
+ SYM_TYPE_RTS_DEF = 1 << 5, /* the symbol is defined in the RTS DSO */
} SymType;
+/* Note [RTS symbol exports]
+ * SymType and SymStrength are used by the RTS's internal (aka GHCi) linker.
+ * They're also used by the rtsSyms array, which is used to pre-populate the
+ * GHCi linker symbol table (see ghciInsertSymbolTable calls in initLinker_).
+ * The rtsSyms array has a secondary purpose: to be the source of truth for
+ * which symbols are supposed to be exported from the RTS, when the RTS is
+ * built as a shared object (i.e. .so, .dll), which is handled by the native
+ * system linker.
+ *
+ * This is related but different to the GHCi linker. The GHCi linker's symbol
+ * table is pre-populated with RTS exported symbols but also additional symbols
+ * from dependent libraries and a few platform specific symbols and hacks (see
+ * for example Note [Strong symbols], and Note [Symbols for MinGW's printf],
+ * Note [Extra RTS symbols]). The GHCi linker does not need to distinguish
+ * known symbols that are defined within the RTS from known symbols from other
+ * libs. All of them are available to resolve against.
+ *
+ * So to serve the secondary purpose, we use the SYM_TYPE_RTS_DEF flag, which
+ * we combine with the other flags (CODE, DATA etc). We arrange to ignore this
+ * flag when pre-populating the GHCi linker symbol table. But we make use of it
+ * to dump the symbols that are intended to be exported from the RTS. This can
+ * be used by the build system and native linker to limit the symbols exported
+ * from the RTS shared object. See utils/rts-sym/rts-sym.c
+ */
+
typedef enum _SymStrength {
STRENGTH_NORMAL,
STRENGTH_WEAK,
@@ -46,7 +73,7 @@ typedef struct _RtsSymbolVal {
SymType type;
} RtsSymbolVal;
-extern RtsSymbolVal rtsSyms[];
+void initLinkerRtsSyms (StrHashTable *symhash);
extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
=====================================
utils/rts-syms/rts-syms.c
=====================================
@@ -0,0 +1,97 @@
+/* A utility to export the symbol table of the RTS. The RTS has a built-in
+ * linker, and has a pre-populated table of known RTS symbols.
+ *
+ * This is used primarily to generate input files for linkers, to limit the
+ * symbols exported from the RTS to those we want to export.
+ *
+ * This utility can generate Windows .def files (for making DLLs), or GNU ld
+ * linker scripts (used by GNU ld and LLVM ld for .so libs). We also support
+ * a raw dump format for curiosity or debugging.
+ */
+
+#include "RtsSymbols.h"
+
+/* RtsSymbols.h is an internal header file.
+ * It defines a symbol table (reordered and simplified for clarity):
+
+extern RtsSymbolVal rtsSyms;
+
+typedef struct _RtsSymbolVal {
+ const SymbolName* lbl;
+ SymbolAddr* addr;
+ SymStrength strength;
+ SymType type;
+ } RtsSymbolVal;
+
+typedef enum _SymType {
+ SYM_TYPE_CODE,
+ SYM_TYPE_DATA,
+ SYM_TYPE_INDIRECT_DATA,
+ SYM_TYPE_DUP_DISCARD,
+ SYM_TYPE_HIDDEN,
+ } SymType;
+
+ typedef enum _SymStrength {
+ STRENGTH_NORMAL,
+ STRENGTH_WEAK,
+ STRENGTH_STRONG,
+ } SymStrength;
+
+ */
+
+#include
participants (1)
-
Duncan Coutts (@dcoutts)