diff options
author | Austin Seipp <austin@well-typed.com> | 2014-06-17 17:09:02 -0500 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2014-06-17 17:09:02 -0500 |
commit | 559ae1e8b6e0229070d371cb90b23655b70e1b77 (patch) | |
tree | 4b67372bca6628d29c3dc8f76d8c5371e3e720a3 | |
parent | 32b4bf33989bdda4dffed1866f7a61a7da4ca275 (diff) | |
download | haskell-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.lhs | 72 | ||||
-rw-r--r-- | rts/Linker.c | 43 |
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); |