2011-02-21 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / ax-general.c
1 /* Functions for manipulating expressions designed to be executed on the agent
2 Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* Despite what the above comment says about this file being part of
21 GDB, we would like to keep these functions free of GDB
22 dependencies, since we want to be able to use them in contexts
23 outside of GDB (test suites, the stub, etc.) */
24
25 #include "defs.h"
26 #include "ax.h"
27
28 #include "value.h"
29 #include "gdb_string.h"
30
31 #include "user-regs.h"
32
33 static void grow_expr (struct agent_expr *x, int n);
34
35 static void append_const (struct agent_expr *x, LONGEST val, int n);
36
37 static LONGEST read_const (struct agent_expr *x, int o, int n);
38
39 static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
40 \f
41 /* Functions for building expressions. */
42
43 /* Allocate a new, empty agent expression. */
44 struct agent_expr *
45 new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
46 {
47 struct agent_expr *x = xmalloc (sizeof (*x));
48
49 x->len = 0;
50 x->size = 1; /* Change this to a larger value once
51 reallocation code is tested. */
52 x->buf = xmalloc (x->size);
53
54 x->gdbarch = gdbarch;
55 x->scope = scope;
56
57 /* Bit vector for registers used. */
58 x->reg_mask_len = 1;
59 x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
60 memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
61
62 return x;
63 }
64
65 /* Free a agent expression. */
66 void
67 free_agent_expr (struct agent_expr *x)
68 {
69 xfree (x->buf);
70 xfree (x->reg_mask);
71 xfree (x);
72 }
73
74 static void
75 do_free_agent_expr_cleanup (void *x)
76 {
77 free_agent_expr (x);
78 }
79
80 struct cleanup *
81 make_cleanup_free_agent_expr (struct agent_expr *x)
82 {
83 return make_cleanup (do_free_agent_expr_cleanup, x);
84 }
85
86
87 /* Make sure that X has room for at least N more bytes. This doesn't
88 affect the length, just the allocated size. */
89 static void
90 grow_expr (struct agent_expr *x, int n)
91 {
92 if (x->len + n > x->size)
93 {
94 x->size *= 2;
95 if (x->size < x->len + n)
96 x->size = x->len + n + 10;
97 x->buf = xrealloc (x->buf, x->size);
98 }
99 }
100
101
102 /* Append the low N bytes of VAL as an N-byte integer to the
103 expression X, in big-endian order. */
104 static void
105 append_const (struct agent_expr *x, LONGEST val, int n)
106 {
107 int i;
108
109 grow_expr (x, n);
110 for (i = n - 1; i >= 0; i--)
111 {
112 x->buf[x->len + i] = val & 0xff;
113 val >>= 8;
114 }
115 x->len += n;
116 }
117
118
119 /* Extract an N-byte big-endian unsigned integer from expression X at
120 offset O. */
121 static LONGEST
122 read_const (struct agent_expr *x, int o, int n)
123 {
124 int i;
125 LONGEST accum = 0;
126
127 /* Make sure we're not reading off the end of the expression. */
128 if (o + n > x->len)
129 error (_("GDB bug: ax-general.c (read_const): incomplete constant"));
130
131 for (i = 0; i < n; i++)
132 accum = (accum << 8) | x->buf[o + i];
133
134 return accum;
135 }
136
137
138 /* Append a simple operator OP to EXPR. */
139 void
140 ax_simple (struct agent_expr *x, enum agent_op op)
141 {
142 grow_expr (x, 1);
143 x->buf[x->len++] = op;
144 }
145
146 /* Append a pick operator to EXPR. DEPTH is the stack item to pick,
147 with 0 being top of stack. */
148 void
149 ax_pick (struct agent_expr *x, int depth)
150 {
151 if (depth < 0 || depth > 255)
152 error (_("GDB bug: ax-general.c (ax_pick): stack depth out of range"));
153 ax_simple (x, aop_pick);
154 append_const (x, 1, depth);
155 }
156
157
158 /* Append a sign-extension or zero-extension instruction to EXPR, to
159 extend an N-bit value. */
160 static void
161 generic_ext (struct agent_expr *x, enum agent_op op, int n)
162 {
163 /* N must fit in a byte. */
164 if (n < 0 || n > 255)
165 error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
166 /* That had better be enough range. */
167 if (sizeof (LONGEST) * 8 > 255)
168 error (_("GDB bug: ax-general.c (generic_ext): "
169 "opcode has inadequate range"));
170
171 grow_expr (x, 2);
172 x->buf[x->len++] = op;
173 x->buf[x->len++] = n;
174 }
175
176
177 /* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
178 void
179 ax_ext (struct agent_expr *x, int n)
180 {
181 generic_ext (x, aop_ext, n);
182 }
183
184
185 /* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
186 void
187 ax_zero_ext (struct agent_expr *x, int n)
188 {
189 generic_ext (x, aop_zero_ext, n);
190 }
191
192
193 /* Append a trace_quick instruction to EXPR, to record N bytes. */
194 void
195 ax_trace_quick (struct agent_expr *x, int n)
196 {
197 /* N must fit in a byte. */
198 if (n < 0 || n > 255)
199 error (_("GDB bug: ax-general.c (ax_trace_quick): "
200 "size out of range for trace_quick"));
201
202 grow_expr (x, 2);
203 x->buf[x->len++] = aop_trace_quick;
204 x->buf[x->len++] = n;
205 }
206
207
208 /* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
209 aop_if_goto). We assume we don't know the target offset yet,
210 because it's probably a forward branch, so we leave space in EXPR
211 for the target, and return the offset in EXPR of that space, so we
212 can backpatch it once we do know the target offset. Use ax_label
213 to do the backpatching. */
214 int
215 ax_goto (struct agent_expr *x, enum agent_op op)
216 {
217 grow_expr (x, 3);
218 x->buf[x->len + 0] = op;
219 x->buf[x->len + 1] = 0xff;
220 x->buf[x->len + 2] = 0xff;
221 x->len += 3;
222 return x->len - 2;
223 }
224
225 /* Suppose a given call to ax_goto returns some value PATCH. When you
226 know the offset TARGET that goto should jump to, call
227 ax_label (EXPR, PATCH, TARGET)
228 to patch TARGET into the ax_goto instruction. */
229 void
230 ax_label (struct agent_expr *x, int patch, int target)
231 {
232 /* Make sure the value is in range. Don't accept 0xffff as an
233 offset; that's our magic sentinel value for unpatched branches. */
234 if (target < 0 || target >= 0xffff)
235 error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
236
237 x->buf[patch] = (target >> 8) & 0xff;
238 x->buf[patch + 1] = target & 0xff;
239 }
240
241
242 /* Assemble code to push a constant on the stack. */
243 void
244 ax_const_l (struct agent_expr *x, LONGEST l)
245 {
246 static enum agent_op ops[]
247 =
248 {aop_const8, aop_const16, aop_const32, aop_const64};
249 int size;
250 int op;
251
252 /* How big is the number? 'op' keeps track of which opcode to use.
253 Notice that we don't really care whether the original number was
254 signed or unsigned; we always reproduce the value exactly, and
255 use the shortest representation. */
256 for (op = 0, size = 8; size < 64; size *= 2, op++)
257 {
258 LONGEST lim = ((LONGEST) 1) << (size - 1);
259
260 if (-lim <= l && l <= lim - 1)
261 break;
262 }
263
264 /* Emit the right opcode... */
265 ax_simple (x, ops[op]);
266
267 /* Emit the low SIZE bytes as an unsigned number. We know that
268 sign-extending this will yield l. */
269 append_const (x, l, size / 8);
270
271 /* Now, if it was negative, and not full-sized, sign-extend it. */
272 if (l < 0 && size < 64)
273 ax_ext (x, size);
274 }
275
276
277 void
278 ax_const_d (struct agent_expr *x, LONGEST d)
279 {
280 /* FIXME: floating-point support not present yet. */
281 error (_("GDB bug: ax-general.c (ax_const_d): "
282 "floating point not supported yet"));
283 }
284
285
286 /* Assemble code to push the value of register number REG on the
287 stack. */
288 void
289 ax_reg (struct agent_expr *x, int reg)
290 {
291 if (reg >= gdbarch_num_regs (x->gdbarch))
292 {
293 /* This is a pseudo-register. */
294 if (!gdbarch_ax_pseudo_register_push_stack_p (x->gdbarch))
295 error (_("'%s' is a pseudo-register; "
296 "GDB cannot yet trace its contents."),
297 user_reg_map_regnum_to_name (x->gdbarch, reg));
298 if (gdbarch_ax_pseudo_register_push_stack (x->gdbarch, x, reg))
299 error (_("Trace '%s' failed."),
300 user_reg_map_regnum_to_name (x->gdbarch, reg));
301 }
302 else
303 {
304 /* Make sure the register number is in range. */
305 if (reg < 0 || reg > 0xffff)
306 error (_("GDB bug: ax-general.c (ax_reg): "
307 "register number out of range"));
308 grow_expr (x, 3);
309 x->buf[x->len] = aop_reg;
310 x->buf[x->len + 1] = (reg >> 8) & 0xff;
311 x->buf[x->len + 2] = (reg) & 0xff;
312 x->len += 3;
313 }
314 }
315
316 /* Assemble code to operate on a trace state variable. */
317
318 void
319 ax_tsv (struct agent_expr *x, enum agent_op op, int num)
320 {
321 /* Make sure the tsv number is in range. */
322 if (num < 0 || num > 0xffff)
323 internal_error (__FILE__, __LINE__,
324 _("ax-general.c (ax_tsv): variable "
325 "number is %d, out of range"), num);
326
327 grow_expr (x, 3);
328 x->buf[x->len] = op;
329 x->buf[x->len + 1] = (num >> 8) & 0xff;
330 x->buf[x->len + 2] = (num) & 0xff;
331 x->len += 3;
332 }
333
334 void
335 ax_memcpy (struct agent_expr *x, const void *src, size_t n)
336 {
337 grow_expr (x, n);
338 memcpy (x->buf + x->len, src, n);
339 x->len += n;
340 }
341 \f
342
343
344 /* Functions for disassembling agent expressions, and otherwise
345 debugging the expression compiler. */
346
347 struct aop_map aop_map[] =
348 {
349 {0, 0, 0, 0, 0}
350 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
351 , { # NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED }
352 #include "ax.def"
353 #undef DEFOP
354 };
355
356
357 /* Disassemble the expression EXPR, writing to F. */
358 void
359 ax_print (struct ui_file *f, struct agent_expr *x)
360 {
361 int i;
362 int is_float = 0;
363
364 fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
365 fprintf_filtered (f, _("Reg mask:"));
366 for (i = 0; i < x->reg_mask_len; ++i)
367 fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
368 fprintf_filtered (f, _("\n"));
369
370 /* Check the size of the name array against the number of entries in
371 the enum, to catch additions that people didn't sync. */
372 if ((sizeof (aop_map) / sizeof (aop_map[0]))
373 != aop_last)
374 error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
375
376 for (i = 0; i < x->len;)
377 {
378 enum agent_op op = x->buf[i];
379 int op_size;
380
381 if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
382 || !aop_map[op].name)
383 {
384 fprintf_filtered (f, _("%3d <bad opcode %02x>\n"), i, op);
385 i++;
386 continue;
387 }
388 if (op == aop_printf)
389 {
390 if (i + 2 >= x->len)
391 {
392 fprintf_filtered (f, _("%3d <bad opcode %02x>\n"), i, op);
393 i++;
394 continue;
395 }
396 op_size = 1 + strlen (x->buf + i + 2) + 1;
397 }
398 else
399 op_size = aop_map[op].op_size;
400 if (i + 1 + op_size > x->len)
401 {
402 fprintf_filtered (f, _("%3d <incomplete opcode %s>\n"),
403 i, aop_map[op].name);
404 break;
405 }
406
407 fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
408 if (op_size > 0)
409 {
410 fputs_filtered (" ", f);
411
412 print_longest (f, 'd', 0,
413 read_const (x, i + 1, op_size));
414 }
415 fprintf_filtered (f, "\n");
416 i += 1 + op_size;
417
418 is_float = (op == aop_float);
419 }
420 }
421
422 /* Add register REG to the register mask for expression AX. */
423 void
424 ax_reg_mask (struct agent_expr *ax, int reg)
425 {
426 if (reg >= gdbarch_num_regs (ax->gdbarch))
427 {
428 /* This is a pseudo-register. */
429 if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
430 error (_("'%s' is a pseudo-register; "
431 "GDB cannot yet trace its contents."),
432 user_reg_map_regnum_to_name (ax->gdbarch, reg));
433 if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
434 error (_("Trace '%s' failed."),
435 user_reg_map_regnum_to_name (ax->gdbarch, reg));
436 }
437 else
438 {
439 int byte = reg / 8;
440
441 /* Grow the bit mask if necessary. */
442 if (byte >= ax->reg_mask_len)
443 {
444 /* It's not appropriate to double here. This isn't a
445 string buffer. */
446 int new_len = byte + 1;
447 unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
448 new_len
449 * sizeof (ax->reg_mask[0]));
450 memset (new_reg_mask + ax->reg_mask_len, 0,
451 (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
452 ax->reg_mask_len = new_len;
453 ax->reg_mask = new_reg_mask;
454 }
455
456 ax->reg_mask[byte] |= 1 << (reg % 8);
457 }
458 }
459
460 /* Given an agent expression AX, fill in requirements and other descriptive
461 bits. */
462 void
463 ax_reqs (struct agent_expr *ax)
464 {
465 int i;
466 int height;
467
468 /* Jump target table. targets[i] is non-zero iff we have found a
469 jump to offset i. */
470 char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
471
472 /* Instruction boundary table. boundary[i] is non-zero iff our scan
473 has reached an instruction starting at offset i. */
474 char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
475
476 /* Stack height record. If either targets[i] or boundary[i] is
477 non-zero, heights[i] is the height the stack should have before
478 executing the bytecode at that point. */
479 int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
480
481 /* Pointer to a description of the present op. */
482 struct aop_map *op;
483
484 int op_size = 0, consumed = 0;
485
486 memset (targets, 0, ax->len * sizeof (targets[0]));
487 memset (boundary, 0, ax->len * sizeof (boundary[0]));
488
489 ax->max_height = ax->min_height = height = 0;
490 ax->flaw = agent_flaw_none;
491 ax->max_data_size = 0;
492
493 for (i = 0; i < ax->len; i += 1 + op_size)
494 {
495 if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
496 {
497 ax->flaw = agent_flaw_bad_instruction;
498 return;
499 }
500
501 op = &aop_map[ax->buf[i]];
502
503 if (!op->name)
504 {
505 ax->flaw = agent_flaw_bad_instruction;
506 return;
507 }
508
509 if (ax->buf[i] == aop_printf)
510 {
511 if (i + 2 >= ax->len)
512 {
513 ax->flaw = agent_flaw_incomplete_instruction;
514 return;
515 }
516 consumed = ax->buf[i + 1];
517 op_size = 1 + strlen (ax->buf + i + 2) + 1;
518 }
519 else
520 {
521 op_size = op->op_size;
522 consumed = op->consumed;
523 }
524
525 if (i + 1 + op_size > ax->len)
526 {
527 ax->flaw = agent_flaw_incomplete_instruction;
528 return;
529 }
530
531 /* If this instruction is a forward jump target, does the
532 current stack height match the stack height at the jump
533 source? */
534 if (targets[i] && (heights[i] != height))
535 {
536 ax->flaw = agent_flaw_height_mismatch;
537 return;
538 }
539
540 boundary[i] = 1;
541 heights[i] = height;
542
543 height -= consumed;
544 if (height < ax->min_height)
545 ax->min_height = height;
546 height += op->produced;
547 if (height > ax->max_height)
548 ax->max_height = height;
549
550 if (op->data_size > ax->max_data_size)
551 ax->max_data_size = op->data_size;
552
553 /* For jump instructions, check that the target is a valid
554 offset. If it is, record the fact that that location is a
555 jump target, and record the height we expect there. */
556 if (aop_goto == op - aop_map
557 || aop_if_goto == op - aop_map)
558 {
559 int target = read_const (ax, i + 1, 2);
560 if (target < 0 || target >= ax->len)
561 {
562 ax->flaw = agent_flaw_bad_jump;
563 return;
564 }
565
566 /* Do we have any information about what the stack height
567 should be at the target? */
568 if (targets[target] || boundary[target])
569 {
570 if (heights[target] != height)
571 {
572 ax->flaw = agent_flaw_height_mismatch;
573 return;
574 }
575 }
576
577 /* Record the target, along with the stack height we expect. */
578 targets[target] = 1;
579 heights[target] = height;
580 }
581
582 /* For unconditional jumps with a successor, check that the
583 successor is a target, and pick up its stack height. */
584 if (aop_goto == op - aop_map
585 && i + 3 < ax->len)
586 {
587 if (!targets[i + 3])
588 {
589 ax->flaw = agent_flaw_hole;
590 return;
591 }
592
593 height = heights[i + 3];
594 }
595
596 /* For reg instructions, record the register in the bit mask. */
597 if (aop_reg == op - aop_map)
598 {
599 int reg = read_const (ax, i + 1, 2);
600
601 ax_reg_mask (ax, reg);
602 }
603 }
604
605 /* Check that all the targets are on boundaries. */
606 for (i = 0; i < ax->len; i++)
607 if (targets[i] && !boundary[i])
608 {
609 ax->flaw = agent_flaw_bad_jump;
610 return;
611 }
612
613 ax->final_height = height;
614 }
This page took 0.051867 seconds and 5 git commands to generate.