summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2014-06-17 17:09:02 -0500
committerAustin Seipp <austin@well-typed.com>2014-06-17 17:09:02 -0500
commit559ae1e8b6e0229070d371cb90b23655b70e1b77 (patch)
tree4b67372bca6628d29c3dc8f76d8c5371e3e720a3
parent32b4bf33989bdda4dffed1866f7a61a7da4ca275 (diff)
downloadhaskell-559ae1e8b6e0229070d371cb90b23655b70e1b77.tar.gz
Revert "Fix obscure problem with using the system linker (#8935)"
This reverts commit 72bd832eb87975c504654a65f9c88daaa478f677. Signed-off-by: Austin Seipp <austin@well-typed.com>
-rw-r--r--compiler/ghci/Linker.lhs72
-rw-r--r--rts/Linker.c43
2 files changed, 32 insertions, 83 deletions
diff --git a/compiler/ghci/Linker.lhs b/compiler/ghci/Linker.lhs
index 78728e1e14..274f2fbd44 100644
--- a/compiler/ghci/Linker.lhs
+++ b/compiler/ghci/Linker.lhs
@@ -123,12 +123,8 @@ data PersistentLinkerState
-- The currently-loaded packages; always object code
-- Held, as usual, in dependency order; though I am not sure if
-- that is really important
- pkgs_loaded :: ![PackageId],
-
- -- we need to remember the name of the last temporary DLL/.so
- -- so we can link it
- last_temp_so :: !(Maybe FilePath)
- }
+ pkgs_loaded :: ![PackageId]
+ }
emptyPLS :: DynFlags -> PersistentLinkerState
emptyPLS _ = PersistentLinkerState {
@@ -136,8 +132,7 @@ emptyPLS _ = PersistentLinkerState {
itbl_env = emptyNameEnv,
pkgs_loaded = init_pkgs,
bcos_loaded = [],
- objs_loaded = [],
- last_temp_so = Nothing }
+ objs_loaded = [] }
-- Packages that don't need loading, because the compiler
-- shares them with the interpreted program.
@@ -319,14 +314,14 @@ reallyInitDynLinker dflags =
; if null cmdline_lib_specs then return pls
else do
- { pls1 <- foldM (preloadLib dflags lib_paths framework_paths) pls cmdline_lib_specs
+ { mapM_ (preloadLib dflags lib_paths framework_paths) cmdline_lib_specs
; maybePutStr dflags "final link ... "
; ok <- resolveObjs
; if succeeded ok then maybePutStrLn dflags "done"
else throwGhcExceptionIO (ProgramError "linking extra libraries/objects failed")
- ; return pls1
+ ; return pls
}}
@@ -365,21 +360,19 @@ classifyLdInput dflags f
return Nothing
where platform = targetPlatform dflags
-preloadLib :: DynFlags -> [String] -> [String] -> PersistentLinkerState -> LibrarySpec -> IO (PersistentLinkerState)
-preloadLib dflags lib_paths framework_paths pls lib_spec
+preloadLib :: DynFlags -> [String] -> [String] -> LibrarySpec -> IO ()
+preloadLib dflags lib_paths framework_paths lib_spec
= do maybePutStr dflags ("Loading object " ++ showLS lib_spec ++ " ... ")
case lib_spec of
Object static_ish
- -> do (b, pls1) <- preload_static lib_paths static_ish
+ -> do b <- preload_static lib_paths static_ish
maybePutStrLn dflags (if b then "done"
else "not found")
- return pls1
Archive static_ish
-> do b <- preload_static_archive lib_paths static_ish
maybePutStrLn dflags (if b then "done"
else "not found")
- return pls
DLL dll_unadorned
-> do maybe_errstr <- loadDLL (mkSOName platform dll_unadorned)
@@ -395,14 +388,12 @@ preloadLib dflags lib_paths framework_paths pls lib_spec
case err2 of
Nothing -> maybePutStrLn dflags "done"
Just _ -> preloadFailed mm lib_paths lib_spec
- return pls
DLLPath dll_path
-> do maybe_errstr <- loadDLL dll_path
case maybe_errstr of
Nothing -> maybePutStrLn dflags "done"
Just mm -> preloadFailed mm lib_paths lib_spec
- return pls
Framework framework ->
if platformUsesFrameworks (targetPlatform dflags)
@@ -410,7 +401,6 @@ preloadLib dflags lib_paths framework_paths pls lib_spec
case maybe_errstr of
Nothing -> maybePutStrLn dflags "done"
Just mm -> preloadFailed mm framework_paths lib_spec
- return pls
else panic "preloadLib Framework"
where
@@ -430,13 +420,11 @@ preloadLib dflags lib_paths framework_paths pls lib_spec
-- Not interested in the paths in the static case.
preload_static _paths name
= do b <- doesFileExist name
- if not b then return (False, pls)
- else if dynamicGhc
- then do pls1 <- dynLoadObjs dflags pls [name]
- return (True, pls1)
- else do loadObj name
- return (True, pls)
-
+ if not b then return False
+ else do if dynamicGhc
+ then dynLoadObjs dflags [name]
+ else loadObj name
+ return True
preload_static_archive _paths name
= do b <- doesFileExist name
if not b then return False
@@ -803,8 +791,8 @@ dynLinkObjs dflags pls objs = do
wanted_objs = map nameOfObject unlinkeds
if dynamicGhc
- then do pls2 <- dynLoadObjs dflags pls1 wanted_objs
- return (pls2, Succeeded)
+ then do dynLoadObjs dflags wanted_objs
+ return (pls1, Succeeded)
else do mapM_ loadObj wanted_objs
-- Link them all together
@@ -818,11 +806,9 @@ dynLinkObjs dflags pls objs = do
pls2 <- unload_wkr dflags [] pls1
return (pls2, Failed)
-
-dynLoadObjs :: DynFlags -> PersistentLinkerState -> [FilePath]
- -> IO PersistentLinkerState
-dynLoadObjs _ pls [] = return pls
-dynLoadObjs dflags pls objs = do
+dynLoadObjs :: DynFlags -> [FilePath] -> IO ()
+dynLoadObjs _ [] = return ()
+dynLoadObjs dflags objs = do
let platform = targetPlatform dflags
soFile <- newTempName dflags (soExt platform)
let -- When running TH for a non-dynamic way, we still need to make
@@ -830,22 +816,10 @@ dynLoadObjs dflags pls objs = do
-- Opt_Static off
dflags1 = gopt_unset dflags Opt_Static
dflags2 = dflags1 {
- -- We don't want the original ldInputs in
- -- (they're already linked in), but we do want
- -- to link against the previous dynLoadObjs
- -- library if there was one, so that the linker
- -- can resolve dependencies when it loads this
- -- library.
- ldInputs =
- case last_temp_so pls of
- Nothing -> []
- Just so ->
- let (lp, l) = splitFileName so in
- [ Option ("-L" ++ lp)
- , Option ("-Wl,-rpath")
- , Option ("-Wl," ++ lp)
- , Option ("-l:" ++ l)
- ],
+ -- We don't want to link the ldInputs in; we'll
+ -- be calling dynLoadObjs with any objects that
+ -- need to be linked.
+ ldInputs = [],
-- Even if we're e.g. profiling, we still want
-- the vanilla dynamic libraries, so we set the
-- ways / build tag to be just WayDyn.
@@ -857,7 +831,7 @@ dynLoadObjs dflags pls objs = do
consIORef (filesToNotIntermediateClean dflags) soFile
m <- loadDLL soFile
case m of
- Nothing -> return pls { last_temp_so = Just soFile }
+ Nothing -> return ()
Just err -> panic ("Loading temp shared object failed: " ++ err)
rmDupLinkables :: [Linkable] -- Already loaded
diff --git a/rts/Linker.c b/rts/Linker.c
index 62bdf73241..47b4008386 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1776,7 +1776,7 @@ internal_dlopen(const char *dll_name)
// (see POSIX also)
ACQUIRE_LOCK(&dl_mutex);
- hdl = dlopen(dll_name, RTLD_LAZY|RTLD_LOCAL); /* see Note [RTLD_LOCAL] */
+ hdl = dlopen(dll_name, RTLD_LAZY | RTLD_GLOBAL);
errmsg = NULL;
if (hdl == NULL) {
@@ -1786,12 +1786,11 @@ internal_dlopen(const char *dll_name)
errmsg_copy = stgMallocBytes(strlen(errmsg)+1, "addDLL");
strcpy(errmsg_copy, errmsg);
errmsg = errmsg_copy;
- } else {
- o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL");
- o_so->handle = hdl;
- o_so->next = openedSOs;
- openedSOs = o_so;
}
+ o_so = stgMallocBytes(sizeof(OpenedSO), "addDLL");
+ o_so->handle = hdl;
+ o_so->next = openedSOs;
+ openedSOs = o_so;
RELEASE_LOCK(&dl_mutex);
//--------------- End critical section -------------------
@@ -1799,39 +1798,14 @@ internal_dlopen(const char *dll_name)
return errmsg;
}
-/*
- Note [RTLD_LOCAL]
-
- In GHCi we want to be able to override previous .so's with newly
- loaded .so's when we recompile something. This further implies that
- when we look up a symbol in internal_dlsym() we have to iterate
- through the loaded libraries (in order from most recently loaded to
- oldest) looking up the symbol in each one until we find it.
-
- However, this can cause problems for some symbols that are copied
- by the linker into the executable image at runtime - see #8935 for a
- lengthy discussion. To solve that problem we need to look up
- symbols in the main executable *first*, before attempting to look
- them up in the loaded .so's. But in order to make that work, we
- have to always call dlopen with RTLD_LOCAL, so that the loaded
- libraries don't populate the global symbol table.
-*/
-
static void *
-internal_dlsym(const char *symbol) {
+internal_dlsym(void *hdl, const char *symbol) {
OpenedSO* o_so;
void *v;
// We acquire dl_mutex as concurrent dl* calls may alter dlerror
ACQUIRE_LOCK(&dl_mutex);
dlerror();
- // look in program first
- v = dlsym(dl_prog_handle, symbol);
- if (dlerror() == NULL) {
- RELEASE_LOCK(&dl_mutex);
- return v;
- }
-
for (o_so = openedSOs; o_so != NULL; o_so = o_so->next) {
v = dlsym(o_so->handle, symbol);
if (dlerror() == NULL) {
@@ -1839,6 +1813,7 @@ internal_dlsym(const char *symbol) {
return v;
}
}
+ v = dlsym(hdl, symbol);
RELEASE_LOCK(&dl_mutex);
return v;
}
@@ -2006,7 +1981,7 @@ lookupSymbol( char *lbl )
if (!ghciLookupSymbolTable(symhash, lbl, &val)) {
IF_DEBUG(linker, debugBelch("lookupSymbol: symbol not found\n"));
# if defined(OBJFORMAT_ELF)
- return internal_dlsym(lbl);
+ return internal_dlsym(dl_prog_handle, lbl);
# elif defined(OBJFORMAT_MACHO)
# if HAVE_DLFCN_H
/* On OS X 10.3 and later, we use dlsym instead of the old legacy
@@ -2020,7 +1995,7 @@ lookupSymbol( char *lbl )
*/
IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
ASSERT(lbl[0] == '_');
- return internal_dlsym(lbl + 1);
+ return internal_dlsym(dl_prog_handle, lbl + 1);
# else
if (NSIsSymbolNameDefined(lbl)) {
NSSymbol symbol = NSLookupAndBindSymbol(lbl);