summaryrefslogtreecommitdiff
path: root/dln.c
diff options
context:
space:
mode:
Diffstat (limited to 'dln.c')
-rw-r--r--dln.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/dln.c b/dln.c
index 76e0785a58..3f96dd3199 100644
--- a/dln.c
+++ b/dln.c
@@ -56,9 +56,6 @@ void *xrealloc();
#endif
#ifndef NT
-# ifndef strdup
-char *strdup();
-# endif
char *getenv();
#endif
@@ -1155,6 +1152,35 @@ dln_strerror()
#if defined(_AIX)
+static void *
+aix_findmain()
+{
+ struct ld_info *lp;
+ char *buf;
+ int size = 4 * 1024;
+ int rc;
+ void *ret;
+
+ if ((buf = xmalloc(size)) == NULL) {
+ return NULL;
+ }
+ while ((rc = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
+ free(buf);
+ size += 4 * 1024;
+ if ((buf = xmalloc(size)) == NULL) {
+ return NULL;
+ }
+ }
+ if (rc == -1) {
+ free(buf);
+ return NULL;
+ }
+ lp = (struct ld_info *)buf;
+ ret = lp->ldinfo_dataorg;
+ free(buf);
+ return ret;
+}
+
static void
aix_loaderror(const char *pathname)
{
@@ -1310,12 +1336,21 @@ dln_load(file)
#if defined(_AIX)
#define DLN_DEFINED
{
+ static void *main_module = NULL;
void (*init_fct)();
- init_fct = (void(*)())load(file, 1, 0);
+ if (main_module == NULL) {
+ if ((main_module = aix_findmain()) == NULL) {
+ aix_loaderror(file);
+ }
+ }
+ init_fct = (void(*)())load((char*)file, 1, 0);
if (init_fct == NULL) {
aix_loaderror(file);
}
+ if (loadbind(0, main_module, init_fct) == -1) {
+ aix_loaderror(file);
+ }
(*init_fct)();
return;
}