On 01/12/2009 06:49, Howard B. Golden wrote:
Mon Nov 30 22:12:34 PST 2009 [email protected]
* Fix GHC ticket 2615 (linker scripts in .so files)
This patch only applies to systems that use ELF format files.
The patch modifies the addDLL function so that it recognizes
"invalid ELF header" errors. If these occur, the file that was opened
is scanned for a linker script GROUP ( ... ) directive. If found,
the first file inside the GROUP ( ... ) will be sent to dlopen.
Any errors reported by dlopen then will be reported to the caller.
Thanks Howard. I think the patch could do with a round of tweaks before
being pushed, comments below.
+#define MIN(a,b) (((a)< (b)) ? (a) : (b))
+
See stg_min() in Rts.h.
# define OBJFORMAT_ELF
+# include<regex.h>
Can we rely on the availability of regex.h and POSIX regexes? Does this
need a configure test?
void
hunk ./rts/Linker.c 1111
initLinker( void )
{
RtsSymbolVal *sym;
+ int compileResult;
/* Make initLinker idempotent, so we can call it
before evey relevant operation; that means we
hunk ./rts/Linker.c 1138
# else
dl_prog_handle = dlopen(NULL, RTLD_LAZY);
# endif /* RTLD_DEFAULT */
+ compileResult = regcomp(&re_invalid,
+ "(/[^ \\t()]+\\.so[^ \\t():]*):[ \\t]*invalid ELF header",
+ REG_EXTENDED);
+ ASSERT( compileResult == 0 );
+ compileResult = regcomp(&re_realso,
+ "GROUP *\\( *(([^ \\)])+)",
+ REG_EXTENDED);
+ ASSERT( compileResult == 0 );
+ atexit(initLinkerCleanup);
We don't generally use atexit() in the RTS, all the cleanup has to be
done by hs_exit(). Typically each subsystem has an exitFoo() or
freeFoo() function called by hs_exit().
+ errmsg = NULL;
if (hdl == NULL) {
/* dlopen failed; return a ptr to the error msg. */
errmsg = dlerror();
hunk ./rts/Linker.c 1227
if (errmsg == NULL) errmsg = "addDLL: unknown error";
- return errmsg;
- } else {
+ }
+ return errmsg;
+}
+# endif
+
+const char *
+addDLL( char *dll_name )
+{
+# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
+ /* ------------------- ELF DLL loader ------------------- */
+
+#define NMATCH 2
+ regmatch_t match[NMATCH];
+ char *errmsg;
+ FILE* fp;
+ size_t match_length;
+#define MAXLINE 1000
+ char line[MAXLINE];
+
+ initLinker();
+
+ debugBelch("addDLL: dll_name = '%s'\n", dll_name);
+ errmsg = internal_dlopen(dll_name);
+
+ if (errmsg == NULL) {
return NULL;
}
hunk ./rts/Linker.c 1254
- /*NOTREACHED*/
+
+ // see if the error message is due to an invalid ELF header
+
+ debugBelch("errmsg = '%s'\n", errmsg);
I think you left some debug output in here. Suggest protecting it with
IF_DEBUG(linker, ...).
Also I suggest adding a comment referring to the ticket number, and an
brief description of the problem and solution.
Cheers,
Simon
_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc