delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2011/12/20/16:58:17

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1/VSrIjyMnVWul2MI2P0Qdxp1NkI22kC4Lrkl4PAS
EPsdli5iNv1jI4
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
To: djgpp-workers AT delorie DOT com
Subject: Re: dxe and gcc 4.6.1 difficulties.
Date: Tue, 20 Dec 2011 22:53:56 +0100
User-Agent: KMail/1.9.10
References: <201108141841 DOT 15711 DOT juan DOT guerrero AT gmx DOT de> <201112191706 DOT pBJH6O0l014645 AT envy DOT delorie DOT com> <4EF02233 DOT 4070004 AT iki DOT fi>
In-Reply-To: <4EF02233.4070004@iki.fi>
MIME-Version: 1.0
Message-Id: <201112202253.56277.juan.guerrero@gmx.de>
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

Am Dienstag, 20. Dezember 2011 schrieb Andris Pavenis:
> On 12/19/2011 06:06 PM, DJ Delorie wrote:
> >> Is there any reason why there is no __deregister_frame_info  in libc?
> > I don't know, perhaps it isn't needed?
> Or maybe it was not needed when using earlier GCC versions before 4.6.
> I would suggest to add it and see whether problems with using DXE
> goes away (when using gcc-4.6). I have not used DXE myself, so I do not
> have earlier experience with them
> 
> Andris



Starting with gcc 4.5.X gcc generates .eh_frame in the objects files by default.
DXE has 3 initX.S files.  Depending if ctor, frame or ctor and frame are defined
in the object file one of those is used.  These means that they generate the
calls to __[de]register_frame_info.  There is probably no way to resolve those
symbols at runtime so I have resolved them when the .dxe file is created by
the linker.  To this purpose I have allowed to evaluate the LD_PRELOAD environment
variable allowing to specifiy an library that will be used to resolve the
unresolved symbols when linking.  First I tried to use libgcc.a.  This library
provide the needed symbols but introduce a lot of others that will appear as
unresolved at runtime.  The better solution was to provide a  __deregister_frame_info
in libc.a.  If only __[de]register_frame_info shall be resolved, the user does
not need to set LD_PRELOAD at all, because libc.a is used anyway to resolve
those symbols.  If the compiler does not generate any frames, then all these
changes have no impact.
For libc.a I have added an dummy __deregister_frame_info implementation.

Suggestions, objections, comments are welcome.


Regards,
Juan M. Guerrero



2011-12-20  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

	* src/dxe/dxe3gen.c:  If object file has frames honor the LD_PRELOAD
	environment variable to allow to link with a library that will resolve
	unresolved variables introduced by frames defined in the file.

	* src/libc/crt0/rfinfo.c:  Define __deregister_frame_info.





diff -aprNU5 djgpp.orig/src/dxe/dxe3gen.c djgpp/src/dxe/dxe3gen.c
--- djgpp.orig/src/dxe/dxe3gen.c	2011-12-20 21:22:38 +0000
+++ djgpp/src/dxe/dxe3gen.c	2011-12-20 21:34:14 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 Borca Daniel <dborca AT yahoo DOT com>
  * Copyright (C) 2000 Andrew Zabolotny <bit AT eltech DOT ru>
  * Partly based on work by Charles Sandmann and DJ Delorie.
  * Usage of this library is not restricted in any way.  
@@ -38,10 +39,13 @@
 #define TEMP_O_FILE	TEMP_BASE".o"
 #define TEMP_S_FILE	TEMP_BASE".s"
 
 #define VALID_RELOC(r) ((r.r_type != RELOC_REL32) && (r.r_symndx != (ULONG32)-1))
 
+#define NUMBER_OF_LINKER_ARGS     10
+#define NUMBER_OF_PRELOADED_LIBS  2
+
 typedef enum {
         FALSE = 0,
         TRUE = !FALSE
 } BOOL;
 
@@ -123,10 +127,31 @@ static struct {
   NULL
 };
 
 
 
