1 /* $NetBSD: mdsetimage.c,v 1.2 2010/11/06 16:03:23 uebayasi Exp $ */
2 /* from: NetBSD: mdsetimage.c,v 1.15 2001/03/21 23:46:48 cgd Exp $ */
5 * Copyright (c) 1996, 2002 Christopher G. Demetriou
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
33 #if HAVE_NBTOOL_CONFIG_H
34 #include "nbtool_config.h"
37 #include <sys/cdefs.h>
39 __COPYRIGHT("@(#) Copyright (c) 1996\
40 Christopher G. Demetriou. All rights reserved.");
41 __RCSID("$NetBSD: mdsetimage.c,v 1.2 2010/11/06 16:03:23 uebayasi Exp $");
44 #include <sys/types.h>
62 #define X_MD_ROOT_IMAGE 0
63 #define X_MD_ROOT_SIZE 1
65 #define CHUNKSIZE (64 * 1024)
67 int main(int, char *[]);
68 static void usage(void) __attribute__((noreturn
));
69 static int find_md_root(bfd
*, struct symbols symbols
[]);
75 static const char *progname
;
77 #define setprogname(x) (void)(progname = (x))
79 #define getprogname() (progname)
82 main(int argc
, char *argv
[])
84 int ch
, kfd
, fsfd
, rv
;
85 struct stat ksb
, fssb
;
86 size_t md_root_offset
, md_root_size_offset
;
87 u_int32_t md_root_size
;
88 const char *kfile
, *fsfile
;
93 struct symbols md_root_symbols
[3] = { { 0 } };
95 md_root_symbols
[X_MD_ROOT_IMAGE
].name
= "_md_root_image";
96 md_root_symbols
[X_MD_ROOT_SIZE
].name
= "_md_root_size";
100 while ((ch
= getopt(argc
, argv
, "I:S:b:svx")) != -1)
103 md_root_symbols
[X_MD_ROOT_IMAGE
].name
= optarg
;
106 md_root_symbols
[X_MD_ROOT_SIZE
].name
= optarg
;
133 if ((kfd
= open(kfile
, O_RDONLY
, 0)) == -1)
134 err(1, "open %s", kfile
);
136 if ((kfd
= open(kfile
, O_RDWR
, 0)) == -1)
137 err(1, "open %s", kfile
);
141 if ((abfd
= bfd_fdopenr(kfile
, bfdname
, kfd
)) == NULL
) {
145 if (!bfd_check_format(abfd
, bfd_object
)) {
146 bfd_perror("check format");
150 if (find_md_root(abfd
, md_root_symbols
) != 0)
151 errx(1, "could not find symbols in %s", kfile
);
153 fprintf(stderr
, "got symbols from %s\n", kfile
);
155 if (fstat(kfd
, &ksb
) == -1)
156 err(1, "fstat %s", kfile
);
157 if (ksb
.st_size
!= (size_t)ksb
.st_size
)
158 errx(1, "%s too big to map", kfile
);
160 if ((mappedkfile
= mmap(NULL
, ksb
.st_size
, PROT_READ
,
161 MAP_FILE
| MAP_PRIVATE
, kfd
, 0)) == (caddr_t
)-1)
162 err(1, "mmap %s", kfile
);
164 fprintf(stderr
, "mapped %s\n", kfile
);
166 md_root_offset
= md_root_symbols
[X_MD_ROOT_IMAGE
].offset
;
167 md_root_size_offset
= md_root_symbols
[X_MD_ROOT_SIZE
].offset
;
168 md_root_size
= bfd_get_32(abfd
, &mappedkfile
[md_root_size_offset
]);
170 munmap(mappedkfile
, ksb
.st_size
);
173 if ((fsfd
= open(fsfile
, O_WRONLY
|O_CREAT
, 0777)) == -1)
174 err(1, "open %s", fsfile
);
175 left_to_copy
= md_root_size
;
177 if ((fsfd
= open(fsfile
, O_RDONLY
, 0)) == -1)
178 err(1, "open %s", fsfile
);
179 if (fstat(fsfd
, &fssb
) == -1)
180 err(1, "fstat %s", fsfile
);
181 if (fssb
.st_size
!= (size_t)fssb
.st_size
)
182 errx(1, "fs image is too big");
183 if (fssb
.st_size
> md_root_size
)
184 errx(1, "fs image (%lld bytes) too big for buffer (%lu bytes)",
185 (long long)fssb
.st_size
, (unsigned long)md_root_size
);
186 left_to_copy
= fssb
.st_size
;
190 fprintf(stderr
, "copying image %s %s %s\n", fsfile
,
191 (extract
? "from" : "into"), kfile
);
193 if (lseek(kfd
, md_root_offset
, SEEK_SET
) != md_root_offset
)
194 err(1, "seek %s", kfile
);
195 while (left_to_copy
> 0) {
214 todo
= (left_to_copy
> CHUNKSIZE
) ? CHUNKSIZE
: left_to_copy
;
215 if ((rv
= read(rfd
, buf
, todo
)) != todo
) {
217 err(1, "read %s", rfile
);
219 errx(1, "unexpected EOF reading %s", rfile
);
221 if ((rv
= write(wfd
, buf
, todo
)) != todo
) {
223 err(1, "write %s", wfile
);
225 errx(1, "short write writing %s", wfile
);
227 left_to_copy
-= todo
;
230 fprintf(stderr
, "done copying image\n");
231 if (setsize
&& !extract
) {
232 char buf
[sizeof(uint32_t)];
235 fprintf(stderr
, "setting md_root_size to %llu\n",
236 (unsigned long long) fssb
.st_size
);
237 if (lseek(kfd
, md_root_size_offset
, SEEK_SET
) !=
239 err(1, "seek %s", kfile
);
240 bfd_put_32(abfd
, fssb
.st_size
, buf
);
241 if (write(kfd
, buf
, sizeof(buf
)) != sizeof(buf
))
242 err(1, "write %s", kfile
);
249 fprintf(stderr
, "exiting\n");
251 bfd_close_all_done(abfd
);
261 "usage: %s [-svx] [-b bfdname] kernel image\n",
263 fprintf(stderr
, "supported targets:");
264 for (list
= bfd_target_list(); *list
!= NULL
; list
++)
265 fprintf(stderr
, " %s", *list
);
266 fprintf(stderr
, "\n");
271 find_md_root(bfd
*abfd
, struct symbols symbols
[])
275 long number_of_symbols
;
276 asymbol
**symbol_table
= NULL
;
279 storage_needed
= bfd_get_symtab_upper_bound(abfd
);
280 if (storage_needed
<= 0)
283 symbol_table
= (asymbol
**)malloc(storage_needed
);
284 if (symbol_table
== NULL
)
287 number_of_symbols
= bfd_canonicalize_symtab(abfd
, symbol_table
);
288 if (number_of_symbols
<= 0) {
293 for (i
= 0; i
< number_of_symbols
; i
++) {
294 for (s
= symbols
; s
->name
!= NULL
; s
++) {
295 const char *sym
= symbol_table
[i
]->name
;
298 * match symbol prefix '_' or ''.
300 if (!strcmp(s
->name
, sym
) ||
301 !strcmp(s
->name
+ 1, sym
)) {
303 (size_t)(symbol_table
[i
]->section
->filepos
304 + symbol_table
[i
]->value
);
311 for (s
= symbols
; s
->name
!= NULL
; s
++) {