~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to dln.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  dln.c -
4
4
 
5
 
  $Author: yugui $
 
5
  $Author: nobu $
6
6
  created at: Tue Jan 18 17:05:06 JST 1994
7
7
 
8
8
  Copyright (C) 1993-2007 Yukihiro Matsumoto
57
57
#include <sys/stat.h>
58
58
 
59
59
#ifndef S_ISDIR
60
 
#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
 
60
#   define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
61
61
#endif
62
62
 
63
63
#ifdef HAVE_SYS_PARAM_H
107
107
 
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_"
111
111
# else
112
 
#  define FUNCNAME_PATTERN "Init_%s"
 
112
#  define FUNCNAME_PREFIX "Init_"
113
113
# endif
114
114
#endif
115
115
 
 
116
#if defined __CYGWIN__ || defined DOSISH
 
117
#define isdirsep(x) ((x) == '/' || (x) == '\\')
 
118
#else
 
119
#define isdirsep(x) ((x) == '/')
 
120
#endif
 
121
 
116
122
static size_t
117
 
init_funcname_len(char **buf, const char *file)
 
123
init_funcname_len(const char **file)
118
124
{
119
 
    char *p;
120
 
    const char *slash;
121
 
    size_t len;
 
125
    const char *p = *file, *base, *dot = NULL;
122
126
 
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;
126
 
 
127
 
    len = strlen(FUNCNAME_PATTERN) + strlen(slash + 1);
128
 
    *buf = xmalloc(len);
129
 
    snprintf(*buf, len, FUNCNAME_PATTERN, slash + 1);
130
 
    for (p = *buf; *p; p++) {         /* Delete suffix if it exists */
131
 
        if (*p == '.') {
132
 
            *p = '\0'; break;
133
 
        }
 
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;
134
131
    }
135
 
    return p - *buf;
 
132
    *file = base;
 
133
    /* Delete suffix if it exists */
 
134
    return (dot ? dot : p) - base;
136
135
}
137
136
 
 
137
static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX;
 
138
 
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);\
141
144
    if (!tmp) {\
142
 
        free(*buf);\
143
145
        dln_memerror();\
144
146
    }\
145
 
    strlcpy(tmp, *buf, len + 1);\
146
 
    free(*buf);\
147
 
    *buf = tmp;\
 
147
    memcpy(tmp, funcname_prefix, plen);\
 
148
    memcpy(tmp+plen, base, flen);\
 
149
    tmp[plen+flen] = '\0';\
 
150
    *(buf) = tmp;\
148
151
} while (0)
149
152
 
150
153
#ifdef USE_DLN_A_OUT
1116
1119
 
1117
1120
#if defined _WIN32 && !defined __CYGWIN__
1118
1121
#include <windows.h>
 
1122
#include <imagehlp.h>
1119
1123
#endif
1120
1124
 
1121
 
#if ! defined _AIX
 
1125
#if defined _WIN32 && !defined __CYGWIN__
 
1126
static const char *
 
1127
dln_strerror(char *message, size_t size)
 
1128
{
 
1129
    int error = GetLastError();
 
1130
    char *p = message;
 
1131
    size_t len = snprintf(message, size, "%d: ", error);
 
1132
 
 
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')
 
1141
            *p = ' ';
 
1142
    }
 
1143
    return message;
 
1144
}
 
1145
#define dln_strerror() dln_strerror(message, sizeof message)
 
1146
#elif ! defined _AIX
1122
1147
static const char *
1123
1148
dln_strerror(void)
1124
1149
{
1146
1171
#ifdef USE_DLN_DLOPEN
1147
1172
    return (char*)dlerror();
1148
1173
#endif
1149
 
 
1150
 
#if defined _WIN32 && !defined __CYGWIN__
1151
 
    static char message[1024];
1152
 
    int error = GetLastError();
1153
 
    char *p = message;
1154
 
    p += sprintf(message, "%d: ", error);
1155
 
    FormatMessage(
1156
 
        FORMAT_MESSAGE_FROM_SYSTEM       | FORMAT_MESSAGE_IGNORE_INSERTS,
1157
 
        NULL,
1158
 
        error,
1159
 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1160
 
        p,
1161
 
        sizeof message - strlen(message),
1162
 
        NULL);
1163
 
 
1164
 
    for (p = message; *p; p++) {
1165
 
        if (*p == '\n' || *p == '\r')
1166
 
            *p = ' ';
1167
 
    }
1168
 
    return message;
1169
 
#endif
1170
1174
}
1171
1175
#endif
1172
1176
 
1176
1180
{
1177
1181
  char *message[1024], errbuf[1024];
1178
1182
  int i;
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);
1181
1185
 
1182
1186
  if (loadquery(L_GETMESSAGES, &message[0], sizeof(message)) != -1) {
1196
1200
}
1197
1201
#endif
1198
1202
 
 
1203
#if defined _WIN32 && defined RUBY_EXPORT
 
1204
HANDLE rb_libruby_handle(void);
 
1205
 
 
1206
static int
 
1207
rb_w32_check_imported(HMODULE ext, HMODULE mine)
 
1208
{
 
1209
    ULONG size;
 
1210
    const IMAGE_IMPORT_DESCRIPTOR *desc;
 
1211
 
 
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;
 
1224
            }
 
1225
            piat++;
 
1226
            pint++;
 
1227
        }
 
1228
        desc++;
 
1229
    }
 
1230
    return 1;
 
1231
}
 
1232
#endif
 
1233
 
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; \
1202
1237
        do { \
1203
1238
            *p++ = ((c = *file++) == '/') ? DLN_NEEDS_ALT_SEPARATOR : c; \
1204
1239
        } while (c); \
1205
 
        src = tmp; \
 
1240
        (src) = tmp; \
1206
1241
    } while (0)
1207
1242
#else
1208
1243
#define translit_separator(str) (void)(str)
1219
1254
#if defined _WIN32 && !defined __CYGWIN__
1220
1255
    HINSTANCE handle;
1221
1256
    char winfile[MAXPATHLEN];
 
1257
    char message[1024];
1222
1258
    void (*init_fct)();
1223
1259
    char *buf;
1224
1260
 
1235
1271
        goto failed;
1236
1272
    }
1237
1273
 
 
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";
 
1278
        goto failed;
 
1279
    }
 
1280
#endif
 
1281
 
1238
1282
    if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
1239
1283
        dln_loaderror("%s - %s\n%s", dln_strerror(), buf, file);
1240
1284
    }