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