Mail Archives: djgpp-workers/2011/12/20/16:58:17
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 -