~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to o/NeXTunixfasl.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * FASL loader using rld() for NeXT
 
3
 *
 
4
 * Written by Noritake YONEZAWA (yonezawa@lsi.tmg.nec.co.jp)
 
5
 * February 14, 1992
 
6
 * 
 
7
 * Modified by Noritake YONEZAWA (yonezawa@lsi.tmg.nec.co.jp)
 
8
 * May 1, 1995
 
9
 * June 5, 1995
 
10
 * June 6, 1995
 
11
 */
 
12
 
 
13
#include <mach/mach.h>
 
14
#include <mach-o/loader.h>
 
15
#include <mach-o/rld.h>
 
16
 
 
17
#include <ar.h>
 
18
#include <nlist.h>
 
19
#include <sys/types.h>
 
20
#include <sys/file.h>
 
21
#include <strings.h>
 
22
 
 
23
static unsigned long object_size, object_start;
 
24
 
 
25
static unsigned long
 
26
my_address_func(size, headers_size)
 
27
    unsigned long       size;
 
28
    unsigned long       headers_size;
 
29
{
 
30
    return (object_start =
 
31
            (unsigned long)alloc_contblock(object_size = size + headers_size));
 
32
}
 
33
 
 
34
static void
 
35
load_mach_o(filename)
 
36
    char               *filename;
 
37
{
 
38
    FILE               *fp;
 
39
    struct mach_header  header;
 
40
    char               *hdrbuf;
 
41
    struct load_command *load_command;
 
42
    struct segment_command *segment_command;
 
43
    struct section     *section;
 
44
    int                 len, cmd, seg;
 
45
 
 
46
    if ((fp = fopen(filename, "r")) == NULL)
 
47
        FEerror("Can't read Mach-O object file", 0);
 
48
    len = fread((char *)&header, sizeof(struct mach_header), 1, fp);
 
49
    if (len == 1 && header.magic == MH_MAGIC) {
 
50
        hdrbuf = (char *)malloc(header.sizeofcmds);
 
51
        len = fread(hdrbuf, header.sizeofcmds, 1, fp);
 
52
        if (len != 1)
 
53
            FEerror("failure reading Mach-O load commands", 0);
 
54
        load_command = (struct load_command *) hdrbuf;
 
55
        for (cmd = 0; cmd < header.ncmds; ++cmd) {
 
56
            if (load_command->cmd == LC_SEGMENT) {
 
57
                segment_command = (struct segment_command *) load_command;
 
58
                section = (struct section *) ((char *)(segment_command + 1));
 
59
                for (seg = 0; seg < segment_command->nsects; ++seg, ++section) {
 
60
                    if (section->size != 0 && section->offset != 0) {
 
61
#ifdef DEBUG
 
62
                        fprintf(stderr, "section: %s, addr: 0x%08x, size: %d\n",
 
63
                           section->sectname, section->addr, section->size);
 
64
                        fflush(stderr);
 
65
#endif
 
66
                        fseek(fp, section->offset, 0);
 
67
                        fread((char *)section->addr, section->size, 1, fp);
 
68
                    }
 
69
                }
 
70
            }
 
71
            load_command = (struct load_command *)
 
72
              ((char *)load_command + load_command->cmdsize);
 
73
        }
 
74
        free(hdrbuf);
 
75
    }
 
76
    (void)fclose(fp);
 
77
}
 
78
 
 
79
int
 
80
seek_to_end_ofile(fp)
 
81
    FILE               *fp;
 
82
{
 
83
    struct mach_header  mach_header;
 
84
    char               *hdrbuf;
 
85
    struct load_command *load_command;
 
86
    struct segment_command *segment_command;
 
87
    struct section     *section;
 
88
    struct symtab_command *symtab_command;
 
89
    struct symseg_command *symseg_command;
 
90
    int                 len, cmd, seg;
 
91
    int                 end_sec, end_ofile;
 
92
 
 
93
    end_ofile = 0;
 
94
    fseek(fp, 0L, 0);
 
95
    len = fread((char *)&mach_header, sizeof(struct mach_header), 1, fp);
 
96
    if (len == 1 && mach_header.magic == MH_MAGIC) {
 
97
        hdrbuf = (char *)malloc(mach_header.sizeofcmds);
 
98
        len = fread(hdrbuf, mach_header.sizeofcmds, 1, fp);
 
99
        if (len != 1) {
 
100
            fprintf(stderr, "seek_to_end_ofile(): failure reading Mach-O load commands\n");
 
101
            return 0;
 
102
        }
 
103
        load_command = (struct load_command *) hdrbuf;
 
104
        for (cmd = 0; cmd < mach_header.ncmds; ++cmd) {
 
105
            switch (load_command->cmd) {
 
106
            case LC_SEGMENT:
 
107
                segment_command = (struct segment_command *) load_command;
 
108
                section = (struct section *) ((char *)(segment_command + 1));
 
109
                for (seg = 0; seg < segment_command->nsects; ++seg, ++section) {
 
110
                    end_sec = section->offset + section->size;
 
111
                    if (end_sec > end_ofile)
 
112
                        end_ofile = end_sec;
 
113
                }
 
114
                break;
 
115
            case LC_SYMTAB:
 
116
                symtab_command = (struct symtab_command *) load_command;
 
117
                end_sec = symtab_command->symoff + symtab_command->nsyms * sizeof(struct nlist);
 
118
                if (end_sec > end_ofile)
 
119
                    end_ofile = end_sec;
 
120
                end_sec = symtab_command->stroff + symtab_command->strsize;
 
121
                if (end_sec > end_ofile)
 
122
                    end_ofile = end_sec;
 
123
                break;
 
124
            case LC_SYMSEG:
 
125
                symseg_command = (struct symseg_command *) load_command;
 
126
                end_sec = symseg_command->offset + symseg_command->size;
 
127
                if (end_sec > end_ofile)
 
128
                    end_ofile = end_sec;
 
129
                break;
 
130
            }
 
131
            load_command = (struct load_command *)
 
132
              ((char *)load_command + load_command->cmdsize);
 
133
        }
 
134
        free(hdrbuf);
 
135
        fseek(fp, end_ofile, 0);
 
136
        return 1;
 
137
    }
 
138
    return 0;
 
139
}
 
140
 
 
141
static char        *library_search_path[] =
 
142
{"/lib", "/usr/lib", "/usr/local/lib", NULL};
 
143
 
 
144
#define strdup(string)  strcpy((char *)malloc(strlen(string)+1),(string))
 
145
 
 
146
static char        *
 
147
expand_library_filename(filename)
 
148
    char               *filename;
 
149
{
 
150
    int                 fd;
 
151
    char              **dir;
 
152
    char                libname[256];
 
153
    char                fullname[256];
 
154
 
 
155
    if (filename[0] == '-' && filename[1] == 'l') {
 
156
        filename++;
 
157
        filename++;
 
158
        strcpy(libname, "lib");
 
159
        strcat(libname, filename);
 
160
        strcat(libname, ".a");
 
161
        for (dir = library_search_path; *dir; dir++) {
 
162
            strcpy(fullname, *dir);
 
163
            strcat(fullname, "/");
 
164
            strcat(fullname, libname);
 
165
#ifdef DEBUG
 
166
            fprintf(stderr, "%s\n", fullname);
 
167
            fflush(stderr);
 
168
#endif
 
169
            if ((fd = open(fullname, O_RDONLY, 0)) > 0) {
 
170
                close(fd);
 
171
                return (strdup(fullname));
 
172
            }
 
173
        }
 
174
        return (strdup(libname));
 
175
    }
 
176
    return (strdup(filename));
 
177
}
 
178
 
 
179
static char       **
 
180
make_ofile_list(faslfile, argstr)
 
181
    char               *faslfile, *argstr;
 
182
{
 
183
    char                filename[256];
 
184
    char               *dst;
 
185
    int                 i;
 
186
    char              **ofile_list;
 
187
 
 
188
    ofile_list = (char **)calloc(1, sizeof(char *));
 
189
    ofile_list[0] = strdup(faslfile);
 
190
    i = 1;
 
191
    if (argstr != NULL) {
 
192
        for (;; i++) {
 
193
            while ((*argstr == ' ') && (*argstr != '\0'))
 
194
                argstr++;
 
195
            if (*argstr == '\0')
 
196
                break;
 
197
            dst = filename;
 
198
            while ((*argstr != ' ') && (*argstr != '\0'))
 
199
                *dst++ = *argstr++;
 
200
            *dst = '\0';
 
201
            ofile_list = (char **)realloc((void *)ofile_list,
 
202
                                          (i + 1) * sizeof(char *));
 
203
            ofile_list[i] = expand_library_filename(filename);
 
204
        }
 
205
    }
 
206
    ofile_list = (char **)realloc((void *)ofile_list, (i + 1) * sizeof(char *));
 
207
    ofile_list[i] = NULL;
 
208
    return (ofile_list);
 
209
}
 
210
 
 
211
static void
 
212
free_ofile_list(ofile_list)
 
213
    char              **ofile_list;
 
214
{
 
215
    int                 i;
 
216
 
 
217
    for (i = 1;; i++) {
 
218
        if (ofile_list[i] == NULL)
 
219
            break;
 
220
        (void)free(ofile_list[i]);
 
221
    }
 
222
    (void)free(ofile_list);
 
223
}
 
224
 
 
225
#ifdef DEBUG
 
226
static void
 
227
print_ofile_list(ofile_list)
 
228
    char              **ofile_list;
 
229
{
 
230
    int                 i;
 
231
 
 
232
    if (ofile_list == NULL)
 
233
        return;
 
234
    fprintf(stderr, "ofiles: ");
 
235
    for (i = 0;; i++) {
 
236
        if (ofile_list[i] == NULL)
 
237
            break;
 
238
        fprintf(stderr, "(%s)", ofile_list[i]);
 
239
    }
 
240
    fprintf(stderr, "\n");
 
241
    fflush(stderr);
 
242
}
 
243
 
 
244
#endif
 
245
 
 
246
int
 
247
fasload(pathname)
 
248
    object              pathname;
 
