108
108
#ifndef FUNCNAME_PATTERN
109
109
# if defined(__hp9000s300) || ((defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(__ELF__)) || defined(__BORLANDC__) || defined(NeXT) || defined(__WATCOMC__) || defined(MACOSX_DYLD)
110
# define FUNCNAME_PATTERN "_Init_%s"
110
# define FUNCNAME_PREFIX "_Init_"
112
# define FUNCNAME_PATTERN "Init_%s"
112
# define FUNCNAME_PREFIX "Init_"
116
#if defined __CYGWIN__ || defined DOSISH
117
#define isdirsep(x) ((x) == '/' || (x) == '\\')
119
#define isdirsep(x) ((x) == '/')
117
init_funcname_len(char **buf, const char *file)
123
init_funcname_len(const char **file)
125
const char *p = *file, *base, *dot = NULL;
123
127
/* Load the file as an object one */
124
for (slash = file-1; *file; file++) /* Find position of last '/' */
125
if (*file == '/') slash = file;
127
len = strlen(FUNCNAME_PATTERN) + strlen(slash + 1);
129
snprintf(*buf, len, FUNCNAME_PATTERN, slash + 1);
130
for (p = *buf; *p; p++) { /* Delete suffix if it exists */
128
for (base = p; *p; p++) { /* Find position of last '/' */
129
if (*p == '.' && !dot) dot = p;
130
if (isdirsep(*p)) base = p+1, dot = NULL;
133
/* Delete suffix if it exists */
134
return (dot ? dot : p) - base;
137
static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;
138
139
#define init_funcname(buf, file) do {\
139
size_t len = init_funcname_len(buf, file);\
140
char *tmp = ALLOCA_N(char, len+1);\
140
const char *base = (file);\
141
const size_t flen = init_funcname_len(&base);\
142
const size_t plen = sizeof(funcname_prefix);\
143
char *const tmp = ALLOCA_N(char, plen+flen+1);\
145
strlcpy(tmp, *buf, len + 1);\
147
memcpy(tmp, funcname_prefix, plen);\
148
memcpy(tmp+plen, base, flen);\
149
tmp[plen+flen] = '\0';\
150
153
#ifdef USE_DLN_A_OUT
1117
1120
#if defined _WIN32 && !defined __CYGWIN__
1118
1121
#include <windows.h>
1122
#include <imagehlp.h>
1125
#if defined _WIN32 && !defined __CYGWIN__
1127
dln_strerror(char *message, size_t size)
1129
int error = GetLastError();
1131
size_t len = snprintf(message, size, "%d: ", error);
1133
#define format_message(sublang) FormatMessage(\
1134
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, \
1135
NULL, error, MAKELANGID(LANG_NEUTRAL, (sublang)), \
1136
message + len, size - len, NULL)
1137
if (format_message(SUBLANG_ENGLISH_US) == 0)
1138
format_message(SUBLANG_DEFAULT);
1139
for (p = message + len; *p; p++) {
1140
if (*p == '\n' || *p == '\r')
1145
#define dln_strerror() dln_strerror(message, sizeof message)
1146
#elif ! defined _AIX
1122
1147
static const char *
1123
1148
dln_strerror(void)
1146
1171
#ifdef USE_DLN_DLOPEN
1147
1172
return (char*)dlerror();
1150
#if defined _WIN32 && !defined __CYGWIN__
1151
static char message[1024];
1152
int error = GetLastError();
1154
p += sprintf(message, "%d: ", error);
1156
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1159
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1161
sizeof message - strlen(message),
1164
for (p = message; *p; p++) {
1165
if (*p == '\n' || *p == '\r')
1177
1181
char *message[1024], errbuf[1024];
1179
#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
1183
#define ERRBUF_APPEND(s) strncat(errbuf, (s), sizeof(errbuf)-strlen(errbuf)-1)
1180
1184
snprintf(errbuf, sizeof(errbuf), "load failed - %s. ", pathname);
1182
1186
if (loadquery(L_GETMESSAGES, &message[0], sizeof(message)) != -1) {
1203
#if defined _WIN32 && defined RUBY_EXPORT
1204
HANDLE rb_libruby_handle(void);
1207
rb_w32_check_imported(HMODULE ext, HMODULE mine)
1210
const IMAGE_IMPORT_DESCRIPTOR *desc;
1212
desc = ImageDirectoryEntryToData(ext, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
1213
if (!desc) return 0;
1214
while (desc->Name) {
1215
PIMAGE_THUNK_DATA pint = (PIMAGE_THUNK_DATA)((char *)ext + desc->Characteristics);
1216
PIMAGE_THUNK_DATA piat = (PIMAGE_THUNK_DATA)((char *)ext + desc->FirstThunk);
1217
while (piat->u1.Function) {
1218
PIMAGE_IMPORT_BY_NAME pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + (size_t)pint->u1.AddressOfData);
1219
static const char prefix[] = "rb_";
1220
const char *name = (const char *)pii->Name;
1221
if (strncmp(name, prefix, sizeof(prefix) - 1) == 0) {
1222
FARPROC addr = GetProcAddress(mine, name);
1223
if (addr) return (FARPROC)piat->u1.Function == addr;
1199
1234
#if defined(DLN_NEEDS_ALT_SEPARATOR) && DLN_NEEDS_ALT_SEPARATOR
1200
1235
#define translit_separator(src) do { \
1201
1236
char *tmp = ALLOCA_N(char, strlen(src) + 1), *p = tmp, c; \
1203
1238
*p++ = ((c = *file++) == '/') ? DLN_NEEDS_ALT_SEPARATOR : c; \
1208
1243
#define translit_separator(str) (void)(str)
1274
#if defined _WIN32 && defined RUBY_EXPORT
1275
if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
1276
FreeLibrary(handle);
1277
error = "incompatible library version";
1238
1282
if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
1239
1283
dln_loaderror("%s - %s\n%s", dln_strerror(), buf, file);