4 * Copyright (c) 2009 Izumi Tsutsui. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Copyright (c) 1996 Christopher G. Demetriou
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. The name of the author may not be used to endorse or promote products
40 * derived from this software without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
56 #include <sys/cdefs.h>
58 __COPYRIGHT("@(#) Copyright (c) 1996\
59 Christopher G. Demetriou. All rights reserved.");
66 #include <sys/types.h>
69 #include <sys/inttypes.h>
82 int main(int, char *[]);
83 static void usage(void) __dead
;
85 bool replace
, verbose
;
93 * Since we can't get the text address from an a.out executable, we
94 * need to be able to specify it. Note: there's no way to test to
95 * see if the user entered a valid address!
97 int T_flag_specified
; /* the -T flag was specified */
98 u_long text_start
; /* Start of kernel text */
99 #endif /* NLIST_AOUT */
101 static const struct {
103 int (*check
)(const char *, size_t);
104 int (*findoff
)(const char *, size_t, u_long
, size_t *);
107 { "a.out", check_aout
, findoff_aout
, },
110 { "ECOFF", check_ecoff
, findoff_ecoff
, },
113 { "ELF32", check_elf32
, findoff_elf32
, },
116 { "ELF64", check_elf64
, findoff_elf64
, },
119 { "COFF", check_coff
, findoff_coff
, },
125 main(int argc
, char *argv
[])
141 int ch
, fd
, rv
, i
, n
;
143 setprogname(argv
[0]);
145 while ((ch
= getopt(argc
, argv
, "bwldT:a:s:o:r:v")) != -1)
148 size
= sizeof(uint8_t);
151 size
= sizeof(uint16_t);
154 size
= sizeof(uint32_t);
157 size
= sizeof(uint64_t);
160 if (addr
!= 0 || symbol
!= NULL
)
162 "only one address/symbol allowed");
163 addr
= strtoul(optarg
, NULL
, 0);
166 if (addr
!= 0 || symbol
!= NULL
)
168 "only one address/symbol allowed");
174 "only one offset allowed");
175 offset
= strtoul(optarg
, NULL
, 0);
179 val
= strtoull(optarg
, NULL
, 0);
186 T_flag_specified
= 1;
187 text_start
= strtoul(optarg
, NULL
, 0);
190 fprintf(stderr
, "%s: unknown option -- %c\n",
191 getprogname(), (char)ch
);
193 #endif /* NLIST_AOUT */
204 if (addr
== 0 && symbol
== NULL
) {
205 warnx("no address or symbol specified");
210 size
= sizeof(uint32_t); /* default to int */
214 if ((fd
= open(fname
, replace
? O_RDWR
: O_RDONLY
, 0)) == -1)
215 err(EXIT_FAILURE
, "open %s", fname
);
217 if (symbol
!= NULL
) {
218 nl
[0].n_name
= symbol
;
220 if ((rv
= __fdnlist(fd
, nl
)) != 0)
221 errx(EXIT_FAILURE
, "could not find symbol %s in %s",
223 addr
= nl
[0].n_value
;
225 fprintf(stderr
, "got symbol address 0x%lx from %s\n",
229 addr
+= offset
* size
;
231 if (fstat(fd
, &sb
) == -1)
232 err(EXIT_FAILURE
, "fstat %s", fname
);
233 if (sb
.st_size
!= (ssize_t
)sb
.st_size
)
234 errx(EXIT_FAILURE
, "%s too big to map", fname
);
236 if ((mappedfile
= mmap(NULL
, sb
.st_size
,
237 replace
? PROT_READ
| PROT_WRITE
: PROT_READ
,
238 MAP_FILE
| MAP_SHARED
, fd
, 0)) == (char *)-1)
239 err(EXIT_FAILURE
, "mmap %s", fname
);
241 fprintf(stderr
, "mapped %s\n", fname
);
243 n
= __arraycount(exec_formats
);
244 for (i
= 0; i
< n
; i
++) {
245 if ((*exec_formats
[i
].check
)(mappedfile
, sb
.st_size
) == 0)
249 errx(EXIT_FAILURE
, "%s: unknown executable format", fname
);
252 fprintf(stderr
, "%s is an %s binary\n", fname
,
253 exec_formats
[i
].name
);
255 if (T_flag_specified
)
256 fprintf(stderr
, "kernel text loads at 0x%lx\n",
261 if ((*exec_formats
[i
].findoff
)(mappedfile
, sb
.st_size
,
263 errx(EXIT_FAILURE
, "couldn't find file offset for %s in %s",
264 symbol
!= NULL
? nl
[0].n_name
: "address" , fname
);
266 valp
= mappedfile
+ valoff
;
269 printf("%s(0x%lx): ", symbol
, addr
);
271 printf("0x%lx: ", addr
);
274 case sizeof(uint8_t):
275 uval8
= *(uint8_t *)valp
;
276 sval8
= *(int8_t *)valp
;
277 printf("0x%02" PRIx8
" (%" PRIu8
, uval8
, uval8
);
279 printf("/%" PRId8
, sval8
);
282 case sizeof(uint16_t):
283 uval16
= *(uint16_t *)valp
;
284 sval16
= *(int16_t *)valp
;
285 printf("0x%04" PRIx16
" (%" PRIu16
, uval16
, uval16
);
287 printf("/%" PRId16
, sval16
);
290 case sizeof(uint32_t):
291 uval32
= *(uint32_t *)valp
;
292 sval32
= *(int32_t *)valp
;
293 printf("0x%08" PRIx32
" (%" PRIu32
, uval32
, uval32
);
295 printf("/%" PRId32
, sval32
);
298 case sizeof(uint64_t):
299 uval64
= *(uint64_t *)valp
;
300 sval64
= *(int64_t *)valp
;
301 printf("0x%016" PRIx64
" (%" PRIu64
, uval64
, uval64
);
303 printf("/%" PRId64
, sval64
);
307 printf(", at offset %#lx in %s\n", (unsigned long)valoff
, fname
);
312 printf("new value: ");
315 case sizeof(uint8_t):
316 uval8
= (uint8_t)val
;
318 printf("0x%02" PRIx8
" (%" PRIu8
, uval8
, uval8
);
320 printf("/%" PRId8
, sval8
);
322 *(uint8_t *)valp
= uval8
;
324 case sizeof(uint16_t):
325 uval16
= (uint16_t)val
;
326 sval16
= (int16_t)val
;
327 printf("0x%04" PRIx16
" (%" PRIu16
, uval16
, uval16
);
329 printf("/%" PRId16
, sval16
);
331 *(uint16_t *)valp
= uval16
;
333 case sizeof(uint32_t):
334 uval32
= (uint32_t)val
;
335 sval32
= (int32_t)val
;
336 printf("0x%08" PRIx32
" (%" PRIu32
, uval32
, uval32
);
338 printf("/%" PRId32
, sval32
);
340 *(uint32_t *)valp
= uval32
;
342 case sizeof(uint64_t):
343 uval64
= (uint64_t)val
;
344 sval64
= (int64_t)val
;
345 printf("0x%016" PRIx64
" (%" PRIu64
, uval64
, uval64
);
347 printf("/%" PRId64
, sval64
);
349 *(uint64_t *)valp
= uval64
;
355 munmap(mappedfile
, sb
.st_size
);
359 fprintf(stderr
, "exiting\n");
368 "usage: %s [-b|-w|-l|-d] [-a address | -s symbol] [-o offset]\n"
373 "[-v] binary\n", getprogname());