| @@ -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 | |
25 | static char synusage[] = | | 25 | static 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 | |
34 | static char desusage[] = | | 34 | static 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 | |
75 | extern char *optarg; | | 75 | extern char *optarg; |
76 | extern int optind; | | 76 | extern int optind; |
77 | | | 77 | |
78 | void error (char *) __attribute__((__noreturn__)); | | 78 | void error(char *) __attribute__((__noreturn__)); |
79 | static void Synopsis(char *program_name); | | 79 | static void Synopsis(char *program_name); |
80 | static void Usage(char *program_name); | | 80 | static void Usage(char *program_name); |
81 | static u_long FindAssign(char *symbol, u_long *rvalue); | | 81 | static u_long FindAssign(char *symbol, u_long *rvalue); |
82 | static void FindOffset(char *symbol, u_long *index); | | 82 | static 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 */ |
85 | int test = 1; | | 85 | int test = 1; |
86 | int testbss; | | 86 | int testbss; |
87 | char foo = 23; | | 87 | char foo = 23; |
88 | char viewb[10] = {0,0,1,0,1,1,0,1,1,1}; | | 88 | char viewb[10] = {0,0,1,0,1,1,0,1,1,1}; |
89 | short vieww[10] = {0,0,1,0,1,1,0,1,1,1}; | | 89 | short vieww[10] = {0,0,1,0,1,1,0,1,1,1}; |
90 | long viewl[10] = {0,0,1,0,1,1,0,1,1,1}; | | 90 | long 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 | |
358 | void | | 359 | void |
359 | error(char *str) | | 360 | error(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 */ |
366 | static void | | 367 | static void |
367 | Synopsis(char *pgname) | | 368 | Synopsis(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 | |
373 | static void | | 374 | static void |
374 | Usage(char *pgname) | | 375 | Usage(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 | */ |
398 | static void | | 399 | static void |
399 | FindOffset(char *symbol, u_long *index) | | 400 | FindOffset(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 | */ |
451 | static u_long | | 452 | static u_long |
452 | FindAssign(char *symbol, u_long *rvalue) | | 453 | FindAssign(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++) |