annotate dlfcn/dlfcn.c @ 7948:af10baa63915 ss-3-1-50

3.1.50 snapshot
author John W. Eaton <jwe@octave.org>
date Fri, 18 Jul 2008 17:42:48 -0400
parents 098edb40c89b
children 66fdc831c580
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
1 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
2 * @(#)dlfcn.c 1.10 revision of 96/02/15 17:42:44
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
3 * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
4 * 30159 Hannover, Germany
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
5 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
6
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
7 /*
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
8 * Changes marked with `--jwe' were made on April 7 1996 by John W. Eaton
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
9 * <jwe@bevo.che.wisc.edu> to support g++ and/or use with Octave.
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
10 */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
11
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
12 /*
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
13 * This makes my life easier with Octave. --jwe
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
14 */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
15 #ifdef HAVE_CONFIG_H
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
16 #include <config.h>
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
17 #endif
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
18
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
19 #include <stdio.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
20 #include <errno.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
21 #include <string.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
22 #include <stdlib.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
23 #include <sys/types.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
24 #include <sys/ldr.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
25 #include <a.out.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
26 #include <ldfcn.h>
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
27 #include "dlfcn.h"
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
28
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
29 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
30 * We simulate dlopen() et al. through a call to load. Because AIX has
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
31 * no call to find an exported symbol we read the loader section of the
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
32 * loaded module and build a list of exported symbols and their virtual
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
33 * address.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
34 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
35
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
36 typedef struct {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
37 char *name; /* the symbols's name */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
38 void *addr; /* its relocated virtual address */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
39 } Export, *ExportPtr;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
40
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
41 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
42 * xlC uses the following structure to list its constructors and
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
43 * destructors. This is gleaned from the output of munch.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
44 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
45 typedef struct {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
46 void (*init)(void); /* call static constructors */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
47 void (*term)(void); /* call static destructors */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
48 } Cdtor, *CdtorPtr;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
49
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
50 typedef void (*GccCDtorPtr)(void);
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
51
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
52 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
53 * The void * handle returned from dlopen is actually a ModulePtr.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
54 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
55 typedef struct Module {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
56 struct Module *next;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
57 char *name; /* module name for refcounting */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
58 int refCnt; /* the number of references */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
59 void *entry; /* entry point from load */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
60 struct dl_info *info; /* optional init/terminate functions */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
61 CdtorPtr cdtors; /* optional C++ constructors */
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
62 GccCDtorPtr gcc_ctor; /* g++ constructors --jwe */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
63 GccCDtorPtr gcc_dtor; /* g++ destructors --jwe */
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
64 int nExports; /* the number of exports found */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
65 ExportPtr exports; /* the array of exports */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
66 } Module, *ModulePtr;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
67
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
68 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
69 * We keep a list of all loaded modules to be able to call the fini
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
70 * handlers and destructors at atexit() time.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
71 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
72 static ModulePtr modList;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
73
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
74 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
75 * The last error from one of the dl* routines is kept in static
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
76 * variables here. Each error is returned only once to the caller.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
77 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
78 static char errbuf[BUFSIZ];
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
79 static int errvalid;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
80
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
81 /*
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
82 * The `fixed' gcc header files on AIX 3.2.5 provide a prototype for
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
83 * strdup(). --jwe
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
84 */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
85 #ifndef HAVE_STRDUP
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
86 extern char *strdup(const char *);
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
87 #endif
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
88 static void caterr(char *);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
89 static int readExports(ModulePtr);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
90 static void terminate(void);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
91 static void *findMain(void);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
92
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
93 void *dlopen(const char *path, int mode)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
94 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
95 register ModulePtr mp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
96 static void *mainModule;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
97
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
98 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
99 * Upon the first call register a terminate handler that will
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
100 * close all libraries. Also get a reference to the main module
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
101 * for use with loadbind.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
102 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
103 if (!mainModule) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
104 if ((mainModule = findMain()) == NULL)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
105 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
106 atexit(terminate);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
107 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
108 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
109 * Scan the list of modules if we have the module already loaded.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
110 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
111 for (mp = modList; mp; mp = mp->next)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
112 if (strcmp(mp->name, path) == 0) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
113 mp->refCnt++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
114 return mp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
115 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
116 if ((mp = (ModulePtr)calloc(1, sizeof(*mp))) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
117 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
118 strcpy(errbuf, "calloc: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
119 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
120 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
121 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
122 if ((mp->name = strdup(path)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
123 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
124 strcpy(errbuf, "strdup: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
125 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
126 free(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
127 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
128 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
129 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
130 * load should be declared load(const char *...). Thus we
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
131 * cast the path to a normal char *. Ugly.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
132 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
133 if ((mp->entry = (void *)load((char *)path, L_NOAUTODEFER, NULL)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
134 free(mp->name);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
135 free(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
136 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
137 strcpy(errbuf, "dlopen: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
138 strcat(errbuf, path);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
139 strcat(errbuf, ": ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
140 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
141 * If AIX says the file is not executable, the error
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
142 * can be further described by querying the loader about
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
143 * the last error.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
144 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
145 if (errno == ENOEXEC) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
146 char *tmp[BUFSIZ/sizeof(char *)];
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
147 if (loadquery(L_GETMESSAGES, tmp, sizeof(tmp)) == -1)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
148 strcpy(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
149 else {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
150 char **p;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
151 for (p = tmp; *p; p++)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
152 caterr(*p);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
153 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
154 } else
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
155 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
156 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
157 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
158 mp->refCnt = 1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
159 mp->next = modList;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
160 modList = mp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
161 if (loadbind(0, mainModule, mp->entry) == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
162 dlclose(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
163 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
164 strcpy(errbuf, "loadbind: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
165 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
166 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
167 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
168 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
169 * If the user wants global binding, loadbind against all other
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
170 * loaded modules.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
171 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
172 if (mode & RTLD_GLOBAL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
173 register ModulePtr mp1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
174 for (mp1 = mp->next; mp1; mp1 = mp1->next)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
175 if (loadbind(0, mp1->entry, mp->entry) == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
176 dlclose(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
177 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
178 strcpy(errbuf, "loadbind: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
179 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
180 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
181 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
182 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
183 if (readExports(mp) == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
184 dlclose(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
185 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
186 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
187 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
188 * If there is a dl_info structure, call the init function.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
189 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
190 if (mp->info = (struct dl_info *)dlsym(mp, "dl_info")) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
191 if (mp->info->init)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
192 (*mp->info->init)();
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
193 } else
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
194 errvalid = 0;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
195 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
196 * If the shared object was compiled using xlC we will need
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
197 * to call static constructors (and later on dlclose destructors).
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
198 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
199 if (mp->cdtors = (CdtorPtr)dlsym(mp, "__cdtors")) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
200 CdtorPtr cp = mp->cdtors;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
201 while (cp->init || cp->term) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
202 if (cp->init && cp->init != (void (*)(void))0xffffffff)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
203 (*cp->init)();
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
204 cp++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
205 }
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
206 /*
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
207 * If the shared object was compiled using g++, we will need
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
208 * to call global constructors using the _GLOBAL__DI function,
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
209 * and later, global destructors using the _GLOBAL_DD
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
210 * funciton. --jwe
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
211 */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
212 } else if (mp->gcc_ctor = (GccCDtorPtr)dlsym(mp, "_GLOBAL__DI")) {
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
213 (*mp->gcc_ctor)();
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
214 mp->gcc_dtor = (GccCDtorPtr)dlsym(mp, "_GLOBAL__DD");
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
215 } else
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
216 errvalid = 0;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
217 return mp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
218 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
219
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
220 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
221 * Attempt to decipher an AIX loader error message and append it
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
222 * to our static error message buffer.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
223 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
224 static void caterr(char *s)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
225 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
226 register char *p = s;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
227
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
228 while (*p >= '0' && *p <= '9')
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
229 p++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
230 switch(atoi(s)) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
231 case L_ERROR_TOOMANY:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
232 strcat(errbuf, "to many errors");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
233 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
234 case L_ERROR_NOLIB:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
235 strcat(errbuf, "can't load library");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
236 strcat(errbuf, p);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
237 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
238 case L_ERROR_UNDEF:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
239 strcat(errbuf, "can't find symbol");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
240 strcat(errbuf, p);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
241 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
242 case L_ERROR_RLDBAD:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
243 strcat(errbuf, "bad RLD");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
244 strcat(errbuf, p);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
245 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
246 case L_ERROR_FORMAT:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
247 strcat(errbuf, "bad exec format in");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
248 strcat(errbuf, p);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
249 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
250 case L_ERROR_ERRNO:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
251 strcat(errbuf, strerror(atoi(++p)));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
252 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
253 default:
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
254 strcat(errbuf, s);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
255 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
256 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
257 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
258
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
259 void *dlsym(void *handle, const char *symbol)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
260 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
261 register ModulePtr mp = (ModulePtr)handle;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
262 register ExportPtr ep;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
263 register int i;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
264
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
265 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
266 * Could speed up the search, but I assume that one assigns
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
267 * the result to function pointers anyways.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
268 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
269 for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
270 if (strcmp(ep->name, symbol) == 0)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
271 return ep->addr;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
272 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
273 strcpy(errbuf, "dlsym: undefined symbol ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
274 strcat(errbuf, symbol);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
275 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
276 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
277
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
278 char *dlerror(void)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
279 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
280 if (errvalid) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
281 errvalid = 0;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
282 return errbuf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
283 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
284 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
285 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
286
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
287 int dlclose(void *handle)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
288 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
289 register ModulePtr mp = (ModulePtr)handle;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
290 int result;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
291 register ModulePtr mp1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
292
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
293 if (--mp->refCnt > 0)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
294 return 0;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
295 if (mp->info && mp->info->fini)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
296 (*mp->info->fini)();
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
297 if (mp->cdtors) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
298 CdtorPtr cp = mp->cdtors;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
299 while (cp->init || cp->term) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
300 if (cp->term && cp->init != (void (*)(void))0xffffffff)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
301 (*cp->term)();
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
302 cp++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
303 }
2061
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
304 /*
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
305 * If the function to handle global destructors for g++
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
306 * exists, call it. --jwe
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
307 */
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
308 } else if (mp->gcc_dtor) {
098edb40c89b [project @ 1996-04-07 21:56:15 by jwe]
jwe
parents: 2060
diff changeset
309 (*mp->gcc_dtor)();
2060
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
310 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
311 result = unload(mp->entry);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
312 if (result == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
313 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
314 strcpy(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
315 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
316 if (mp->exports) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
317 register ExportPtr ep;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
318 register int i;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
319 for (ep = mp->exports, i = mp->nExports; i; i--, ep++)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
320 if (ep->name)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
321 free(ep->name);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
322 free(mp->exports);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
323 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
324 if (mp == modList)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
325 modList = mp->next;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
326 else {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
327 for (mp1 = modList; mp1; mp1 = mp1->next)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
328 if (mp1->next == mp) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
329 mp1->next = mp->next;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
330 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
331 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
332 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
333 free(mp->name);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
334 free(mp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
335 return result;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
336 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
337
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
338 static void terminate(void)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
339 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
340 while (modList)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
341 dlclose(modList);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
342 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
343
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
344 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
345 * Build the export table from the XCOFF .loader section.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
346 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
347 static int readExports(ModulePtr mp)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
348 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
349 LDFILE *ldp = NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
350 SCNHDR sh, shdata;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
351 LDHDR *lhp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
352 char *ldbuf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
353 LDSYM *ls;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
354 int i;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
355 ExportPtr ep;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
356
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
357 if ((ldp = ldopen(mp->name, ldp)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
358 struct ld_info *lp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
359 char *buf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
360 int size = 4*1024;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
361 if (errno != ENOENT) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
362 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
363 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
364 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
365 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
366 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
367 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
368 * The module might be loaded due to the LIBPATH
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
369 * environment variable. Search for the loaded
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
370 * module using L_GETINFO.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
371 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
372 if ((buf = malloc(size)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
373 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
374 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
375 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
376 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
377 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
378 while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
379 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
380 size += 4*1024;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
381 if ((buf = malloc(size)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
382 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
383 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
384 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
385 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
386 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
387 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
388 if (i == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
389 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
390 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
391 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
392 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
393 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
394 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
395 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
396 * Traverse the list of loaded modules. The entry point
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
397 * returned by load() does actually point to the data
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
398 * segment origin.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
399 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
400 lp = (struct ld_info *)buf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
401 while (lp) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
402 if (lp->ldinfo_dataorg == mp->entry) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
403 ldp = ldopen(lp->ldinfo_filename, ldp);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
404 break;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
405 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
406 if (lp->ldinfo_next == 0)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
407 lp = NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
408 else
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
409 lp = (struct ld_info *)((char *)lp + lp->ldinfo_next);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
410 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
411 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
412 if (!ldp) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
413 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
414 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
415 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
416 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
417 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
418 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
419 if (TYPE(ldp) != U802TOCMAGIC) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
420 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
421 strcpy(errbuf, "readExports: bad magic");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
422 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
423 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
424 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
425 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
426 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
427 * Get the padding for the data section. This is needed for
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
428 * AIX 4.1 compilers. This is used when building the final
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
429 * function pointer to the exported symbol.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
430 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
431 if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
432 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
433 strcpy(errbuf, "readExports: cannot read data section header");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
434 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
435 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
436 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
437 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
438 if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
439 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
440 strcpy(errbuf, "readExports: cannot read loader section header");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
441 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
442 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
443 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
444 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
445 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
446 * We read the complete loader section in one chunk, this makes
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
447 * finding long symbol names residing in the string table easier.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
448 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
449 if ((ldbuf = (char *)malloc(sh.s_size)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
450 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
451 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
452 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
453 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
454 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
455 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
456 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
457 if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
458 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
459 strcpy(errbuf, "readExports: cannot seek to loader section");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
460 free(ldbuf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
461 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
462 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
463 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
464 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
465 if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
466 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
467 strcpy(errbuf, "readExports: cannot read loader section");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
468 free(ldbuf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
469 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
470 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
471 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
472 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
473 lhp = (LDHDR *)ldbuf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
474 ls = (LDSYM *)(ldbuf+LDHDRSZ);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
475 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
476 * Count the number of exports to include in our export table.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
477 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
478 for (i = lhp->l_nsyms; i; i--, ls++) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
479 if (!LDR_EXPORT(*ls))
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
480 continue;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
481 mp->nExports++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
482 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
483 if ((mp->exports = (ExportPtr)calloc(mp->nExports, sizeof(*mp->exports))) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
484 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
485 strcpy(errbuf, "readExports: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
486 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
487 free(ldbuf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
488 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
489 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
490 return -1;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
491 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
492 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
493 * Fill in the export table. All entries are relative to
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
494 * the entry point we got from load.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
495 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
496 ep = mp->exports;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
497 ls = (LDSYM *)(ldbuf+LDHDRSZ);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
498 for (i = lhp->l_nsyms; i; i--, ls++) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
499 char *symname;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
500 char tmpsym[SYMNMLEN+1];
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
501 if (!LDR_EXPORT(*ls))
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
502 continue;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
503 if (ls->l_zeroes == 0)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
504 symname = ls->l_offset+lhp->l_stoff+ldbuf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
505 else {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
506 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
507 * The l_name member is not zero terminated, we
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
508 * must copy the first SYMNMLEN chars and make
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
509 * sure we have a zero byte at the end.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
510 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
511 strncpy(tmpsym, ls->l_name, SYMNMLEN);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
512 tmpsym[SYMNMLEN] = '\0';
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
513 symname = tmpsym;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
514 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
515 ep->name = strdup(symname);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
516 ep->addr = (void *)((unsigned long)mp->entry +
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
517 ls->l_value - shdata.s_vaddr);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
518 ep++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
519 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
520 free(ldbuf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
521 while(ldclose(ldp) == FAILURE)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
522 ;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
523 return 0;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
524 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
525
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
526 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
527 * Find the main modules entry point. This is used as export pointer
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
528 * for loadbind() to be able to resolve references to the main part.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
529 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
530 static void * findMain(void)
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
531 {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
532 struct ld_info *lp;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
533 char *buf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
534 int size = 4*1024;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
535 int i;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
536 void *ret;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
537
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
538 if ((buf = malloc(size)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
539 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
540 strcpy(errbuf, "findMain: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
541 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
542 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
543 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
544 while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
545 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
546 size += 4*1024;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
547 if ((buf = malloc(size)) == NULL) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
548 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
549 strcpy(errbuf, "findMain: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
550 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
551 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
552 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
553 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
554 if (i == -1) {
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
555 errvalid++;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
556 strcpy(errbuf, "findMain: ");
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
557 strcat(errbuf, strerror(errno));
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
558 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
559 return NULL;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
560 }
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
561 /*
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
562 * The first entry is the main module. The entry point
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
563 * returned by load() does actually point to the data
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
564 * segment origin.
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
565 */
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
566 lp = (struct ld_info *)buf;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
567 ret = lp->ldinfo_dataorg;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
568 free(buf);
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
569 return ret;
7e430470e098 [project @ 1996-04-07 21:50:34 by jwe]
jwe
parents:
diff changeset
570 }