89
89
#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY
92
/* These are all require for the PR_GetLibraryFilePathname implementation */
97
#include <lib$routines.h>
104
#pragma __member_alignment __save
105
#pragma __nomember_alignment
106
#ifdef __INITIAL_POINTER_SIZE
107
#pragma __required_pointer_size __save
108
#pragma __required_pointer_size __short
111
typedef struct _imcb {
112
struct _imcb *imcb$l_flink;
113
struct _imcb *imcb$l_blink;
114
unsigned short int imcb$w_size;
115
unsigned char imcb$b_type;
117
unsigned char imcb$b_access_mode;
118
unsigned char imcb$b_act_code;
119
unsigned short int imcb$w_chan;
120
unsigned int imcb$l_flags;
121
char imcb$t_image_name [40];
122
unsigned int imcb$l_symvec_size;
123
unsigned __int64 imcb$q_ident;
124
void *imcb$l_starting_address;
125
void *imcb$l_end_address;
128
#pragma __member_alignment __restore
129
#ifdef __INITIAL_POINTER_SIZE
130
#pragma __required_pointer_size __restore
147
typedef unsigned long int ulong_t;
149
struct _imcb *IAC$GL_IMAGE_LIST = NULL;
151
#define MAX_DEVNAM 64
152
#define MAX_FILNAM 255
156
92
* On these platforms, symbols have a leading '_'.
158
94
#if defined(SUNOS4) || (defined(DARWIN) && defined(USE_MACH_DYLD)) \
159
|| defined(NEXTSTEP) || defined(WIN16) || defined(XP_OS2) \
95
|| defined(NEXTSTEP) || defined(XP_OS2) \
160
96
|| ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__))
161
97
#define NEED_LEADING_UNDERSCORE
330
250
PR_ExitMonitor(pr_linker_lock);
335
* _PR_ShutdownLinker unloads all dlls loaded by the application via
336
* calls to PR_LoadLibrary
338
void _PR_ShutdownLinker(void)
340
PR_EnterMonitor(pr_linker_lock);
343
if (pr_loadmap->refCount > 1) {
345
fprintf(stderr, "# Forcing library to unload: %s (%d outstanding references)\n",
346
pr_loadmap->name, pr_loadmap->refCount);
348
pr_loadmap->refCount = 1;
350
PR_UnloadLibrary(pr_loadmap);
353
PR_ExitMonitor(pr_linker_lock);
355
PR_DestroyMonitor(pr_linker_lock);
356
pr_linker_lock = NULL;
360
* _PR_ShutdownLinker was originally only used on WIN16 (see above),
361
* but I think it should also be used on other platforms. However,
362
* I disagree with the original implementation's unloading the dlls
363
* for the application. Any dlls that still remain on the pr_loadmap
364
* list when NSPR shuts down are application programming errors. The
365
* only exception is pr_exe_loadmap, which was added to the list by
254
* _PR_ShutdownLinker does not unload the dlls loaded by the application
255
* via calls to PR_LoadLibrary. Any dlls that still remain on the
256
* pr_loadmap list when NSPR shuts down are application programming errors.
257
* The only exception is pr_exe_loadmap, which was added to the list by
366
258
* NSPR and hence should be cleaned up by NSPR.
368
260
void _PR_ShutdownLinker(void)
781
672
#endif /* XP_MACOSX && USE_MACH_DYLD */
784
static HMODULE WINAPI
785
EmulateLoadLibraryW(LPCWSTR lpLibFileName)
788
char nameA[MAX_PATH];
790
if (!WideCharToMultiByte(CP_ACP, 0, lpLibFileName, -1,
791
nameA, sizeof nameA, NULL, NULL)) {
794
/* Perhaps it's better to add a check for characters
795
* not representable in CP_ACP.
797
h = LoadLibraryA(nameA);
803
675
** Dynamically load a library. Only load libraries once, so scan the load
841
len = pr_ConvertUTF16toUTF8(wname, NULL, 0);
713
len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL);
842
714
if (len > MAX_PATH)
843
715
utf8name = utf8name_malloc = PR_Malloc(len);
844
716
if (utf8name == NULL ||
845
!pr_ConvertUTF16toUTF8(wname, utf8name, len)) {
717
!WideCharToMultiByte(CP_UTF8, 0, wname, -1,
718
utf8name, len, NULL, NULL)) {
846
719
oserr = _MD_ERRNO();
1126
* CP_UTF8 is not supported by WideCharToMultiByte on Windows 95 so that
1127
* we have to emulate it
1130
pr_ConvertSingleCharToUTF8(PRUint32 usv, PRUint16 offset, int bufLen,
1131
int *utf8Len, char * *buf)
1134
PR_ASSERT(!bufLen || *buf);
1140
if (*utf8Len + offset >= bufLen)
1146
} else if (offset == 2) {
1147
*p++ = (char)0xc0 | (usv >> 6);
1148
*p++ = (char)0x80 | (usv & 0x003f);
1149
} else if (offset == 3) {
1150
*p++ = (char)0xe0 | (usv >> 12);
1151
*p++ = (char)0x80 | ((usv >> 6) & 0x003f);
1152
*p++ = (char)0x80 | (usv & 0x003f);
1153
} else { /* offset = 4 */
1154
*p++ = (char)0xf0 | (usv >> 18);
1155
*p++ = (char)0x80 | ((usv >> 12) & 0x003f);
1156
*p++ = (char)0x80 | ((usv >> 6) & 0x003f);
1157
*p++ = (char)0x80 | (usv & 0x003f);
1164
static int pr_ConvertUTF16toUTF8(LPCWSTR wname, LPSTR name, int len)
1169
PRBool highSurrogate = PR_FALSE;
1171
utf8Len = WideCharToMultiByte(CP_UTF8, 0, wname, -1, name, len,
1174
* Windows 95 and NT 3.51 don't support CP_UTF8.
1175
* WideCharToMultiByte(CP_UTF8, ...) fails with the error code
1176
* ERROR_INVALID_PARAMETER on Windows 95 and NT 3.51.
1178
if (utf8Len || GetLastError() != ERROR_INVALID_PARAMETER)
1181
if (!wname || len < 0 || (len > 0 && !name)) {
1182
SetLastError(ERROR_INVALID_PARAMETER);
1187
PRStatus status = PR_SUCCESS;
1188
if (highSurrogate) {
1189
if (*pw >= (PRUnichar) 0xDC00 && *pw < (PRUnichar) 0xE000) {
1190
/* found a matching low surrogate */
1191
/* convert a surrogate pair to UCS4 */
1192
PRUint32 usv = ((*(pw-1) - (PRUnichar)0xD800) << 10) +
1193
(*pw - (PRUnichar)0xDC00) + (PRUint32)0x10000;
1194
if (pr_ConvertSingleCharToUTF8(usv, 4, len, &utf8Len, &p) ==
1197
highSurrogate = PR_FALSE;
1202
* silently ignore a lone high surrogate
1203
* as is done by WideCharToMultiByte by default
1205
highSurrogate = PR_FALSE;
1209
status = pr_ConvertSingleCharToUTF8(*pw, 1, len, &utf8Len, &p);
1210
else if (*pw <= 0x07ff)
1211
status = pr_ConvertSingleCharToUTF8(*pw, 2, len, &utf8Len, &p);
1212
else if (*pw < (PRUnichar) 0xD800 || *pw >= (PRUnichar) 0xE000)
1213
status = pr_ConvertSingleCharToUTF8(*pw, 3, len, &utf8Len, &p);
1214
else if (*pw < (PRUnichar) 0xDC00)
1215
highSurrogate = PR_TRUE;
1217
/* silently ignore a lone low surrogate as is done by
1218
* WideCharToMultiByte by default */
1220
if (status == PR_FAILURE) {
1221
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1227
/* if we're concerned with a lone high surrogate,
1228
* we have to take care of it here, but we just drop it
1235
static int pr_ConvertUTF16toUTF8(LPCWSTR wname, LPSTR name, int len)
1237
return WideCharToMultiByte(CP_UTF8, 0, wname, -1, name, len, NULL, NULL);
1243
989
** Unload a shared library which was loaded via PR_LoadLibrary
1778
1524
PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
1781
/* Contributed by Colin Blake of HP */
1784
char device_name[MAX_DEVNAM];
1785
int device_name_len;
1786
$DESCRIPTOR (device_name_desc, device_name);
1788
struct dsc$descriptor_s fib_desc =
1789
{ sizeof(struct fibdef), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&fib } ;
1791
ITMLST devlst[2] = {
1792
{MAX_DEVNAM, DVI$_ALLDEVNAM, device_name, &device_name_len},
1794
short file_name_len;
1795
char file_name[MAX_FILNAM+1];
1796
char *result = NULL;
1797
struct dsc$descriptor_s file_name_desc =
1798
{ MAX_FILNAM, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &file_name[0] } ;
1801
** The address for the process image list could change in future versions
1802
** of the operating system. 7FFD0688 is valid for V7.2 and V7.3 releases,
1803
** so we use that for the default, but allow an environment variable
1804
** (logical name) to override.
1806
if (IAC$GL_IMAGE_LIST == NULL) {
1807
char *p = getenv("MOZILLA_IAC_GL_IMAGE_LIST");
1809
IAC$GL_IMAGE_LIST = (struct _imcb *) strtol(p,NULL,0);
1811
IAC$GL_IMAGE_LIST = (struct _imcb *) 0x7FFD0688;
1814
for (icb = IAC$GL_IMAGE_LIST->imcb$l_flink;
1815
icb != IAC$GL_IMAGE_LIST;
1816
icb = icb->imcb$l_flink) {
1817
if (((void *)addr >= icb->imcb$l_starting_address) &&
1818
((void *)addr <= icb->imcb$l_end_address)) {
1820
** This is the correct image.
1821
** Get the device name.
1823
status = sys$getdviw(0,icb->imcb$w_chan,0,&devlst,0,0,0,0);
1824
if ($VMS_STATUS_SUCCESS(status))
1825
device_name_desc.dsc$w_length = device_name_len;
1830
memset(&fib,0,sizeof(struct fibdef));
1831
status = sys$qiow(0,icb->imcb$w_chan,IO$_ACCESS,&iosb,
1832
0,0,&fib_desc,0,0,0,0,0);
1835
** If we got the FID, now look up its name (if for some reason
1836
** we didn't get the device name, this call will fail).
1838
if (($VMS_STATUS_SUCCESS(status)) && ($VMS_STATUS_SUCCESS(iosb.cond))) {
1839
status = lib$fid_to_name (
1847
** If we succeeded then remove the version number and
1848
** return a copy of the UNIX format version of the file name.
1850
if ($VMS_STATUS_SUCCESS(status)) {
1852
file_name[file_name_len] = 0;
1853
p = strrchr(file_name,';');
1855
p = decc$translate_vms(&file_name[0]);
1856
result = PR_Malloc(strlen(p)+1);
1857
if (result != NULL) {
1866
/* Didn't find it */
1867
PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
1870
1526
#elif defined(HPUX) && defined(USE_HPSHL)
1872
1528
struct shl_descriptor desc;
1925
1581
#elif defined(WIN32)
1927
char module_name[MAX_PATH];
1582
PRUnichar wname[MAX_PATH];
1583
HMODULE handle = NULL;
1584
PRUnichar module_name[MAX_PATH];
1930
handle = GetModuleHandle(name);
1588
if (MultiByteToWideChar(CP_ACP, 0, name, -1, wname, MAX_PATH)) {
1589
handle = GetModuleHandleW(wname);
1931
1591
if (handle == NULL) {
1932
1592
PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
1933
1593
DLLErrorInternal(_MD_ERRNO());
1936
if (GetModuleFileName(handle, module_name, sizeof module_name) == 0) {
1596
if (GetModuleFileNameW(handle, module_name, MAX_PATH) == 0) {
1937
1597
/* should not happen */
1938
1598
_PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
1941
result = PR_Malloc(strlen(module_name)+1);
1601
len = WideCharToMultiByte(CP_ACP, 0, module_name, -1,
1602
NULL, 0, NULL, NULL);
1604
_PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
1607
result = PR_Malloc(len * sizeof(PRUnichar));
1942
1608
if (result != NULL) {
1943
strcpy(result, module_name);
1609
WideCharToMultiByte(CP_ACP, 0, module_name, -1,
1610
result, len, NULL, NULL);
1946
1613
#elif defined(XP_OS2)