Fix GHC ticket 2615 (linker scripts in .so files)
Simon Marlow
marlowsd at gmail.com
Wed Dec 2 11:50:21 EST 2009
On 01/12/2009 06:49, Howard B. Golden wrote:
> Mon Nov 30 22:12:34 PST 2009 howard_b_golden at yahoo.com
> * 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
More information about the Cvs-ghc
mailing list