2
* FASL loader using rld() for NeXT
4
* Written by Noritake YONEZAWA (yonezawa@lsi.tmg.nec.co.jp)
7
* Modified by Noritake YONEZAWA (yonezawa@lsi.tmg.nec.co.jp)
13
#include <mach/mach.h>
14
#include <mach-o/loader.h>
15
#include <mach-o/rld.h>
19
#include <sys/types.h>
23
static unsigned long object_size, object_start;
26
my_address_func(size, headers_size)
28
unsigned long headers_size;
30
return (object_start =
31
(unsigned long)alloc_contblock(object_size = size + headers_size));
39
struct mach_header header;
41
struct load_command *load_command;
42
struct segment_command *segment_command;
43
struct section *section;
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);
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) {
62
fprintf(stderr, "section: %s, addr: 0x%08x, size: %d\n",
63
section->sectname, section->addr, section->size);
66
fseek(fp, section->offset, 0);
67
fread((char *)section->addr, section->size, 1, fp);
71
load_command = (struct load_command *)
72
((char *)load_command + load_command->cmdsize);
83
struct mach_header mach_header;
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;
91
int end_sec, end_ofile;
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);
100
fprintf(stderr, "seek_to_end_ofile(): failure reading Mach-O load commands\n");
103
load_command = (struct load_command *) hdrbuf;
104
for (cmd = 0; cmd < mach_header.ncmds; ++cmd) {
105
switch (load_command->cmd) {
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)
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)
120
end_sec = symtab_command->stroff + symtab_command->strsize;
121
if (end_sec > end_ofile)
125
symseg_command = (struct symseg_command *) load_command;
126
end_sec = symseg_command->offset + symseg_command->size;
127
if (end_sec > end_ofile)
131
load_command = (struct load_command *)
132
((char *)load_command + load_command->cmdsize);
135
fseek(fp, end_ofile, 0);
141
static char *library_search_path[] =
142
{"/lib", "/usr/lib", "/usr/local/lib", NULL};
144
#define strdup(string) strcpy((char *)malloc(strlen(string)+1),(string))
147
expand_library_filename(filename)
155
if (filename[0] == '-' && filename[1] == 'l') {
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);
166
fprintf(stderr, "%s\n", fullname);
169
if ((fd = open(fullname, O_RDONLY, 0)) > 0) {
171
return (strdup(fullname));
174
return (strdup(libname));
176
return (strdup(filename));
180
make_ofile_list(faslfile, argstr)
181
char *faslfile, *argstr;
188
ofile_list = (char **)calloc(1, sizeof(char *));
189
ofile_list[0] = strdup(faslfile);
191
if (argstr != NULL) {
193
while ((*argstr == ' ') && (*argstr != '\0'))
198
while ((*argstr != ' ') && (*argstr != '\0'))
201
ofile_list = (char **)realloc((void *)ofile_list,
202
(i + 1) * sizeof(char *));
203
ofile_list[i] = expand_library_filename(filename);
206
ofile_list = (char **)realloc((void *)ofile_list, (i + 1) * sizeof(char *));
207
ofile_list[i] = NULL;
212
free_ofile_list(ofile_list)
218
if (ofile_list[i] == NULL)
220
(void)free(ofile_list[i]);
222
(void)free(ofile_list);
227
print_ofile_list(ofile_list)
232
if (ofile_list == NULL)
234
fprintf(stderr, "ofiles: ");
236
if (ofile_list[i] == NULL)
238
fprintf(stderr, "(%s)", ofile_list[i]);
240
fprintf(stderr, "\n");
251
object *old_vs_base = vs_base;
252
object *old_vs_top = vs_top;
258
char tempfilename[40];
260
NXStream *err_stream;
262
struct mach_header *hdr;
264
stream = open_stream(pathname, smm_input, Cnil, sKerror);
265
fp = stream->sm.sm_fp;
267
seek_to_end_ofile(fp);
268
fasl_data = read_fasl_vector(stream);
271
pathname = coerce_to_pathname(stream);
272
coerce_to_filename(stream, filename);
274
if ((err_stream = NXOpenFile(fileno(stderr), NX_WRITEONLY)) == 0)
275
FEerror("NXOpenFile() failed", 0);
277
sprintf(tempfilename, "/tmp/fasltemp%d", getpid());
278
rld_address_func(my_address_func);
279
ofiles = make_ofile_list(filename, NULL);
281
print_ofile_list(ofiles);
283
if (!rld_load(err_stream, &hdr, ofiles, tempfilename)) {
284
free_ofile_list(ofiles);
287
FEerror("rld_load() failed", 0);
289
free_ofile_list(ofiles);
290
load_mach_o(tempfilename);
291
unlink(tempfilename);
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)) {
302
FEerror("Can't find init code", 0);
305
(void)rld_unload_all(err_stream, 0);
312
extern char *mach_brkpt, *mach_maplimit, *core_end;
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);
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;
335
call_init(entry - object_start, memory, fasl_data,0);
337
if (symbol_value(sLAload_verboseA) != Cnil)
338
printf("start address -T 0x%08x ", entry);
340
vs_base = old_vs_base;
342
close_stream(stream);
347
faslink(pathname, ldargstring)
348
object pathname, ldargstring;
351
object *old_vs_base = vs_base;
352
object *old_vs_top = vs_top;
359
char tempfilename[40];
361
NXStream *err_stream;
363
struct mach_header *hdr;
365
stream = open_stream(pathname, smm_input, Cnil, sKerror);
366
fp = stream->sm.sm_fp;
368
seek_to_end_ofile(fp);
369
fasl_data = read_fasl_vector(stream);
372
pathname = coerce_to_pathname(stream);
373
coerce_to_filename(stream, filename);
374
coerce_to_filename(ldargstring, ldargstr);
376
if ((err_stream = NXOpenFile(fileno(stderr), NX_WRITEONLY)) == 0)
377
FEerror("NXOpenFile() failed", 0);
379
sprintf(tempfilename, "/tmp/fasltemp%d", getpid());
380
rld_address_func(my_address_func);
381
ofiles = make_ofile_list(filename, ldargstr);
383
print_ofile_list(ofiles);
385
if (!rld_load(err_stream, &hdr, ofiles, tempfilename)) {
386
free_ofile_list(ofiles);
389
FEerror("rld_load() failed", 0);
391
free_ofile_list(ofiles);
392
load_mach_o(tempfilename);
393
unlink(tempfilename);
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)) {
404
FEerror("Can't find init code", 0);
407
(void)rld_unload_all(err_stream, 0);
414
extern char *mach_brkpt, *mach_maplimit, *core_end;
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);
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;
437
call_init(entry - object_start, memory, fasl_data,0);
439
if (symbol_value(sLAload_verboseA) != Cnil)
440
printf("start address -T 0x%08x \n", entry);
442
vs_base = old_vs_base;
444
close_stream(stream);
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);
466
vs_push(make_fixnum(i));