1 /* $NetBSD: mdsetimage.c,v 1.18 2008/07/21 13:36:59 lukem Exp $ */
4 * Copyright (c) 1996 Christopher G. Demetriou
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1996\
35 Christopher G. Demetriou. All rights reserved.");
39 __RCSID("$NetBSD: mdsetimage.c,v 1.18 2008/07/21 13:36:59 lukem Exp $");
42 #include <sys/types.h>
56 int main
__P((int, char *[]));
57 static void usage
__P((void)) __dead
;
58 static int find_md_root
__P((const char *, const char *, size_t,
59 const struct nlist
*, size_t *, u_int32_t
*));
61 static struct nlist md_root_nlist
[] = {
62 #define X_MD_ROOT_IMAGE 0
63 { "_md_root_image", 0, 0, 0, 0 },
64 #define X_MD_ROOT_SIZE 1
65 { "_md_root_size", 0, 0, 0, 0 },
72 * Since we can't get the text address from an a.out executable, we
73 * need to be able to specify it. Note: there's no way to test to
74 * see if the user entered a valid address!
76 int T_flag_specified
; /* the -T flag was specified */
77 u_long text_start
; /* Start of kernel text */
78 #endif /* NLIST_AOUT */
85 struct stat ksb
, fssb
;
86 size_t md_root_offset
;
87 u_int32_t md_root_size
;
88 const char *kfile
, *fsfile
;
90 int ch
, kfd
, fsfd
, rv
;
94 while ((ch
= getopt(argc
, argv
, "T:v")) != -1)
101 T_flag_specified
= 1;
102 text_start
= strtoul(optarg
, NULL
, 0);
104 #endif /* NLIST_AOUT */
118 if ((kfd
= open(kfile
, O_RDWR
, 0)) == -1)
119 err(1, "open %s", kfile
);
121 if ((rv
= __fdnlist(kfd
, md_root_nlist
)) != 0)
122 errx(1, "could not find symbols in %s", kfile
);
124 fprintf(stderr
, "got symbols from %s\n", kfile
);
126 if (fstat(kfd
, &ksb
) == -1)
127 err(1, "fstat %s", kfile
);
128 if (ksb
.st_size
!= (size_t)ksb
.st_size
)
129 errx(1, "%s too big to map", kfile
);
131 if ((mappedkfile
= mmap(NULL
, ksb
.st_size
, PROT_READ
| PROT_WRITE
,
132 MAP_FILE
| MAP_SHARED
, kfd
, 0)) == (caddr_t
)-1)
133 err(1, "mmap %s", kfile
);
135 fprintf(stderr
, "mapped %s\n", kfile
);
137 if (find_md_root(kfile
, mappedkfile
, ksb
.st_size
, md_root_nlist
,
138 &md_root_offset
, &md_root_size
) != 0)
139 errx(1, "could not find md root buffer in %s", kfile
);
141 if ((fsfd
= open(fsfile
, O_RDONLY
, 0)) == -1)
142 err(1, "open %s", fsfile
);
143 if (fstat(fsfd
, &fssb
) == -1)
144 err(1, "fstat %s", fsfile
);
145 if (fssb
.st_size
!= (size_t)fssb
.st_size
)
146 errx(1, "fs image is too big");
147 if (fssb
.st_size
> md_root_size
)
148 errx(1, "fs image (%lld bytes) too big for buffer (%lu bytes)",
149 (long long)fssb
.st_size
, (unsigned long)md_root_size
);
152 fprintf(stderr
, "copying image from %s into %s\n", fsfile
,
154 if ((rv
= read(fsfd
, mappedkfile
+ md_root_offset
,
155 fssb
.st_size
)) != fssb
.st_size
) {
157 err(1, "read %s", fsfile
);
159 errx(1, "unexpected EOF reading %s", fsfile
);
162 fprintf(stderr
, "done copying image\n");
166 munmap(mappedkfile
, ksb
.st_size
);
170 fprintf(stderr
, "exiting\n");
179 "usage: %s kernel_file fsimage_file\n",
187 int (*check
) __P((const char *, size_t));
188 int (*findoff
) __P((const char *, size_t, u_long
, size_t *));
191 { "a.out", check_aout
, findoff_aout
, },
194 { "ECOFF", check_ecoff
, findoff_ecoff
, },
197 { "ELF32", check_elf32
, findoff_elf32
, },
200 { "ELF64", check_elf64
, findoff_elf64
, },
203 { "COFF", check_coff
, findoff_coff
, },
208 find_md_root(fname
, mappedfile
, mappedsize
, nl
, rootoffp
, rootsizep
)
209 const char *fname
, *mappedfile
;
211 const struct nlist
*nl
;
213 u_int32_t
*rootsizep
;
218 n
= sizeof exec_formats
/ sizeof exec_formats
[0];
219 for (i
= 0; i
< n
; i
++) {
220 if ((*exec_formats
[i
].check
)(mappedfile
, mappedsize
) == 0)
224 warnx("%s: unknown executable format", fname
);
229 fprintf(stderr
, "%s is an %s binary\n", fname
,
230 exec_formats
[i
].name
);
232 if (T_flag_specified
)
233 fprintf(stderr
, "kernel text loads at 0x%lx\n",
238 if ((*exec_formats
[i
].findoff
)(mappedfile
, mappedsize
,
239 nl
[X_MD_ROOT_SIZE
].n_value
, &rootsizeoff
) != 0) {
240 warnx("couldn't find offset for %s in %s",
241 nl
[X_MD_ROOT_SIZE
].n_name
, fname
);
245 fprintf(stderr
, "%s is at offset %#lx in %s\n",
246 nl
[X_MD_ROOT_SIZE
].n_name
,
247 (unsigned long)rootsizeoff
, fname
);
248 *rootsizep
= *(const u_int32_t
*)&mappedfile
[rootsizeoff
];
250 fprintf(stderr
, "%s has value %#x\n",
251 nl
[X_MD_ROOT_SIZE
].n_name
, *rootsizep
);
253 if ((*exec_formats
[i
].findoff
)(mappedfile
, mappedsize
,
254 nl
[X_MD_ROOT_IMAGE
].n_value
, rootoffp
) != 0) {
255 warnx("couldn't find offset for %s in %s",
256 nl
[X_MD_ROOT_IMAGE
].n_name
, fname
);
260 fprintf(stderr
, "%s is at offset %#lx in %s\n",
261 nl
[X_MD_ROOT_IMAGE
].n_name
,
262 (unsigned long)(*rootoffp
), fname
);