Mon May 30 03:02:59 2016 UTC ()
further whitespace


(dholland)
diff -r1.14 -r1.15 src/sys/arch/amiga/stand/binpatch/binpatch.c

cvs diff -r1.14 -r1.15 src/sys/arch/amiga/stand/binpatch/binpatch.c (expand / switch to unified diff)

--- src/sys/arch/amiga/stand/binpatch/binpatch.c 2016/05/30 02:57:32 1.14
+++ src/sys/arch/amiga/stand/binpatch/binpatch.c 2016/05/30 03:02:58 1.15
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: binpatch.c,v 1.14 2016/05/30 02:57:32 dholland Exp $ */ 1/* $NetBSD: binpatch.c,v 1.15 2016/05/30 03:02:58 dholland Exp $ */
2 2
3/* Author: Markus Wild mw@eunet.ch ??? */ 3/* Author: Markus Wild mw@eunet.ch ??? */
4/* Modified: Rob Leland leland@mitre.org */ 4/* Modified: Rob Leland leland@mitre.org */
5 5
6#include <sys/types.h> 6#include <sys/types.h>
7#include <a.out.h> 7#include <a.out.h>
8#include <fcntl.h> 8#include <fcntl.h>
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12#include <unistd.h> 12#include <unistd.h>
13 13
14#ifdef __NetBSD__ 14#ifdef __NetBSD__
@@ -23,27 +23,27 @@ @@ -23,27 +23,27 @@
23 23
24 24
25static char synusage[] = 25static char synusage[] =
26"NAME\n" 26"NAME\n"
27"\t%s - Allows the patching of BSD binaries\n" 27"\t%s - Allows the patching of BSD binaries\n"
28"SYNOPSIS\n" 28"SYNOPSIS\n"
29"\t%s [-HELP]\n" 29"\t%s [-HELP]\n"
30"\t%s [-b|-w|-l] -s symbol[[[index]][=value]] binary\n" 30"\t%s [-b|-w|-l] -s symbol[[[index]][=value]] binary\n"
31"\t%s [-b|-w|-l] [-o offset] -s symbol [-r value] binary\n" 31"\t%s [-b|-w|-l] [-o offset] -s symbol [-r value] binary\n"
32"\t%s [-b|-w|-l] [-o offset] -a address [-r value] binary\n"; 32"\t%s [-b|-w|-l] [-o offset] -a address [-r value] binary\n";
33 33
34static char desusage[] = 34static char desusage[] =
35"DESCRIPTION\n" 35"DESCRIPTION\n"
36"\tAllows the patching of BSD binaries, for example,a distributed\n" 36"\tAllows the patching of BSD binaries, for example, a distributed\n"
37"\tkernel. Recient additions allows the user to index into an array\n" 37"\tkernel. Recient additions allows the user to index into an array\n"
38"\tand assign a value. Binpatch has internal variables to allow\n" 38"\tand assign a value. Binpatch has internal variables to allow\n"
39"\tyou to test it on itself under NetBSD.\n" 39"\tyou to test it on itself under NetBSD.\n"
40"OPTIONS\n" 40"OPTIONS\n"
41"\t-a patch variable by specifying address in hex\n" 41"\t-a patch variable by specifying address in hex\n"
42"\t-b symbol or address to be patched is 1 byte\n" 42"\t-b symbol or address to be patched is 1 byte\n"
43"\t-l symbol or address to be patched is 4 bytes (default)\n" 43"\t-l symbol or address to be patched is 4 bytes (default)\n"
44"\t-o offset to begin patching value relative to symbol or address\n" 44"\t-o offset to begin patching value relative to symbol or address\n"
45"\t-r replace value, and print out previous value to stdout\n" 45"\t-r replace value, and print out previous value to stdout\n"
46"\t-s patch variable by specifying symbol name. Use '[]'\n" 46"\t-s patch variable by specifying symbol name. Use '[]'\n"
47"\t to specify the 'index'. If '-b, -w or -l' not specified\n" 47"\t to specify the 'index'. If '-b, -w or -l' not specified\n"
48"\t then index value is used like an offset. Also can use '='\n" 48"\t then index value is used like an offset. Also can use '='\n"
49"\t to assign value\n" 49"\t to assign value\n"
@@ -65,27 +65,27 @@ static char desusage[] = @@ -65,27 +65,27 @@ static char desusage[] =
65"\tOne last example using '=' and []\n" 65"\tOne last example using '=' and []\n"
66"\t\tbinpatch -w -s '_vieww[4]=2' a.out\n" 66"\t\tbinpatch -w -s '_vieww[4]=2' a.out\n"
67"\tSo if the kernel is not finding your drives, you could enable\n" 67"\tSo if the kernel is not finding your drives, you could enable\n"
68"\tall available debugging options, helping to shed light on that problem.\n" 68"\tall available debugging options, helping to shed light on that problem.\n"
69"\t\tbinpatch -l -s _sbic_debug -r 1 netbsd scsi-level\n" 69"\t\tbinpatch -l -s _sbic_debug -r 1 netbsd scsi-level\n"
70"\t\tbinpatch -l -s _sddebug -r 1 netbsd sd-level (disk-driver)\n" 70"\t\tbinpatch -l -s _sddebug -r 1 netbsd sd-level (disk-driver)\n"
71"\t\tbinpatch -l -s _acdebug -r 1 netbsd autoconfig-level\n" 71"\t\tbinpatch -l -s _acdebug -r 1 netbsd autoconfig-level\n"
72"SEE ALSO\n" 72"SEE ALSO\n"
73"\tbinpatch.c binpatch(1)\n"; 73"\tbinpatch.c binpatch(1)\n";
74 74
75extern char *optarg; 75extern char *optarg;
76extern int optind; 76extern int optind;
77 77
78void error (char *) __attribute__((__noreturn__)); 78void error(char *) __attribute__((__noreturn__));
79static void Synopsis(char *program_name); 79static void Synopsis(char *program_name);
80static void Usage(char *program_name); 80static void Usage(char *program_name);
81static u_long FindAssign(char *symbol, u_long *rvalue); 81static u_long FindAssign(char *symbol, u_long *rvalue);
82static void FindOffset(char *symbol, u_long *index); 82static void FindOffset(char *symbol, u_long *index);
83 83
84/* The following variables are so binpatch can be tested on itself */ 84/* The following variables are so binpatch can be tested on itself */
85int test = 1; 85int test = 1;
86int testbss; 86int testbss;
87char foo = 23; 87char foo = 23;
88char viewb[10] = {0,0,1,0,1,1,0,1,1,1}; 88char viewb[10] = {0,0,1,0,1,1,0,1,1,1};
89short vieww[10] = {0,0,1,0,1,1,0,1,1,1}; 89short vieww[10] = {0,0,1,0,1,1,0,1,1,1};
90long viewl[10] = {0,0,1,0,1,1,0,1,1,1}; 90long viewl[10] = {0,0,1,0,1,1,0,1,1,1};
91/* End of test binpatch variables */ 91/* End of test binpatch variables */
@@ -104,272 +104,273 @@ main(int argc, char *argv[]) @@ -104,272 +104,273 @@ main(int argc, char *argv[])
104 char size = 4; 104 char size = 4;
105 /* Flag to say size option was set, used with index */ 105 /* Flag to say size option was set, used with index */
106 char size_opt = 0; 106 char size_opt = 0;
107 char *fname; 107 char *fname;
108 /* Program name */ 108 /* Program name */
109 char *pgname = argv[0]; 109 char *pgname = argv[0];
110 int fd; 110 int fd;
111 int type, off; 111 int type, off;
112 u_long lval; 112 u_long lval;
113 u_short sval; 113 u_short sval;
114 u_char cval; 114 u_char cval;
115 115
116 116
117 while ((c = getopt (argc, argv, "H:a:bwlr:s:o:")) != -1) { 117 while ((c = getopt(argc, argv, "H:a:bwlr:s:o:")) != -1) {
118 switch (c) { 118 switch (c) {
119 case 'H': 119 case 'H':
120 Usage(argv[0]); 120 Usage(argv[0]);
121 break; 121 break;
122 case 'a': 122 case 'a':
123 if (addr || symbol) { 123 if (addr || symbol) {
124 error ("only one address/symbol allowed"); 124 error("only one address/symbol allowed");
125 } 125 }
126 if (!strncmp(optarg, "0x", 2)) { 126 if (!strncmp(optarg, "0x", 2)) {
127 sscanf (optarg, "%x", &addr); 127 sscanf(optarg, "%x", &addr);
128 } else { 128 } else {
129 addr = atoi (optarg); 129 addr = atoi(optarg);
130 } 130 }
131 if (!addr) { 131 if (!addr) {
132 error ("invalid address"); 132 error("invalid address");
133 } 133 }
134 break; 134 break;
135 135
136 case 'b': 136 case 'b':
137 size = 1; 137 size = 1;
138 size_opt = 1; 138 size_opt = 1;
139 break; 139 break;
140 140
141 case 'w': 141 case 'w':
142 size = 2; 142 size = 2;
143 size_opt = 1; 143 size_opt = 1;
144 break; 144 break;
145 145
146 case 'l': 146 case 'l':
147 size = 4; 147 size = 4;
148 size_opt = 1; 148 size_opt = 1;
149 break; 149 break;
150 150
151 case 'r': 151 case 'r':
152 do_replace = 1; 152 do_replace = 1;
153 if (!strncmp(optarg, "0x", 2)) { 153 if (!strncmp(optarg, "0x", 2)) {
154 sscanf (optarg, "%x", &replace); 154 sscanf(optarg, "%x", &replace);
155 } else { 155 } else {
156 replace = atoi (optarg); 156 replace = atoi(optarg);
157 } 157 }
158 break; 158 break;
159 159
160 case 's': 160 case 's':
161 if (addr || symbol) { 161 if (addr || symbol) {
162 error ("only one address/symbol allowed"); 162 error("only one address/symbol allowed");
163 } 163 }
164 symbol = optarg; 164 symbol = optarg;
165 break; 165 break;
166 166
167 case 'o': 167 case 'o':
168 if (offset) { 168 if (offset) {
169 error ("only one offset allowed"); 169 error("only one offset allowed");
170 } 170 }
171 if (! strncmp (optarg, "0x", 2)) { 171 if (!strncmp(optarg, "0x", 2)) {
172 sscanf (optarg, "%x", &offset); 172 sscanf(optarg, "%x", &offset);
173 } else { 173 } else {
174 offset = atoi (optarg); 174 offset = atoi(optarg);
175 } 175 }
176 break; 176 break;
177 } 177 }
178 /* end while switch() */ 178 /* end while switch() */
179 } 179 }
180 180
181 if (argc > 1) { 181 if (argc > 1) {
182 if (addr || symbol) { 182 if (addr || symbol) {
183 argv += optind; 183 argv += optind;
184 argc -= optind; 184 argc -= optind;
185 185
186 if (argc < 1) { 186 if (argc < 1) {
187 error ("No file to patch."); 187 error("No file to patch.");
188 } 188 }
189 189
190 fname = argv[0]; 190 fname = argv[0];
191 if ((fd = open (fname, 0)) < 0) { 191 if ((fd = open(fname, 0)) < 0) {
192 error ("Can't open file"); 192 error("Can't open file");
193 } 193 }
194 194
195 if (read (fd, &e, sizeof (e)) != sizeof (e) 195 if (read(fd, &e, sizeof(e)) != sizeof(e)
196 || N_BADMAG (e)) { 196 || N_BADMAG(e)) {
197 error ("Not a valid executable."); 197 error("Not a valid executable.");
198 } 198 }
199 199
200 /* fake mid, so the N_ macros work on the amiga.. */ 200 /* fake mid, so the N_ macros work on the amiga.. */
201 e.a_midmag |= 127 << 16; 201 e.a_midmag |= 127 << 16;
202 202
203 if (symbol) { 203 if (symbol) {
204 struct nlist nl[2]; 204 struct nlist nl[2];
205 205
206 if (offset == 0) { 206 if (offset == 0) {
207 u_long new_do_replace = 0; 207 u_long new_do_replace = 0;
208 208
209 new_do_replace = FindAssign(symbol, 209 new_do_replace = FindAssign(symbol,
210 &replace); 210 &replace);
211 if (new_do_replace && do_replace) 211 if (new_do_replace && do_replace)
212 error("Cannot use both '=' " 212 error("Cannot use both '=' "
213 "and '-r' option!"); 213 "and '-r' option!");
214 FindOffset(symbol,&index); 214 FindOffset(symbol, &index);
215 if (size_opt) { 215 if (size_opt) {
216 /* Treat like an index */ 216 /* Treat like an index */
217 offset = index*size; 217 offset = index*size;
218 } else { 218 } else {
219 /* Treat like an offset */ 219 /* Treat like an offset */
220 offset = index; 220 offset = index;
221 } 221 }
222 if (new_do_replace) 222 if (new_do_replace)
223 do_replace = new_do_replace; 223 do_replace = new_do_replace;
224 } 224 }
225 nl[0].n_un.n_name = symbol; 225 nl[0].n_un.n_name = symbol;
226 nl[1].n_un.n_name = 0; 226 nl[1].n_un.n_name = 0;
227 if (nlist (fname, nl) != 0) { 227 if (nlist(fname, nl) != 0) {
228 fprintf(stderr,"Symbol is %s ",symbol); 228 fprintf(stderr, "Symbol is %s ",
229 error ("Symbol not found."); 229 symbol);
 230 error("Symbol not found.");
230 } 231 }
231 addr = nl[0].n_value; 232 addr = nl[0].n_value;
232 type = nl[0].n_type & N_TYPE; 233 type = nl[0].n_type & N_TYPE;
233 } else { 234 } else {
234 type = N_UNDF; 235 type = N_UNDF;
235 if (addr >= N_TXTADDR(e) && 236 if (addr >= N_TXTADDR(e) &&
236 addr < N_DATADDR(e)) { 237 addr < N_DATADDR(e)) {
237 type = N_TEXT; 238 type = N_TEXT;
238 } else if (addr >= N_DATADDR(e) && 239 } else if (addr >= N_DATADDR(e) &&
239 addr < N_DATADDR(e) + e.a_data) { 240 addr < N_DATADDR(e) + e.a_data) {
240 type = N_DATA; 241 type = N_DATA;
241 } 242 }
242 } 243 }
243 addr += offset; 244 addr += offset;
244 245
245 /* 246 /*
246 * if replace-mode, have to reopen the file 247 * if replace-mode, have to reopen the file
247 * for writing. Can't do that from the 248 * for writing. Can't do that from the
248 * beginning, or nlist() will not work (at 249 * beginning, or nlist() will not work (at
249 * least not under AmigaDOS) 250 * least not under AmigaDOS)
250 */ 251 */
251 if (do_replace) { 252 if (do_replace) {
252 close (fd); 253 close(fd);
253 if ((fd = open (fname, 2)) == -1) { 254 if ((fd = open(fname, 2)) == -1) {
254 error("Can't reopen file for writing."); 255 error("Can't reopen file for writing.");
255 } 256 }
256 } 257 }
257 258
258 if (type != N_TEXT && type != N_DATA) { 259 if (type != N_TEXT && type != N_DATA) {
259 error("address/symbol is not in text " 260 error("address/symbol is not in text "
260 "or data section."); 261 "or data section.");
261 } 262 }
262 263
263 if (type == N_TEXT) { 264 if (type == N_TEXT) {
264 off = addr - N_TXTADDR(e) + N_TXTOFF(e); 265 off = addr - N_TXTADDR(e) + N_TXTOFF(e);
265 } else { 266 } else {
266 off = addr - N_DATADDR(e) + N_DATOFF(e); 267 off = addr - N_DATADDR(e) + N_DATOFF(e);
267 } 268 }
268 269
269 if (lseek(fd, off, 0) == -1) { 270 if (lseek(fd, off, 0) == -1) {
270 error ("lseek"); 271 error("lseek");
271 } 272 }
272 273
273 /* 274 /*
274 * not beautiful, but works on big and little 275 * not beautiful, but works on big and little
275 * endian machines 276 * endian machines
276 */ 277 */
277 switch (size) { 278 switch (size) {
278 case 1: 279 case 1:
279 if (read(fd, &cval, 1) != 1) { 280 if (read(fd, &cval, 1) != 1) {
280 error ("cread"); 281 error("cread");
281 } 282 }
282 lval = cval; 283 lval = cval;
283 break; 284 break;
284 285
285 case 2: 286 case 2:
286 if (read(fd, &sval, 2) != 2) { 287 if (read(fd, &sval, 2) != 2) {
287 error ("sread"); 288 error("sread");
288 } 289 }
289 lval = sval; 290 lval = sval;
290 break; 291 break;
291 292
292 case 4: 293 case 4:
293 if (read(fd, &lval, 4) != 4) { 294 if (read(fd, &lval, 4) != 4) {
294 error ("lread"); 295 error("lread");
295 } 296 }
296 break; 297 break;
297 }/* switch size */ 298 }/* switch size */
298 299
299 300
300 if (symbol) { 301 if (symbol) {
301 printf("%s(0x%x): %d (0x%x)\n", symbol, addr, 302 printf("%s(0x%x): %d (0x%x)\n", symbol, addr,
302 lval, lval); 303 lval, lval);
303 } else { 304 } else {
304 printf("0x%x: %d (0x%x)\n", addr, lval, lval); 305 printf("0x%x: %d (0x%x)\n", addr, lval, lval);
305 } 306 }
306 307
307 if (do_replace) { 308 if (do_replace) {
308 if (lseek (fd, off, 0) == -1) { 309 if (lseek(fd, off, 0) == -1) {
309 error ("write-lseek"); 310 error("write-lseek");
310 } 311 }
311 switch (size) { 312 switch (size) {
312 case 1: 313 case 1:
313 cval = replace; 314 cval = replace;
314 if (cval != replace) { 315 if (cval != replace) {
315 error ("byte-value overflow."); 316 error("byte-value overflow.");
316 } 317 }
317 if (write(fd, &cval, 1) != 1) { 318 if (write(fd, &cval, 1) != 1) {
318 error ("cwrite"); 319 error("cwrite");
319 } 320 }
320 break; 321 break;
321 322
322 case 2: 323 case 2:
323 sval = replace; 324 sval = replace;
324 if (sval != replace) { 325 if (sval != replace) {
325 error ("word-value overflow."); 326 error("word-value overflow.");
326 } 327 }
327 if (write(fd, &sval, 2) != 2) { 328 if (write(fd, &sval, 2) != 2) {
328 error ("swrite"); 329 error("swrite");
329 } 330 }
330 break; 331 break;
331 332
332 case 4: 333 case 4:
333 if (write(fd, &replace, 4) != 4) { 334 if (write(fd, &replace, 4) != 4) {
334 error ("lwrite"); 335 error("lwrite");
335 } 336 }
336 break; 337 break;
337 } 338 }
338 /* end switch(size) */ 339 /* end switch(size) */
339 } 340 }
340 /* end if (do_replace) */ 341 /* end if (do_replace) */
341 342
342 close (fd); 343 close(fd);
343 } else {  344 } else {
344 /* not (addr || symbol) */ 345 /* not (addr || symbol) */
345 error("Must specify either address or symbol."); 346 error("Must specify either address or symbol.");
346 } 347 }
347 } else { 348 } else {
348 /* if argc <= 1 */ 349 /* if argc <= 1 */
349 Synopsis(pgname); 350 Synopsis(pgname);
350 } 351 }
351 352
352 return 0; 353 return 0;
353} 354}
354/* end main () */ 355/* end main () */
355 356
356 357
357 358
358void 359void
359error(char *str) 360error(char *str)
360{ 361{
361 fprintf (stderr, "%s\n", str); 362 fprintf(stderr, "%s\n", str);
362 exit (1); 363 exit(1);
363} 364}
364 365
365/* Give user very short help to avoid scrolling screen much */ 366/* Give user very short help to avoid scrolling screen much */
366static void 367static void
367Synopsis(char *pgname) 368Synopsis(char *pgname)
368{ 369{
369 fprintf(stdout, synusage, pgname, pgname, pgname, pgname, pgname); 370 fprintf(stdout, synusage, pgname, pgname, pgname, pgname, pgname);
370} 371}
371 372
372 373
373static void 374static void
374Usage(char *pgname) 375Usage(char *pgname)
375{ 376{
@@ -389,30 +390,30 @@ Usage(char *pgname) @@ -389,30 +390,30 @@ Usage(char *pgname)
389 * and we want to index the 3rd. element. 390 * and we want to index the 3rd. element.
390 * which is offset = (3 -1)*sizeof(short) =4. 391 * which is offset = (3 -1)*sizeof(short) =4.
391 * we would use view[4], which becomes view,4. 392 * we would use view[4], which becomes view,4.
392 * 393 *
393 * The way the code is implemented the [value] is 394 * The way the code is implemented the [value] is
394 * treated as a index if-and-only-if a '-b -w -l' option 395 * treated as a index if-and-only-if a '-b -w -l' option
395 * was given. Otherwise it is treated like an offset. 396 * was given. Otherwise it is treated like an offset.
396 * See above documentation in for of help! 397 * See above documentation in for of help!
397 */ 398 */
398static void 399static void
399FindOffset(char *symbol, u_long *index) 400FindOffset(char *symbol, u_long *index)
400{ 401{
401 /* Start of '[', now line must contain matching']' */ 402 /* Start of '[', now line must contain matching']' */
402 char *sb = strchr(symbol,'['); 403 char *sb = strchr(symbol, '[');
403 404
404 /* End of ']' */  405 /* End of ']' */
405 char *eb = strchr(symbol,']'); 406 char *eb = strchr(symbol, ']');
406 407
407 /* symbol size */ 408 /* symbol size */
408 short sz = strlen(symbol); 409 short sz = strlen(symbol);
409 410
410 if (sb) { 411 if (sb) {
411 if (eb && (eb > sb)) { 412 if (eb && (eb > sb)) {
412 if ((eb - symbol) == (sz - 1)) { 413 if ((eb - symbol) == (sz - 1)) {
413 /* Start of index */ 414 /* Start of index */
414 char *sindex; 415 char *sindex;
415 u_long newindex = 0; 416 u_long newindex = 0;
416 417
417 /* 418 /*
418 * In the future we could get fancy 419 * In the future we could get fancy
@@ -442,27 +443,27 @@ FindOffset(char *symbol, u_long *index) @@ -442,27 +443,27 @@ FindOffset(char *symbol, u_long *index)
442 } 443 }
443 /* end if sb != 0 */ 444 /* end if sb != 0 */
444} 445}
445/* end FindOffset */ 446/* end FindOffset */
446 447
447/* 448/*
448 * FindAssign : Scans symbol name for an '=number' strips it off of 449 * FindAssign : Scans symbol name for an '=number' strips it off of
449 * the symbol and proceeds. 450 * the symbol and proceeds.
450 */ 451 */
451static u_long 452static u_long
452FindAssign(char *symbol, u_long *rvalue) 453FindAssign(char *symbol, u_long *rvalue)
453{ 454{
454 /* Assign symbol some number */ 455 /* Assign symbol some number */
455 char *ce = rindex(symbol,'='); 456 char *ce = rindex(symbol, '=');
456 457
457 /* This should point at some number, no spaces allowed */ 458 /* This should point at some number, no spaces allowed */
458 char *cn = ce + 1; 459 char *cn = ce + 1;
459 460
460 /* flag for do_replace */ 461 /* flag for do_replace */
461 u_long dr = 0; 462 u_long dr = 0;
462 463
463 if (ce) { 464 if (ce) {
464 /* number of variaables scanned in */ 465 /* number of variaables scanned in */
465 int nscan; 466 int nscan;
466 467
467 /* get the number to assign to symbol and strip off = */ 468 /* get the number to assign to symbol and strip off = */
468 for (cn=ce + 1; *cn==' '; cn++) 469 for (cn=ce + 1; *cn==' '; cn++)