+/* Desc: replaces backslash with slash in a path
+ *
+ * In  : path string
+ * Out : path string
+ *
+ * Note: -
+ */
+static void canonicalize_path(char *path)
+{
+  if (path)
+  {
+    char *scan = path;
+
+    for (; *scan; scan++)
+      if (*scan == '\\')
+        *scan = '/';
+  }
+}
+
+
+
 /* Desc: remove temporary files
  *
  * In  : -
  * Out : -
  *
@@ -229,20 +254,21 @@ static void display_help (void)
 static void process_args (int argc, char *argv[], const char *new_argv[])
 {
  static char libdir[FILENAME_MAX];
  char *p;
  int i;
- int new_argc = 10;
+ int new_argc = NUMBER_OF_LINKER_ARGS;
 
  p = getenv("DXE_LD_LIBRARY_PATH");
  if (p)
     strcpy(libdir, p);
  else {
     p = getenv("DJDIR");
     if (p) {
        strcpy(libdir, p);
        strcat(libdir, "/lib");
+       canonicalize_path(libdir);
     } else {
        fprintf(stderr, "Error: neither DXE_LD_LIBRARY_PATH nor DJDIR are set in environment\n");
        exit(1);
     }
  }
@@ -335,11 +361,11 @@ static void process_args (int argc, char
            new_argv[new_argc++] = argv[i];
            dot = strrchr(argv[i], '.');
            if (dot) {
               if (!strcasecmp(dot, ".o") || !strcasecmp(dot, ".a")) {
                  opt.objcount++;
-              } else if (!strcasecmp(dot, ".dxe")) {
+              } else if (!strcasecmp(dot, ".dxe") || !strcasecmp(dot, ".so")) {
                  opt.dxefile = argv[i];
               }
            }
         }
     }
@@ -452,10 +478,12 @@ static FILE *run_ld (const char *argv[],
        init = (first_ctor != last_ctor) ? 1 : 0;
        fini = (first_dtor != last_dtor) ? 1 : 0;
     }
 
     if ((init > 0) || (fini > 0)) {
+       char *p, ld_preload_lib[FILENAME_MAX];
+
        fclose(f);
 
        for (i = 0; argv[i] != NULL; i++)
          ;
 
@@ -469,10 +497,25 @@ static FILE *run_ld (const char *argv[],
           f = fopen(TEMP_BASE"f.o", "wb");
           fwrite(finis[fini - 1].data, finis[fini - 1].size, 1, f);
           fclose(f);
           argv[i++] = TEMP_BASE"f.o";
        }
+
+       /*  Append the library defined by LD_PRELOAD
+        *  and also libc.  This shall allow to
+        *  resolve certain symbols introduced
+        *  by a defined EH frame and by other
+        *  frames.
+        */
+       p = getenv("LD_PRELOAD");
+       if (p)
+       {
+         strcpy(ld_preload_lib, p);
+         canonicalize_path(ld_preload_lib);
+         argv[i++] = ld_preload_lib;
+       }
+       argv[i++] = "/dev/env/DJDIR/lib/libc.a";  /*  libc will resolve [de]register_frame_* symbols.  */
        argv[i] = NULL;
 
        rv = myspawn(argv);
 
        if (init > 0) {
@@ -1112,17 +1155,18 @@ int main (int argc, char **argv)
  const char **new_argv;
 
  progname = argv[0];
  /* Prepare the command line for ld */
  new_argv = (const char **)malloc((argc - 1 + 11 + 2) * sizeof(char *));
+ new_argv = (const char **)malloc((argc - 1 + NUMBER_OF_LINKER_ARGS + NUMBER_OF_PRELOADED_LIBS + 2 + 1) * sizeof(char *));
  process_args(argc, argv, new_argv);
 
  if (opt.showdep || opt.showexp || opt.showunres) {
     for (i = 1; i < argc; i++) {
         if (argv[i][0] != '-') {
            char *dot = strchr(argv[i], '.');
-           if (dot && !strcasecmp(dot, ".dxe")) {
+           if (dot && (!strcasecmp(dot, ".dxe") || !strcasecmp(dot, ".so"))) {
               if ((rv = show_symbols(argv[i])) != 0) {
                  return rv;
               }
            }
         }
diff -aprNU5 djgpp.orig/src/libc/crt0/rfinfo.c djgpp/src/libc/crt0/rfinfo.c
--- djgpp.orig/src/libc/crt0/rfinfo.c	2011-12-20 21:22:38 +0000
+++ djgpp/src/libc/crt0/rfinfo.c	2011-12-20 21:25:36 +0000
@@ -1,7 +1,14 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
-void __register_frame_info(void *begin __attribute__((unused)),
-                           void *object __attribute__((unused)));
-void __register_frame_info(void *begin __attribute__((unused)),
-                           void *object __attribute__((unused)))
+void __register_frame_info(const void *begin __attribute__((unused)),
+                           const void *object __attribute__((unused)));
+void __register_frame_info(const void *begin __attribute__((unused)),
+                           const void *object __attribute__((unused)))
 {
 }
+
+
+void __deregister_frame_info(const void *begin __attribute__((unused)));
+void __deregister_frame_info(const void *begin __attribute__((unused)))
+ {
+ }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019