249
{
 
250
    FILE               *fp;
 
251
    object             *old_vs_base = vs_base;
 
252
    object             *old_vs_top = vs_top;
 
253
    object              memory;
 
254
    object              fasl_data;
 
255
    object              stream;
 
256
    char                entryname[100];
 
257
    char                filename[256];
 
258
    char                tempfilename[40];
 
259
    char              **ofiles;
 
260
    NXStream           *err_stream;
 
261
    void                (*entry) ();
 
262
    struct mach_header *hdr;
 
263
 
 
264
    stream = open_stream(pathname, smm_input, Cnil, sKerror);
 
265
    fp = stream->sm.sm_fp;
 
266
 
 
267
    seek_to_end_ofile(fp);
 
268
    fasl_data = read_fasl_vector(stream);
 
269
    vs_push(fasl_data);
 
270
 
 
271
    pathname = coerce_to_pathname(stream);
 
272
    coerce_to_filename(stream, filename);
 
273
 
 
274
    if ((err_stream = NXOpenFile(fileno(stderr), NX_WRITEONLY)) == 0)
 
275
        FEerror("NXOpenFile() failed", 0);
 
276
 
 
277
    sprintf(tempfilename, "/tmp/fasltemp%d", getpid());
 
278
    rld_address_func(my_address_func);
 
279
    ofiles = make_ofile_list(filename, NULL);
 
280
#ifdef DEBUG
 
281
    print_ofile_list(ofiles);
 
282
#endif
 
283
    if (!rld_load(err_stream, &hdr, ofiles, tempfilename)) {
 
284
        free_ofile_list(ofiles);
 
285
        NXFlush(err_stream);
 
286
        NXClose(err_stream);
 
287
        FEerror("rld_load() failed", 0);
 
288
    }
 
289
    free_ofile_list(ofiles);
 
290
    load_mach_o(tempfilename);
 
291
    unlink(tempfilename);
 
292
 
 
293
    strcpy(entryname, "_init_code");
 
294
    if (!rld_lookup(err_stream, entryname, (unsigned long *)&entry)) {
 
295
        strcpy(entryname, "_init_");
 
296
        bcopy(pathname->pn.pn_name->st.st_self,
 
297
              entryname + 6, pathname->pn.pn_name->st.st_fillp);
 
298
        entryname[6 + pathname->pn.pn_name->st.st_fillp] = 0;
 
299
        if (!rld_lookup(err_stream, entryname, (unsigned long *)&entry)) {
 
300
            NXFlush(err_stream);
 
301
            NXClose(err_stream);
 
302
            FEerror("Can't find init code", 0);
 
303
        }
 
304
    }
 
305
    (void)rld_unload_all(err_stream, 0);
 
306
    NXFlush(err_stream);
 
307
    NXClose(err_stream);
 
308
 
 
309
 
 
310
#ifdef DEBUG
 
311
    {
 
312
        extern char        *mach_brkpt, *mach_maplimit, *core_end;
 
313
 
 
314
        fprintf(stderr, "mach_brkpt    : 0x%08x\n", mach_brkpt);
 
315
        fprintf(stderr, "mach_maplimit : 0x%08x\n", mach_maplimit);
 
316
        fprintf(stderr, "core_end      : 0x%08x\n", core_end);
 
317
        fprintf(stderr, "hdr           : 0x%08x\n", hdr);
 
318
        fprintf(stderr, "object_start  : 0x%08x\n", object_start);
 
319
        fprintf(stderr, "object_size   : %d\n", object_size);
 
320
        fprintf(stderr, "&%s   : 0x%08x\n", entryname, entry);
 
321
        fflush(stderr);
 
322
    }
 
323
#endif
 
324
 
 
325
    memory = alloc_object(t_cfdata);
 
326
    memory->cfd.cfd_self = 0;
 
327
    memory->cfd.cfd_fillp = 0;
 
328
    memory->cfd.cfd_size = object_size;
 
329
    memory->cfd.cfd_start = (char *)object_start;
 
330
    vs_push(memory);
 
331
 
 
332
#ifdef CLEAR_CACHE
 
333
    CLEAR_CACHE;
 
334
#endif
 
335
    call_init(entry - object_start, memory, fasl_data,0);
 
336
 
 
337
    if (symbol_value(sLAload_verboseA) != Cnil)
 
338
        printf("start address -T 0x%08x ", entry);
 
339
 
 
340
    vs_base = old_vs_base;
 
341
    vs_top = old_vs_top;
 
342
    close_stream(stream);
 
343
    return object_size;
 
344
}
 
345
 
 
346
int
 
347
faslink(pathname, ldargstring)
 
348
    object              pathname, ldargstring;
 
