PERL_SRC already has brackets on VMS.
[p5sagit/p5-mst-13.2.git] / ext / DynaLoader / dl_dyld.xs
CommitLineData
f556e5b9 1/* dl_dyld.xs
8f1f23e8 2 *
f556e5b9 3 * Platform: Darwin (Mac OS)
4 * Author: Wilfredo Sanchez <wsanchez@apple.com>
8f1f23e8 5 * Based on: dl_next.xs by Paul Marquess
6 * Based on: dl_dlopen.xs by Anno Siegel
7 * Created: Aug 15th, 1994
8 *
9 */
10
11/*
4ac71550 12 * And Gandalf said: 'Many folk like to know beforehand what is to
13 * be set on the table; but those who have laboured to prepare the
14 * feast like to keep their secret; for wonder makes the words of
15 * praise louder.'
16 *
17 * [p.970 of _The Lord of the Rings_, VI/v: "The Steward and the King"]
18 */
8f1f23e8 19
20/* Porting notes:
21
f556e5b9 22dl_dyld.xs is based on dl_next.xs by Anno Siegel.
23
24dl_next.xs is in turn a port from dl_dlopen.xs by Paul Marquess. It
8f1f23e8 25should not be used as a base for further ports though it may be used
26as an example for how dl_dlopen.xs can be ported to other platforms.
27
28The method used here is just to supply the sun style dlopen etc.
f556e5b9 29functions in terms of NeXT's/Apple's dyld. The xs code proper is
30unchanged from Paul's original.
8f1f23e8 31
32The port could use some streamlining. For one, error handling could
33be simplified.
34
f556e5b9 35This should be useable as a replacement for dl_next.xs, but it has not
36been tested on NeXT platforms.
37
38 Wilfredo Sanchez
8f1f23e8 39
40*/
41
42#include "EXTERN.h"
43#include "perl.h"
44#include "XSUB.h"
45
cdc73a10 46#include "dlutils.c" /* for SaveError() etc */
8f1f23e8 47
48#undef environ
f556e5b9 49#undef bool
8f1f23e8 50#import <mach-o/dyld.h>
51
8f1f23e8 52static char *dlerror()
53{
cdc73a10 54 dTHX;
55 dMY_CXT;
8f1f23e8 56 return dl_last_error;
57}
58
2ec6e385 59static int dlclose(void *handle) /* stub only */
8f1f23e8 60{
61 return 0;
62}
63
64enum dyldErrorSource
65{
66 OFImage,
67};
68
69static void TranslateError
70 (const char *path, enum dyldErrorSource type, int number)
71{
5b877257 72 dTHX;
cdc73a10 73 dMY_CXT;
8f1f23e8 74 char *error;
75 unsigned int index;
76 static char *OFIErrorStrings[] =
77 {
78 "%s(%d): Object Image Load Failure\n",
79 "%s(%d): Object Image Load Success\n",
d1be9408 80 "%s(%d): Not a recognisable object file\n",
8f1f23e8 81 "%s(%d): No valid architecture\n",
82 "%s(%d): Object image has an invalid format\n",
83 "%s(%d): Invalid access (permissions?)\n",
84 "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n",
85 };
86#define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0]))
87
88 switch (type)
89 {
90 case OFImage:
91 index = number;
92 if (index > NUM_OFI_ERRORS - 1)
93 index = NUM_OFI_ERRORS - 1;
7a3f2258 94 error = Perl_form_nocontext(OFIErrorStrings[index], path, number);
8f1f23e8 95 break;
96
97 default:
7a3f2258 98 error = Perl_form_nocontext("%s(%d): Totally unknown error type %d\n",
8f1f23e8 99 path, number, type);
100 break;
101 }
379d1ffd 102 sv_setpv(MY_CXT.x_dl_last_error, error);
8f1f23e8 103}
104
105static char *dlopen(char *path, int mode /* mode is ignored */)
106{
107 int dyld_result;
108 NSObjectFileImage ofile;
109 NSModule handle = NULL;
110
111 dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
112 if (dyld_result != NSObjectFileImageSuccess)
113 TranslateError(path, OFImage, dyld_result);
114 else
115 {
03f6ae00 116 // NSLinkModule will cause the run to abort on any link errors
8f1f23e8 117 // not very friendly but the error recovery functionality is limited.
118 handle = NSLinkModule(ofile, path, TRUE);
bb2834fe 119 NSDestroyObjectFileImage(ofile);
8f1f23e8 120 }
121
122 return handle;
123}
124
a97fb7de 125static void *
2ec6e385 126dlsym(void *handle, char *symbol)
8f1f23e8 127{
128 void *addr;
129
130 if (NSIsSymbolNameDefined(symbol))
131 addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
132 else
133 addr = NULL;
134
135 return addr;
136}
137
138
139
140/* ----- code from dl_dlopen.xs below here ----- */
141
142
143static void
cea2e8a9 144dl_private_init(pTHX)
8f1f23e8 145{
cea2e8a9 146 (void)dl_generic_private_init(aTHX);
8f1f23e8 147}
148
149MODULE = DynaLoader PACKAGE = DynaLoader
150
151BOOT:
cea2e8a9 152 (void)dl_private_init(aTHX);
8f1f23e8 153
154
155
156void *
157dl_load_file(filename, flags=0)
158 char * filename
159 int flags
160 PREINIT:
161 int mode = 1;
162 CODE:
bf49b057 163 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
8f1f23e8 164 if (flags & 0x01)
cea2e8a9 165 Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
8f1f23e8 166 RETVAL = dlopen(filename, mode) ;
bf49b057 167 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%x\n", RETVAL));
8f1f23e8 168 ST(0) = sv_newmortal() ;
169 if (RETVAL == NULL)
cea2e8a9 170 SaveError(aTHX_ "%s",dlerror()) ;
8f1f23e8 171 else
3175b8cd 172 sv_setiv( ST(0), PTR2IV(RETVAL) );
8f1f23e8 173
174
175void *
176dl_find_symbol(libhandle, symbolname)
177 void * libhandle
178 char * symbolname
179 CODE:
7a3f2258 180 symbolname = Perl_form_nocontext("_%s", symbolname);
bf49b057 181 DLDEBUG(2, PerlIO_printf(Perl_debug_log,
8f1f23e8 182 "dl_find_symbol(handle=%lx, symbol=%s)\n",
183 (unsigned long) libhandle, symbolname));
184 RETVAL = dlsym(libhandle, symbolname);
bf49b057 185 DLDEBUG(2, PerlIO_printf(Perl_debug_log,
8f1f23e8 186 " symbolref = %lx\n", (unsigned long) RETVAL));
187 ST(0) = sv_newmortal() ;
188 if (RETVAL == NULL)
cea2e8a9 189 SaveError(aTHX_ "%s",dlerror()) ;
8f1f23e8 190 else
3175b8cd 191 sv_setiv( ST(0), PTR2IV(RETVAL) );
8f1f23e8 192
193
194void
195dl_undef_symbols()
196 PPCODE:
197
198
199
200# These functions should not need changing on any platform:
201
202void
203dl_install_xsub(perl_name, symref, filename="$Package")
204 char * perl_name
205 void * symref
d3f5e399 206 const char * filename
8f1f23e8 207 CODE:
bf49b057 208 DLDEBUG(2,PerlIO_printf(Perl_debug_log, "dl_install_xsub(name=%s, symref=%x)\n",
8f1f23e8 209 perl_name, symref));
77004dee 210 ST(0) = sv_2mortal(newRV((SV*)newXS_flags(perl_name,
211 (void(*)(pTHX_ CV *))symref,
212 filename, NULL,
213 XS_DYNAMIC_FILENAME)));
8f1f23e8 214
215
216char *
217dl_error()
218 CODE:
cdc73a10 219 dMY_CXT;
220 RETVAL = dl_last_error ;
8f1f23e8 221 OUTPUT:
222 RETVAL
223
8c472fc1 224#if defined(USE_ITHREADS)
225
226void
227CLONE(...)
228 CODE:
229 MY_CXT_CLONE;
230
231 /* MY_CXT_CLONE just does a memcpy on the whole structure, so to avoid
232 * using Perl variables that belong to another thread, we create our
233 * own for this thread.
234 */
235 MY_CXT.x_dl_last_error = newSVpvn("", 0);
236
237#endif
238
f556e5b9 239# end.