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