349
{
 
350
    FILE               *fp;
 
351
    object             *old_vs_base = vs_base;
 
352
    object             *old_vs_top = vs_top;
 
353
    object              memory;
 
354
    object              fasl_data;
 
355
    object              stream;
 
356
    char                entryname[100];
 
357
    char                filename[256];
 
358
    char                ldargstr[256];
 
359
    char                tempfilename[40];
 
360
    char              **ofiles;
 
361
    NXStream           *err_stream;
 
362
    void                (*entry) ();
 
363
    struct mach_header *hdr;
 
364
 
 
365
    stream = open_stream(pathname, smm_input, Cnil, sKerror);
 
366
    fp = stream->sm.sm_fp;
 
367
 
 
368
    seek_to_end_ofile(fp);
 
369
    fasl_data = read_fasl_vector(stream);
 
370
    vs_push(fasl_data);
 
371
 
 
372
    pathname = coerce_to_pathname(stream);
 
373
    coerce_to_filename(stream, filename);
 
374
    coerce_to_filename(ldargstring, ldargstr);
 
375
 
 
376
    if ((err_stream = NXOpenFile(fileno(stderr), NX_WRITEONLY)) == 0)
 
377
        FEerror("NXOpenFile() failed", 0);
 
378
 
 
379
    sprintf(tempfilename, "/tmp/fasltemp%d", getpid());
 
380
    rld_address_func(my_address_func);
 
381
    ofiles = make_ofile_list(filename, ldargstr);
 
382
#ifdef DEBUG
 
383
    print_ofile_list(ofiles);
 
384
#endif
 
385
    if (!rld_load(err_stream, &hdr, ofiles, tempfilename)) {
 
386
        free_ofile_list(ofiles);
 
387
        NXFlush(err_stream);
 
388
        NXClose(err_stream);
 
389
        FEerror("rld_load() failed", 0);
 
390
    }
 
391
    free_ofile_list(ofiles);
 
392
    load_mach_o(tempfilename);
 
393
    unlink(tempfilename);
 
394
 
 
395
    strcpy(entryname, "_init_code");
 
396
    if (!rld_lookup(err_stream, entryname, (unsigned long *)&entry)) {
 
397
        strcpy(entryname, "_init_");
 
398
        bcopy(pathname->pn.pn_name->st.st_self,
 
399
              entryname + 6, pathname->pn.pn_name->st.st_fillp);
 
400
        entryname[6 + pathname->pn.pn_name->st.st_fillp] = 0;
 
401
        if (!rld_lookup(err_stream, entryname, (unsigned long *)&entry)) {
 
402
            NXFlush(err_stream);
 
403
            NXClose(err_stream);
 
404
            FEerror("Can't find init code", 0);
 
405
        }
 
406
    }
 
407
    (void)rld_unload_all(err_stream, 0);
 
408
    NXFlush(err_stream);
 
409
    NXClose(err_stream);
 
410
 
 
411
 
 
412
#ifdef DEBUG
 
413
    {
 
414
        extern char        *mach_brkpt, *mach_maplimit, *core_end;
 
415
 
 
416
        fprintf(stderr, "mach_brkpt    : 0x%08x\n", mach_brkpt);
 
417
        fprintf(stderr, "mach_maplimit : 0x%08x\n", mach_maplimit);
 
418
        fprintf(stderr, "core_end      : 0x%08x\n", core_end);
 
419
        fprintf(stderr, "hdr           : 0x%08x\n", hdr);
 
420
        fprintf(stderr, "object_start  : 0x%08x\n", object_start);
 
421
        fprintf(stderr, "object_size   : %d\n", object_size);
 
422
        fprintf(stderr, "&%s   : 0x%08x\n", entryname, entry);
 
423
        fflush(stderr);
 
424
    }
 
425
#endif
 
426
 
 
427
    memory = alloc_object(t_cfdata);
 
428
    memory->cfd.cfd_self = 0;
 
429
    memory->cfd.cfd_fillp = 0;
 
430
    memory->cfd.cfd_size = object_size;
 
431
    memory->cfd.cfd_start = (char *)object_start;
 
432
    vs_push(memory);
 
433
 
 
434
#ifdef CLEAR_CACHE
 
435
    CLEAR_CACHE;
 
436
#endif
 
437
    call_init(entry - object_start, memory, fasl_data,0);
 
438
 
 
439
    if (symbol_value(sLAload_verboseA) != Cnil)
 
440
        printf("start address -T 0x%08x \n", entry);
 
441
 
 
442
    vs_base = old_vs_base;
 
443
    vs_top = old_vs_top;
 
444
    close_stream(stream);
 
445
    return object_size;
 
446
}
 
447
 
 
448
siLfaslink()
 
449
{
 
450
    bds_ptr             old_bds_top;
 
451
    int                 i;
 
452
    object              package;
 
453
 
 
454
    check_arg(2);
 
455
    check_type_or_pathname_string_symbol_stream(&vs_base[0]);
 
456
    check_type_string(&vs_base[1]);
 
457
    vs_base[0] = coerce_to_pathname(vs_base[0]);
 
458
    vs_base[0]->pn.pn_type = FASL_string;
 
459
    vs_base[0] = namestring(vs_base[0]);
 
460
    package = symbol_value(sLApackageA);
 
461
    old_bds_top = bds_top;
 
462
    bds_bind(sLApackageA, package);
 
463
    i = faslink(vs_base[0], vs_base[1]);
 
464
    bds_unwind(old_bds_top);
 
465
    vs_top = vs_base;
 
466
    vs_push(make_fixnum(i));
 
467
}
 
468
 
 
469
#define FASLINK