]> git.saurik.com Git - apple/boot.git/blob - i386/tests/rldtest.c
ecaecf1e7a0145f6e142b2d9fcb99a49e9c806cc
[apple/boot.git] / i386 / tests / rldtest.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /* test of standalone rld
26 * usage: rldtest <sarld> <kernel> <driver>
27 *
28 */
29
30 #include <stdio.h>
31 #include <streams/streams.h>
32 #include <mach-o/loader.h>
33
34 extern int errno;
35
36 typedef unsigned int entry_t;
37 struct mach_header head;
38
39 #define zalloc(a) malloc(a)
40 #define zfree(a) free(a)
41 #define xread read
42
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44
45 extern void *malloc(int size);
46 loadmacho(
47 struct mach_header *head,
48 int dev,
49 int io,
50 entry_t *rentry,
51 char **raddr,
52 int *rsize,
53 int file_offset
54 )
55 {
56 int ncmds;
57 unsigned cmds, cp;
58 struct xxx_thread_command {
59 unsigned long cmd;
60 unsigned long cmdsize;
61 unsigned long flavor;
62 unsigned long count;
63 i386_thread_state_t state;
64 } *th;
65 unsigned int entry;
66 int size, vmsize = 0;
67 unsigned int vmaddr = ~0;
68
69 // XXX should check cputype
70 cmds = (unsigned int) zalloc(head->sizeofcmds);
71 b_lseek(io, sizeof (struct mach_header) + file_offset, 0);
72
73 if (read(io, cmds, head->sizeofcmds) != head->sizeofcmds)
74 {printf("error reading commands\n");
75 goto shread;}
76
77 for (ncmds = head->ncmds, cp = cmds; ncmds > 0; ncmds--)
78 {
79 unsigned int addr;
80
81 // putchar('.');
82
83 #define lcp ((struct load_command *)cp)
84 switch (lcp->cmd)
85 {
86
87 case LC_SEGMENT:
88 #define scp ((struct segment_command *)cp)
89
90 addr = (scp->vmaddr & 0x3fffffff) + (int)*raddr;
91 if (scp->filesize) {
92 // Is this an OK assumption?
93 // if the filesize is zero, it doesn't
94 // take up any virtual space...
95 // (Hopefully this only excludes PAGEZERO.)
96 // Also, ignore linkedit segment when
97 // computing size, because we will erase
98 // the linkedit segment later.
99 if(strncmp(scp->segname, SEG_LINKEDIT,
100 sizeof(scp->segname)) != 0)
101 vmsize += scp->vmsize;
102 vmaddr = min(vmaddr, addr);
103
104 // Zero any space at the end of the segment.
105 bzero((char *)(addr + scp->filesize),
106 scp->vmsize - scp->filesize);
107
108 // FIXME: check to see if we overflow
109 // the available space (should be passed in
110 // as the size argument).
111
112 b_lseek(io, scp->fileoff + file_offset, 0);
113 if (xread(io, (char *)addr, scp->filesize)
114 != scp->filesize) {
115 printf("Error loading section\n");
116 printf("File size =%x; fileoff_set=%x; addr=%x\n",
117 scp->filesize, scp->fileoff, addr);
118 goto shread;
119 }
120 }
121 break;
122
123 case LC_THREAD:
124 case LC_UNIXTHREAD:
125 th = (struct xxx_thread_command *)cp;
126 entry = th->state.eip;
127 break;
128 }
129
130 cp += lcp->cmdsize;
131 }
132
133 // kernBootStruct->rootdev = (dev & 0xffffff00) | devMajor[Dev(dev)];
134
135 zfree((char *)cmds);
136 *rentry = (entry_t)( (int) entry & 0x3fffffff );
137 *rsize = vmsize;
138 *raddr = (char *)vmaddr;
139 return 0;
140
141 shread:
142 zfree((char *)cmds);
143 printf("Read error\n");
144 return -1;
145 }
146
147 loadprog(
148 int dev,
149 int fd,
150 entry_t *entry, // entry point
151 char **addr, // load address
152 int *size // size of loaded program
153 )
154 {
155 /* get file header */
156 read(fd, &head, sizeof(head));
157
158 if (head.magic == MH_MAGIC) {
159 return loadmacho((struct mach_header *) &head,
160 dev, fd, entry, addr, size,0);
161 }
162
163 else if (head.magic == 0xbebafeca)
164 {
165 printf("no fat binary support yet\n");
166 return -1;
167 }
168
169 printf("unrecognized binary format\n");
170 return -1;
171 }
172
173 #define DRIVER "/usr/Devices/EtherExpress16.config/EtherExpress16_reloc"
174
175 void usage(void)
176 {
177 fprintf(stderr,"usage: rldtest <sarld> <kernel> <driver>\n");
178 exit(1);
179 }
180
181 main(int argc, char **argv)
182 {
183 int fd;
184 char *mem, *workmem, *ebuf;
185 char *laddr, *kaddr, *daddr;
186 NXStream *str;
187 struct mach_header *mh;
188 int ret, size, ksize, dsize, count;
189 entry_t entry;
190 int (*fn)();
191 struct section *sp;
192 char *kernel, *sarld, *driver;
193
194 if (argc != 4)
195 usage();
196 sarld = argv[1];
197 kernel = argv[2];
198 driver = argv[3];
199 mem = malloc(1024 * 1024 * 16);
200 printf("mem = %x\n",mem);
201 laddr = (char *)0x0;
202 fd = open(sarld,0);
203 if (fd < 0) {
204 fprintf(stderr, "couldn't open sarld %s, error %d\n",sarld,errno);
205 exit(1);
206 }
207 printf("fd = %d\n",fd);
208 loadprog(0, fd, &entry, &laddr, &size);
209 close(fd);
210 printf("entry = %x, laddr = %x, size = %d\n",entry, laddr, size);
211 fn = (int (*)())entry;
212 fd = open(kernel,0);
213 if (fd < 0) {
214 fprintf(stderr, "couldn't open kernel %s, error %d\n",kernel,errno);
215 exit(1);
216 }
217 kaddr = 0;
218 loadprog(0, fd, &entry, &kaddr, &ksize);
219 printf("entry = %x, kaddr = %x, ksize = %d\n",entry, kaddr, ksize);
220 close(fd);
221 daddr = (char *)0x70000;
222 fd = open(driver,0);
223 if (fd < 0) {
224 fprintf(stderr, "couldn't open driver %s, error %d\n",driver,errno);
225 exit(1);
226 }
227 size = 0;
228 do {
229 count = read(fd, daddr, 65536);
230 daddr += count;
231 size += count;
232 } while (count > 0);
233 daddr = (char *)0x70000;
234 printf("entry = %x, daddr = %x, size = %d\n",entry, daddr, size);
235 close(fd);
236 workmem = malloc(300 * 1024);
237 ebuf = malloc(64 * 1024);
238 ebuf[0] = 0;
239 dsize = 16 * 1024 * 1024 - (int)kaddr - (int)ksize;
240 printf("about to call %x\n",fn);
241 ret = (*fn)( "mach_kernel", kaddr,
242 "driver", daddr, size,
243 kaddr + ksize, &dsize,
244 ebuf, 64 * 1024,
245 workmem, 300 * 1024
246 );
247 printf("rld return: %d '%s'\n",ret, ebuf);
248
249 #define SEG_OBJC "__OBJC"
250 sp = getsectbyname ("__TEXT", "__text");
251 printf("text section: %s\n",sp->sectname);
252 sp = getsectbynamefromheader (kaddr+ksize, "__OBJC", "__module_info");
253 printf("objc section: %s\n",sp->sectname);
254 sp = getsectdatafromheader (kaddr+ksize,
255 SEG_OBJC, "__module_info", &size);
256 printf("objc section: %s\n",sp->sectname);
257
258 printf("getsectdata ret = %d\n",sp);
259 free(mem);
260 }