Mail Archives: djgpp/2015/10/04/08:28:43
Am 04.10.2015 12:39, schrieb Juan Manuel Guerrero (juan DOT guerrero AT gmx DOT de) [via djgpp AT delorie DOT com]:
[snip]
> Below is a patch that will implement ref-counting for implicitly loaded modules
> by other ones. Please not that this ref-counting only works for dlopen/dlclose.
> There may be other loading mechanisms that suffer from the same issue and that
> will not be fixed by this modification.
> The patch is intended for the main branch but should work on v2_05_1 as well.
[snip]
There was a typo in the previously posted patch. Please use this one.
Regards,
Juan M. Guerrero
2015-10-03 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* djgpp/src/libc/dxe/dlopen.c: Added reference counting support for implicitly loaded DXE modules by dlopen.
diff -aprNU5 djgpp.orig/src/libc/dxe/dlopen.c djgpp/src/libc/dxe/dlopen.c
--- djgpp.orig/src/libc/dxe/dlopen.c 2015-10-04 10:27:26 -29907
+++ djgpp/src/libc/dxe/dlopen.c 2015-10-04 13:58:56 -29907
@@ -36,14 +36,16 @@
#ifndef ELOOP
#define ELOOP EMLINK
#endif
+#define __DEBUG_DXE3__ 0 /* Prints struct __dxe_handle members. Always commited as 0. */
+
/* private stack */
-typedef struct stk_node {
+typedef struct __stk_node {
const char *name;
- struct stk_node *next;
+ struct __stk_node *next;
} stk_node;
/* Exported symbols table entry */
typedef struct
{
@@ -57,22 +59,29 @@ typedef struct
unsigned short n_rel_relocs;
unsigned short n_abs_relocs;
char name [1]; /* expanded as needed */
} __attribute__((packed)) unres_table_entry;
+/* This is a linked list of implicitly loaded dxe modules. */
+typedef struct __linked_list {
+ struct __dxe_handle *handle; /* Pointer to next implicitly open module by this module */
+ struct __linked_list *next; /* Next entry in list */
+} dxe_handle_list;
+
/* This is the private dxe_h structure */
typedef struct __dxe_handle
{
- struct __dxe_handle *next; /* Pointer to next module in chain */
- char fname[FILENAME_MAX]; /* Full module pathname */
- int mode; /* Module open mode */
- int inuse; /* In-use counter */
- int n_exp_syms; /* Number of entries in export table */
- exp_table_entry **exp_table; /* Exported symbols table */
- char *header; /* The resident portion of header */
- char *section; /* code+data+bss section */
- long _fini; /* finalization */
+ struct __dxe_handle *next; /* Pointer to next module in chain */
+ char fname[FILENAME_MAX]; /* Full module pathname */
+ int mode; /* Module open mode */
+ int in_use; /* In-use counter */
+ int n_exp_syms; /* Number of entries in export table */
+ exp_table_entry **exp_table; /* Exported symbols table */
+ char *header; /* The resident portion of header */
+ char *section; /* code+data+bss section */
+ long _fini; /* Finalization */
+ dxe_handle_list *implicit_handle_list; /* Linked list of implicitly open module by this module or NULL */
} dxe_handle, *dxe_h;
/* Last-resort symbol resolver */
void *(*_dlsymresolver) (const char *symname) = NULL;
/* Last-error unresolved symbol count */
@@ -110,10 +119,12 @@ void *dlopen(const char *filename, int m
char *discardable;
stk_node *node;
static stk_node *stk_top = NULL;
+ dxe_handle_list *implicitly_open_handle_list;
+
#ifndef __GNUC__
static int cleanup = 0;
#endif
_dl_unresolved_count = 0;
@@ -180,11 +191,11 @@ found:
/* Look through the loaded modules list */
for (cur = dxe_chain; cur; cur = cur->next)
if (!strcmp(realfn, cur->fname))
{
- cur->inuse++;
+ cur->in_use++;
return cur;
}
fh = OPEN(filename, OPENFLAGS);
if (fh < 0) return NULL;
@@ -202,13 +213,14 @@ found:
return NULL;
}
/* O.k, fill the module handle structure */
strcpy(dxe.fname, realfn);
- dxe.inuse = 1;
+ dxe.in_use = 1;
dxe.mode = mode;
dxe.n_exp_syms = dxehdr.n_exp_syms;
+ dxe.implicit_handle_list = NULL;
/* Read DXE tables and the data section */
hdrsize = dxehdr.symbol_offset - sizeof(dxehdr);
discardsize = dxehdr.dep_size + dxehdr.unres_size + dxehdr.nrelocs * sizeof(long);
if ((dxe.header = malloc(hdrsize + dxehdr.sec_size)) == NULL)
@@ -240,11 +252,11 @@ found:
/* Fill the unfilled portion of code+data+bss segment with zeros */
memset(dxe.section + dxehdr.sec_f_size, 0, dxehdr.sec_size - dxehdr.sec_f_size);
/* Load the dependencies */
scan = discardable;
- for (i = 0; i < dxehdr.n_deps; i++)
+ for (implicitly_open_handle_list = NULL, i = 0; i < dxehdr.n_deps; i++)
{
stk_node tmp;
tmp.name = realfn;
tmp.next = stk_top;
stk_top = &tmp;
@@ -252,14 +264,35 @@ found:
if (dlopen(scan, RTLD_GLOBAL) == NULL)
{
stk_top = tmp.next;
goto unrecoverable;
}
+ else
+ {
+ dxe_handle_list *next_handle_list;
+
+ stk_top = tmp.next;
- stk_top = tmp.next;
+ scan = strchr(scan, 0) + 1;
- scan = strchr(scan, 0) + 1;
+ /* Register all implicitly open modules by this one. */
+ if ((next_handle_list = malloc(sizeof(dxe_handle_list))) == NULL)
+ {
+ errno = ENOMEM;
+ goto midwayerror;
+ }
+ next_handle_list->handle = dxe_chain;
+ next_handle_list->next = NULL;
+
+ if (implicitly_open_handle_list)
+ {
+ implicitly_open_handle_list->next = next_handle_list;
+ implicitly_open_handle_list = implicitly_open_handle_list->next;
+ }
+ else
+ dxe.implicit_handle_list = implicitly_open_handle_list = next_handle_list;
+ }
}
/* Allright, now we're ready to resolve all unresolved symbols */
_dl_unresolved_count = dxehdr.n_unres_syms;
_dl_unresolved_symbol[0] = 0;
@@ -325,10 +358,50 @@ found:
errno = ENOMEM;
goto midwayerror;
}
memcpy(dxe_chain, &dxe, sizeof(dxe_handle));
+#if defined(__DEBUG_DXE3__) && __DEBUG_DXE3__ == 1
+ {
+ FILE *f = fopen("c:/tmp/dxe_chain.txt", "a");
+
+ if (f)
+ {
+ fprintf(f, "dxe_chain : 0x%p\n"
+ " next : 0x%p\n"
+ " fname : %s\n"
+ " mode : %s\n"
+ " in_use : %d\n"
+ " n_exp_syms : %d\n"
+ " exp_table : 0x%p\n",
+ dxe_chain, dxe_chain->next, dxe_chain->fname,
+ dxe_chain->mode == RTLD_LAZY ? "RTLD_LAZY" :
+ dxe_chain->mode == RTLD_NOW ? "RTLD_NOW" :
+ dxe_chain->mode == RTLD_LOCAL ? "RTLD_LOCAL" :
+ dxe_chain->mode == RTLD_GLOBAL ? "RTLD_GLOBAL" : "unknown",
+ dxe_chain->in_use, dxe_chain->n_exp_syms, dxe_chain->exp_table);
+ for (i = 0; i < dxe_chain->n_exp_syms; i++)
+ fprintf(f, " exp_table[%d]->offset : %ld\n"
+ " exp_table[%d]->name : %s\n",
+ i, dxe_chain->exp_table[i]->offset, i, dxe_chain->exp_table[i]->name);
+ fprintf(f, " header : 0x%p\n"
+ " section : 0x%p\n"
+ " _fini : %ld\n",
+ dxe_chain->header, dxe_chain->section, dxe_chain->_fini);
+ if ((implicitly_open_handle_list = dxe_chain->implicit_handle_list))
+ for (; implicitly_open_handle_list; implicitly_open_handle_list = implicitly_open_handle_list->next)
+ fprintf(f, " implicitly_open_handle_list: 0x%p\n"
+ " handle : 0x%p\n"
+ " handle->fname : %s\n\n",
+ implicitly_open_handle_list, implicitly_open_handle_list->handle, implicitly_open_handle_list->handle->fname);
+ else
+ fprintf(f, " implicitly_open_handle_list: 0x00000000\n\n");
+ fclose(f);
+ }
+ }
+#endif
+
#ifndef __GNUC__
if (!cleanup)
{
cleanup = !0;
atexit(_closeall);
@@ -348,11 +421,11 @@ midwayerror:
int dlclose(void *dxe)
{
if (!dxe)
return -1;
- if (--((dxe_h)dxe)->inuse)
+ if (--((dxe_h)dxe)->in_use)
return 0;
/* finalization */
if (((dxe_h)dxe)->_fini != -1)
((void (*) (void))(((dxe_h)dxe)->_fini + (long)((dxe_h)dxe)->section))();
@@ -361,10 +434,21 @@ int dlclose(void *dxe)
{
dxe_h *cur;
for (cur = &dxe_chain; *cur; cur = &(*cur)->next)
if (*cur == dxe)
{
+ /* Un-register all implicitly loaded modules by this module. */
+ dxe_handle_list *implicitly_open_handle_list = (*cur)->implicit_handle_list;
+ while (implicitly_open_handle_list)
+ {
+ dxe_handle_list *next_handle_list = implicitly_open_handle_list->next;
+
+ dlclose(implicitly_open_handle_list->handle);
+ free(implicitly_open_handle_list);
+ implicitly_open_handle_list = next_handle_list;
+ }
+
*cur = ((dxe_h)dxe)->next;
break;
}
}
- Raw text -