2011-01-05 Michael Snyder <msnyder@vmware.com>
[external/binutils.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
147 /* Append a sign-extension or zero-extension instruction to EXPR, to
148    extend an N-bit value.  */
149 static void
150 generic_ext (struct agent_expr *x, enum agent_op op, int n)
151 {
152   /* N must fit in a byte.  */
153   if (n < 0 || n > 255)
154     error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
155   /* That had better be enough range.  */
156   if (sizeof (LONGEST) * 8 > 255)
157     error (_("GDB bug: ax-general.c (generic_ext): "
158              "opcode has inadequate range"));
159
160   grow_expr (x, 2);
161   x->buf[x->len++] = op;
162   x->buf[x->len++] = n;
163 }
164
165
166 /* Append a sign-extension instruction to EXPR, to extend an N-bit value.  */
167 void
168 ax_ext (struct agent_expr *x, int n)
169 {
170   generic_ext (x, aop_ext, n);
171 }
172
173
174 /* Append a zero-extension instruction to EXPR, to extend an N-bit value.  */
175 void
176 ax_zero_ext (struct agent_expr *x, int n)
177 {
178   generic_ext (x, aop_zero_ext, n);
179 }
180
181
182 /* Append a trace_quick instruction to EXPR, to record N bytes.  */
183 void
184 ax_trace_quick (struct agent_expr *x, int n)
185 {
186   /* N must fit in a byte.  */
187   if (n < 0 || n > 255)
188     error (_("GDB bug: ax-general.c (ax_trace_quick): "
189              "size out of range for trace_quick"));
190
191   grow_expr (x, 2);
192   x->buf[x->len++] = aop_trace_quick;
193   x->buf[x->len++] = n;
194 }
195
196
197 /* Append a goto op to EXPR.  OP is the actual op (must be aop_goto or
198    aop_if_goto).  We assume we don't know the target offset yet,
199    because it's probably a forward branch, so we leave space in EXPR
200    for the target, and return the offset in EXPR of that space, so we
201    can backpatch it once we do know the target offset.  Use ax_label
202    to do the backpatching.  */
203 int
204 ax_goto (struct agent_expr *x, enum agent_op op)
205 {
206   grow_expr (x, 3);
207   x->buf[x->len + 0] = op;
208   x->buf[x->len + 1] = 0xff;
209   x->buf[x->len + 2] = 0xff;
210   x->len += 3;
211   return x->len - 2;
212 }
213
214 /* Suppose a given call to ax_goto returns some value PATCH.  When you
215    know the offset TARGET that goto should jump to, call
216    ax_label (EXPR, PATCH, TARGET)
217    to patch TARGET into the ax_goto instruction.  */
218 void
219 ax_label (struct agent_expr *x, int patch, int target)
220 {
221   /* Make sure the value is in range.  Don't accept 0xffff as an
222      offset; that's our magic sentinel value for unpatched branches.  */
223   if (target < 0 || target >= 0xffff)
224     error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
225
226   x->buf[patch] = (target >> 8) & 0xff;
227   x->buf[patch + 1] = target & 0xff;
228 }
229
230
231 /* Assemble code to push a constant on the stack.  */
232 void
233 ax_const_l (struct agent_expr *x, LONGEST l)
234 {
235   static enum agent_op ops[]
236   =
237   {aop_const8, aop_const16, aop_const32, aop_const64};
238   int size;
239   int op;
240
241   /* How big is the number?  'op' keeps track of which opcode to use.
242      Notice that we don't really care whether the original number was
243      signed or unsigned; we always reproduce the value exactly, and
244      use the shortest representation.  */
245   for (op = 0, size = 8; size < 64; size *= 2, op++)
246     {
247       LONGEST lim = ((LONGEST) 1) << (size - 1);
248
249       if (-lim <= l && l <= lim - 1)
250         break;
251     }
252
253   /* Emit the right opcode...  */
254   ax_simple (x, ops[op]);
255
256   /* Emit the low SIZE bytes as an unsigned number.  We know that
257      sign-extending this will yield l.  */
258   append_const (x, l, size / 8);
259
260   /* Now, if it was negative, and not full-sized, sign-extend it.  */
261   if (l < 0 && size < 64)
262     ax_ext (x, size);
263 }
264
265
266 void
267 ax_const_d (struct agent_expr *x, LONGEST d)
268 {
269   /* FIXME: floating-point support not present yet.  */
270   error (_("GDB bug: ax-general.c (ax_const_d): "
271            "floating point not supported yet"));
272 }
273
274
275 /* Assemble code to push the value of register number REG on the
276    stack.  */
277 void
278 ax_reg (struct agent_expr *x, int reg)
279 {
280   if (reg >= gdbarch_num_regs (x->gdbarch))
281     {
282       /* This is a pseudo-register.  */
283       if (!gdbarch_ax_pseudo_register_push_stack_p (x->gdbarch))
284         error (_("'%s' is a pseudo-register; "
285                  "GDB cannot yet trace its contents."),
286                user_reg_map_regnum_to_name (x->gdbarch, reg));
287       if (gdbarch_ax_pseudo_register_push_stack (x->gdbarch, x, reg))
288         error (_("Trace '%s' failed."),
289                user_reg_map_regnum_to_name (x->gdbarch, reg));
290     }
291   else
292     {
293       /* Make sure the register number is in range.  */
294       if (reg < 0 || reg > 0xffff)
295         error (_("GDB bug: ax-general.c (ax_reg): "
296                  "register number out of range"));
297       grow_expr (x, 3);
298       x->buf[x->len] = aop_reg;
299       x->buf[x->len + 1] = (reg >> 8) & 0xff;
300       x->buf[x->len + 2] = (reg) & 0xff;
301       x->len += 3;
302     }
303 }
304
305 /* Assemble code to operate on a trace state variable.  */
306
307 void
308 ax_tsv (struct agent_expr *x, enum agent_op op, int num)
309 {
310   /* Make sure the tsv number is in range.  */
311   if (num < 0 || num > 0xffff)
312     internal_error (__FILE__, __LINE__, 
313                     _("ax-general.c (ax_tsv): variable "
314                       "number is %d, out of range"), num);
315
316   grow_expr (x, 3);
317   x->buf[x->len] = op;
318   x->buf[x->len + 1] = (num >> 8) & 0xff;
319   x->buf[x->len + 2] = (num) & 0xff;
320   x->len += 3;
321 }
322 \f
323
324
325 /* Functions for disassembling agent expressions, and otherwise
326    debugging the expression compiler.  */
327
328 struct aop_map aop_map[] =
329 {
330   {0, 0, 0, 0, 0},
331   {"float", 0, 0, 0, 0},        /* 0x01 */
332   {"add", 0, 0, 2, 1},          /* 0x02 */
333   {"sub", 0, 0, 2, 1},          /* 0x03 */
334   {"mul", 0, 0, 2, 1},          /* 0x04 */
335   {"div_signed", 0, 0, 2, 1},   /* 0x05 */
336   {"div_unsigned", 0, 0, 2, 1}, /* 0x06 */
337   {"rem_signed", 0, 0, 2, 1},   /* 0x07 */
338   {"rem_unsigned", 0, 0, 2, 1}, /* 0x08 */
339   {"lsh", 0, 0, 2, 1},          /* 0x09 */
340   {"rsh_signed", 0, 0, 2, 1},   /* 0x0a */
341   {"rsh_unsigned", 0, 0, 2, 1}, /* 0x0b */
342   {"trace", 0, 0, 2, 0},        /* 0x0c */
343   {"trace_quick", 1, 0, 1, 1},  /* 0x0d */
344   {"log_not", 0, 0, 1, 1},      /* 0x0e */
345   {"bit_and", 0, 0, 2, 1},      /* 0x0f */
346   {"bit_or", 0, 0, 2, 1},       /* 0x10 */
347   {"bit_xor", 0, 0, 2, 1},      /* 0x11 */
348   {"bit_not", 0, 0, 1, 1},      /* 0x12 */
349   {"equal", 0, 0, 2, 1},        /* 0x13 */
350   {"less_signed", 0, 0, 2, 1},  /* 0x14 */
351   {"less_unsigned", 0, 0, 2, 1},        /* 0x15 */
352   {"ext", 1, 0, 1, 1},          /* 0x16 */
353   {"ref8", 0, 8, 1, 1},         /* 0x17 */
354   {"ref16", 0, 16, 1, 1},       /* 0x18 */
355   {"ref32", 0, 32, 1, 1},       /* 0x19 */
356   {"ref64", 0, 64, 1, 1},       /* 0x1a */
357   {"ref_float", 0, 0, 1, 1},    /* 0x1b */
358   {"ref_double", 0, 0, 1, 1},   /* 0x1c */
359   {"ref_long_double", 0, 0, 1, 1},      /* 0x1d */
360   {"l_to_d", 0, 0, 1, 1},       /* 0x1e */
361   {"d_to_l", 0, 0, 1, 1},       /* 0x1f */
362   {"if_goto", 2, 0, 1, 0},      /* 0x20 */
363   {"goto", 2, 0, 0, 0},         /* 0x21 */
364   {"const8", 1, 8, 0, 1},       /* 0x22 */
365   {"const16", 2, 16, 0, 1},     /* 0x23 */
366   {"const32", 4, 32, 0, 1},     /* 0x24 */
367   {"const64", 8, 64, 0, 1},     /* 0x25 */
368   {"reg", 2, 0, 0, 1},          /* 0x26 */
369   {"end", 0, 0, 0, 0},          /* 0x27 */
370   {"dup", 0, 0, 1, 2},          /* 0x28 */
371   {"pop", 0, 0, 1, 0},          /* 0x29 */
372   {"zero_ext", 1, 0, 1, 1},     /* 0x2a */
373   {"swap", 0, 0, 2, 2},         /* 0x2b */
374   {"getv", 2, 0, 0, 1},         /* 0x2c */
375   {"setv", 2, 0, 0, 1},         /* 0x2d */
376   {"tracev", 2, 0, 0, 1},       /* 0x2e */
377   {0, 0, 0, 0, 0},              /* 0x2f */
378   {"trace16", 2, 0, 1, 1},      /* 0x30 */
379 };
380
381
382 /* Disassemble the expression EXPR, writing to F.  */
383 void
384 ax_print (struct ui_file *f, struct agent_expr *x)
385 {
386   int i;
387   int is_float = 0;
388
389   fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
390   fprintf_filtered (f, _("Reg mask:"));
391   for (i = 0; i < x->reg_mask_len; ++i)
392     fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
393   fprintf_filtered (f, _("\n"));
394
395   /* Check the size of the name array against the number of entries in
396      the enum, to catch additions that people didn't sync.  */
397   if ((sizeof (aop_map) / sizeof (aop_map[0]))
398       != aop_last)
399     error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
400
401   for (i = 0; i < x->len;)
402     {
403       enum agent_op op = x->buf[i];
404
405       if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
406           || !aop_map[op].name)
407         {
408           fprintf_filtered (f, _("%3d  <bad opcode %02x>\n"), i, op);
409           i++;
410           continue;
411         }
412       if (i + 1 + aop_map[op].op_size > x->len)
413         {
414           fprintf_filtered (f, _("%3d  <incomplete opcode %s>\n"),
415                             i, aop_map[op].name);
416           break;
417         }
418
419       fprintf_filtered (f, "%3d  %s", i, aop_map[op].name);
420       if (aop_map[op].op_size > 0)
421         {
422           fputs_filtered (" ", f);
423
424           print_longest (f, 'd', 0,
425                          read_const (x, i + 1, aop_map[op].op_size));
426         }
427       fprintf_filtered (f, "\n");
428       i += 1 + aop_map[op].op_size;
429
430       is_float = (op == aop_float);
431     }
432 }
433
434 /* Add register REG to the register mask for expression AX.  */
435 void
436 ax_reg_mask (struct agent_expr *ax, int reg)
437 {
438   if (reg >= gdbarch_num_regs (ax->gdbarch))
439     {
440       /* This is a pseudo-register.  */
441       if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
442         error (_("'%s' is a pseudo-register; "
443                  "GDB cannot yet trace its contents."),
444                user_reg_map_regnum_to_name (ax->gdbarch, reg));
445       if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
446         error (_("Trace '%s' failed."),
447                user_reg_map_regnum_to_name (ax->gdbarch, reg));
448     }
449   else
450     {
451       int byte = reg / 8;
452
453       /* Grow the bit mask if necessary.  */
454       if (byte >= ax->reg_mask_len)
455         {
456           /* It's not appropriate to double here.  This isn't a
457              string buffer.  */
458           int new_len = byte + 1;
459           unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
460                                                   new_len
461                                                   * sizeof (ax->reg_mask[0]));
462           memset (new_reg_mask + ax->reg_mask_len, 0,
463                   (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
464           ax->reg_mask_len = new_len;
465           ax->reg_mask = new_reg_mask;
466         }
467
468       ax->reg_mask[byte] |= 1 << (reg % 8);
469     }
470 }
471
472 /* Given an agent expression AX, fill in requirements and other descriptive
473    bits.  */
474 void
475 ax_reqs (struct agent_expr *ax)
476 {
477   int i;
478   int height;
479
480   /* Jump target table.  targets[i] is non-zero iff we have found a
481      jump to offset i.  */
482   char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
483
484   /* Instruction boundary table.  boundary[i] is non-zero iff our scan
485      has reached an instruction starting at offset i.  */
486   char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
487
488   /* Stack height record.  If either targets[i] or boundary[i] is
489      non-zero, heights[i] is the height the stack should have before
490      executing the bytecode at that point.  */
491   int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
492
493   /* Pointer to a description of the present op.  */
494   struct aop_map *op;
495
496   memset (targets, 0, ax->len * sizeof (targets[0]));
497   memset (boundary, 0, ax->len * sizeof (boundary[0]));
498
499   ax->max_height = ax->min_height = height = 0;
500   ax->flaw = agent_flaw_none;
501   ax->max_data_size = 0;
502
503   for (i = 0; i < ax->len; i += 1 + op->op_size)
504     {
505       if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
506         {
507           ax->flaw = agent_flaw_bad_instruction;
508           return;
509         }
510
511       op = &aop_map[ax->buf[i]];
512
513       if (!op->name)
514         {
515           ax->flaw = agent_flaw_bad_instruction;
516           return;
517         }
518
519       if (i + 1 + op->op_size > ax->len)
520         {
521           ax->flaw = agent_flaw_incomplete_instruction;
522           return;
523         }
524
525       /* If this instruction is a forward jump target, does the
526          current stack height match the stack height at the jump
527          source?  */
528       if (targets[i] && (heights[i] != height))
529         {
530           ax->flaw = agent_flaw_height_mismatch;
531           return;
532         }
533
534       boundary[i] = 1;
535       heights[i] = height;
536
537       height -= op->consumed;
538       if (height < ax->min_height)
539         ax->min_height = height;
540       height += op->produced;
541       if (height > ax->max_height)
542         ax->max_height = height;
543
544       if (op->data_size > ax->max_data_size)
545         ax->max_data_size = op->data_size;
546
547       /* For jump instructions, check that the target is a valid
548          offset.  If it is, record the fact that that location is a
549          jump target, and record the height we expect there.  */
550       if (aop_goto == op - aop_map
551           || aop_if_goto == op - aop_map)
552         {
553           int target = read_const (ax, i + 1, 2);
554           if (target < 0 || target >= ax->len)
555             {
556               ax->flaw = agent_flaw_bad_jump;
557               return;
558             }
559
560           /* Do we have any information about what the stack height
561              should be at the target?  */
562           if (targets[target] || boundary[target])
563             {
564               if (heights[target] != height)
565                 {
566                   ax->flaw = agent_flaw_height_mismatch;
567                   return;
568                 }
569             }
570
571           /* Record the target, along with the stack height we expect.  */
572           targets[target] = 1;
573           heights[target] = height;
574         }
575
576       /* For unconditional jumps with a successor, check that the
577          successor is a target, and pick up its stack height.  */
578       if (aop_goto == op - aop_map
579           && i + 3 < ax->len)
580         {
581           if (!targets[i + 3])
582             {
583               ax->flaw = agent_flaw_hole;
584               return;
585             }
586
587           height = heights[i + 3];
588         }
589
590       /* For reg instructions, record the register in the bit mask.  */
591       if (aop_reg == op - aop_map)
592         {
593           int reg = read_const (ax, i + 1, 2);
594
595           ax_reg_mask (ax, reg);
596         }
597     }
598
599   /* Check that all the targets are on boundaries.  */
600   for (i = 0; i < ax->len; i++)
601     if (targets[i] && !boundary[i])
602       {
603         ax->flaw = agent_flaw_bad_jump;
604         return;
605       }
606
607   ax->final_height = height;
608 }