summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--arch/nt32/psxglue.h2
-rw-r--r--arch/nt64/psxglue.h2
-rw-r--r--include/sys/ldso.h15
-rw-r--r--project/arch.mk1
-rw-r--r--src/ldso/nt32/dynlink.c52
-rw-r--r--src/ldso/nt64/dynlink.c52
6 files changed, 124 insertions, 0 deletions
diff --git a/arch/nt32/psxglue.h b/arch/nt32/psxglue.h
index d8e653a..b8f22b8 100644
--- a/arch/nt32/psxglue.h
+++ b/arch/nt32/psxglue.h
@@ -14,6 +14,8 @@ struct __ldso_vtbl {
int (*dlinfo) (void * dso, int req, void * res);
void * (*dlsym) (void * p, const char * s, void * ra);
void * (*dlopen) (const char * file, int mode, const char ** pathv, int * status);
+ void * (*dldopen) (int fd, int mode, int * status);
+ void * (*dlsopen) (const char * file, int mode, int * status);
int (*dlclose) (void *p);
char * (*dlerror) (void);
void (*tlsreset) (void);
diff --git a/arch/nt64/psxglue.h b/arch/nt64/psxglue.h
index d8e653a..b8f22b8 100644
--- a/arch/nt64/psxglue.h
+++ b/arch/nt64/psxglue.h
@@ -14,6 +14,8 @@ struct __ldso_vtbl {
int (*dlinfo) (void * dso, int req, void * res);
void * (*dlsym) (void * p, const char * s, void * ra);
void * (*dlopen) (const char * file, int mode, const char ** pathv, int * status);
+ void * (*dldopen) (int fd, int mode, int * status);
+ void * (*dlsopen) (const char * file, int mode, int * status);
int (*dlclose) (void *p);
char * (*dlerror) (void);
void (*tlsreset) (void);
diff --git a/include/sys/ldso.h b/include/sys/ldso.h
new file mode 100644
index 0000000..8013b6a
--- /dev/null
+++ b/include/sys/ldso.h
@@ -0,0 +1,15 @@
+#ifndef _SYS_LDSO_H
+#define _SYS_LDSO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void * __dldopen(int, int);
+void * __dlsopen(const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/project/arch.mk b/project/arch.mk
index a33fd09..76bca17 100644
--- a/project/arch.mk
+++ b/project/arch.mk
@@ -24,6 +24,7 @@ LDFLAGS_CONFIG += -Wl,--exclude-symbols=___errno_location
TARGET_SYS_HEADERS = \
$(PROJECT_DIR)/include/sys/debug.h \
+ $(PROJECT_DIR)/include/sys/ldso.h \
$(PROJECT_DIR)/include/sys/unwind.h \
install-headers: install-target-sys-headers
diff --git a/src/ldso/nt32/dynlink.c b/src/ldso/nt32/dynlink.c
index a585fbb..c0a1f04 100644
--- a/src/ldso/nt32/dynlink.c
+++ b/src/ldso/nt32/dynlink.c
@@ -106,6 +106,58 @@ void * dlopen(const char * file, int mode)
return base;
}
+void * __dldopen(int fd, int mode)
+{
+ int status;
+ void * base;
+ int cs;
+
+ /* prolog */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ pthread_rwlock_wrlock(&__ldso_lock);
+ __inhibit_ptc();
+
+ /* dldopen */
+ base = __ldso_vtbl->dldopen(fd,mode,&status);
+
+ /* epilog */
+ __release_ptc();
+ pthread_rwlock_unlock(&__ldso_lock);
+
+ if (base)
+ __psx_vtbl->do_global_ctors_fn();
+
+ pthread_setcancelstate(cs, 0);
+
+ return base;
+}
+
+void * __dlsopen(const char * file, int mode)
+{
+ int status;
+ void * base;
+ int cs;
+
+ /* prolog */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ pthread_rwlock_wrlock(&__ldso_lock);
+ __inhibit_ptc();
+
+ /* dlsopen */
+ base = __ldso_vtbl->dlsopen(file,mode,&status);
+
+ /* epilog */
+ __release_ptc();
+ pthread_rwlock_unlock(&__ldso_lock);
+
+ if (base)
+ __psx_vtbl->do_global_ctors_fn();
+
+ pthread_setcancelstate(cs, 0);
+
+ return base;
+}
+
int __dladdr(const void * addr, Dl_info * info)
{
return __ldso_vtbl->dladdr(addr,info);
diff --git a/src/ldso/nt64/dynlink.c b/src/ldso/nt64/dynlink.c
index a585fbb..c0a1f04 100644
--- a/src/ldso/nt64/dynlink.c
+++ b/src/ldso/nt64/dynlink.c
@@ -106,6 +106,58 @@ void * dlopen(const char * file, int mode)
return base;
}
+void * __dldopen(int fd, int mode)
+{
+ int status;
+ void * base;
+ int cs;
+
+ /* prolog */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ pthread_rwlock_wrlock(&__ldso_lock);
+ __inhibit_ptc();
+
+ /* dldopen */
+ base = __ldso_vtbl->dldopen(fd,mode,&status);
+
+ /* epilog */
+ __release_ptc();
+ pthread_rwlock_unlock(&__ldso_lock);
+
+ if (base)
+ __psx_vtbl->do_global_ctors_fn();
+
+ pthread_setcancelstate(cs, 0);
+
+ return base;
+}
+
+void * __dlsopen(const char * file, int mode)
+{
+ int status;
+ void * base;
+ int cs;
+
+ /* prolog */
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+ pthread_rwlock_wrlock(&__ldso_lock);
+ __inhibit_ptc();
+
+ /* dlsopen */
+ base = __ldso_vtbl->dlsopen(file,mode,&status);
+
+ /* epilog */
+ __release_ptc();
+ pthread_rwlock_unlock(&__ldso_lock);
+
+ if (base)
+ __psx_vtbl->do_global_ctors_fn();
+
+ pthread_setcancelstate(cs, 0);
+
+ return base;
+}
+
int __dladdr(const void * addr, Dl_info * info)
{
return __ldso_vtbl->dladdr(addr,info);