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

Reply via email to