2010-05-11 Pierre Muller <muller@ics.u-strasbg.fr>
[platform/upstream/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 static void grow_expr (struct agent_expr *x, int n);
32
33 static void append_const (struct agent_expr *x, LONGEST val, int n);
34
35 static LONGEST read_const (struct agent_expr *x, int o, int n);
36
37 static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
38 \f
39 /* Functions for building expressions.  */
40
41 /* Allocate a new, empty agent expression.  */
42 struct agent_expr *
43 new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
44 {
45   struct agent_expr *x = xmalloc (sizeof (*x));
46
47   x->len = 0;
48   x->size = 1;                  /* Change this to a larger value once
49                                    reallocation code is tested.  */
50   x->buf = xmalloc (x->size);
51
52   x->gdbarch = gdbarch;
53   x->scope = scope;
54
55   /* Bit vector for registers used.  */
56   x->reg_mask_len = 1;
57   x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
58   memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
59
60   return x;
61 }
62
63 /* Free a agent expression.  */
64 void
65 free_agent_expr (struct agent_expr *x)
66 {
67   xfree (x->buf);
68   xfree (x->reg_mask);
69   xfree (x);
70 }
71
72 static void
73 do_free_agent_expr_cleanup (void *x)
74 {
75   free_agent_expr (x);
76 }
77
78 struct cleanup *
79 make_cleanup_free_agent_expr (struct agent_expr *x)
80 {
81   return make_cleanup (do_free_agent_expr_cleanup, x);
82 }
83
84
85 /* Make sure that X has room for at least N more bytes.  This doesn't
86    affect the length, just the allocated size.  */
87 static void
88 grow_expr (struct agent_expr *x, int n)
89 {
90   if (x->len + n > x->size)
91     {
92       x->size *= 2;
93       if (x->size < x->len + n)
94         x->size = x->len + n + 10;
95       x->buf = xrealloc (x->buf, x->size);
96     }
97 }
98
99
100 /* Append the low N bytes of VAL as an N-byte integer to the
101    expression X, in big-endian order.  */
102 static void
103 append_const (struct agent_expr *x, LONGEST val, int n)
104 {
105   int i;
106
107   grow_expr (x, n);
108   for (i = n - 1; i >= 0; i--)
109     {
110       x->buf[x->len + i] = val & 0xff;
111       val >>= 8;
112     }
113   x->len += n;
114 }
115
116
117 /* Extract an N-byte big-endian unsigned integer from expression X at
118    offset O.  */
119 static LONGEST
120 read_const (struct agent_expr *x, int o, int n)
121 {
122   int i;
123   LONGEST accum = 0;
124
125   /* Make sure we're not reading off the end of the expression.  */
126   if (o + n > x->len)
127     error (_("GDB bug: ax-general.c (read_const): incomplete constant"));
128
129   for (i = 0; i < n; i++)
130     accum = (accum << 8) | x->buf[o + i];
131
132   return accum;
133 }
134
135
136 /* Append a simple operator OP to EXPR.  */
137 void
138 ax_simple (struct agent_expr *x, enum agent_op op)
139 {
140   grow_expr (x, 1);
141   x->buf[x->len++] = op;
142 }
143
144
145 /* Append a sign-extension or zero-extension instruction to EXPR, to
146    extend an N-bit value.  */
147 static void
148 generic_ext (struct agent_expr *x, enum agent_op op, int n)
149 {
150   /* N must fit in a byte.  */
151   if (n < 0 || n > 255)
152     error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
153   /* That had better be enough range.  */
154   if (sizeof (LONGEST) * 8 > 255)
155     error (_("GDB bug: ax-general.c (generic_ext): opcode has inadequate range"));
156
157   grow_expr (x, 2);
158   x->buf[x->len++] = op;
159   x->buf[x->len++] = n;
160 }
161
162
163 /* Append a sign-extension instruction to EXPR, to extend an N-bit value.  */
164 void
165 ax_ext (struct agent_expr *x, int n)
166 {
167   generic_ext (x, aop_ext, n);
168 }
169
170
171 /* Append a zero-extension instruction to EXPR, to extend an N-bit value.  */
172 void
173 ax_zero_ext (struct agent_expr *x, int n)
174 {
175   generic_ext (x, aop_zero_ext, n);
176 }
177
178
179 /* Append a trace_quick instruction to EXPR, to record N bytes.  */
180 void
181 ax_trace_quick (struct agent_expr *x, int n)
182 {
183   /* N must fit in a byte.  */
184   if (n < 0 || n > 255)
185     error (_("GDB bug: ax-general.c (ax_trace_quick): size out of range for trace_quick"));
186
187   grow_expr (x, 2);
188   x->buf[x->len++] = aop_trace_quick;
189   x->buf[x->len++] = n;
190 }
191
192
193 /* Append a goto op to EXPR.  OP is the actual op (must be aop_goto or
194    aop_if_goto).  We assume we don't know the target offset yet,
195    because it's probably a forward branch, so we leave space in EXPR
196    for the target, and return the offset in EXPR of that space, so we
197    can backpatch it once we do know the target offset.  Use ax_label
198    to do the backpatching.  */
199 int
200 ax_goto (struct agent_expr *x, enum agent_op op)
201 {
202   grow_expr (x, 3);
203   x->buf[x->len + 0] = op;
204   x->buf[x->len + 1] = 0xff;
205   x->buf[x->len + 2] = 0xff;
206   x->len += 3;
207   return x->len - 2;
208 }
209
210 /* Suppose a given call to ax_goto returns some value PATCH.  When you
211    know the offset TARGET that goto should jump to, call
212    ax_label (EXPR, PATCH, TARGET)
213    to patch TARGET into the ax_goto instruction.  */
214 void
215 ax_label (struct agent_expr *x, int patch, int target)
216 {
217   /* Make sure the value is in range.  Don't accept 0xffff as an
218      offset; that's our magic sentinel value for unpatched branches.  */
219   if (target < 0 || target >= 0xffff)
220     error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
221
222   x->buf[patch] = (target >> 8) & 0xff;
223   x->buf[patch + 1] = target & 0xff;
224 }
225
226
227 /* Assemble code to push a constant on the stack.  */
228 void
229 ax_const_l (struct agent_expr *x, LONGEST l)
230 {
231   static enum agent_op ops[]
232   =
233   {aop_const8, aop_const16, aop_const32, aop_const64};
234   int size;
235   int op;
236
237   /* How big is the number?  'op' keeps track of which opcode to use.
238      Notice that we don't really care whether the original number was
239      signed or unsigned; we always reproduce the value exactly, and
240      use the shortest representation.  */
241   for (op = 0, size = 8; size < 64; size *= 2, op++)
242     {
243       LONGEST lim = ((LONGEST) 1) << (size - 1);
244
245       if (-lim <= l && l <= lim - 1)
246         break;
247     }
248
249   /* Emit the right opcode... */
250   ax_simple (x, ops[op]);
251
252   /* Emit the low SIZE bytes as an unsigned number.  We know that
253      sign-extending this will yield l.  */
254   append_const (x, l, size / 8);
255
256   /* Now, if it was negative, and not full-sized, sign-extend it.  */
257   if (l < 0 && size < 64)
258     ax_ext (x, size);
259 }
260
261
262 void
263 ax_const_d (struct agent_expr *x, LONGEST d)
264 {
265   /* FIXME: floating-point support not present yet.  */
266   error (_("GDB bug: ax-general.c (ax_const_d): floating point not supported yet"));
267 }
268
269
270 /* Assemble code to push the value of register number REG on the
271    stack.  */
272 void
273 ax_reg (struct agent_expr *x, int reg)
274 {
275   /* Make sure the register number is in range.  */
276   if (reg < 0 || reg > 0xffff)
277     error (_("GDB bug: ax-general.c (ax_reg): register number out of range"));
278   grow_expr (x, 3);
279   x->buf[x->len] = aop_reg;
280   x->buf[x->len + 1] = (reg >> 8) & 0xff;
281   x->buf[x->len + 2] = (reg) & 0xff;
282   x->len += 3;
283 }
284
285 /* Assemble code to operate on a trace state variable.  */
286
287 void
288 ax_tsv (struct agent_expr *x, enum agent_op op, int num)
289 {
290   /* Make sure the tsv number is in range.  */
291   if (num < 0 || num > 0xffff)
292     internal_error (__FILE__, __LINE__, _("ax-general.c (ax_tsv): variable number is %d, out of range"), num);
293
294   grow_expr (x, 3);
295   x->buf[x->len] = op;
296   x->buf[x->len + 1] = (num >> 8) & 0xff;
297   x->buf[x->len + 2] = (num) & 0xff;
298   x->len += 3;
299 }
300 \f
301
302
303 /* Functions for disassembling agent expressions, and otherwise
304    debugging the expression compiler.  */
305
306 struct aop_map aop_map[] =
307 {
308   {0, 0, 0, 0, 0},
309   {"float", 0, 0, 0, 0},        /* 0x01 */
310   {"add", 0, 0, 2, 1},          /* 0x02 */
311   {"sub", 0, 0, 2, 1},          /* 0x03 */
312   {"mul", 0, 0, 2, 1},          /* 0x04 */
313   {"div_signed", 0, 0, 2, 1},   /* 0x05 */
314   {"div_unsigned", 0, 0, 2, 1}, /* 0x06 */
315   {"rem_signed", 0, 0, 2, 1},   /* 0x07 */
316   {"rem_unsigned", 0, 0, 2, 1}, /* 0x08 */
317   {"lsh", 0, 0, 2, 1},          /* 0x09 */
318   {"rsh_signed", 0, 0, 2, 1},   /* 0x0a */
319   {"rsh_unsigned", 0, 0, 2, 1}, /* 0x0b */
320   {"trace", 0, 0, 2, 0},        /* 0x0c */
321   {"trace_quick", 1, 0, 1, 1},  /* 0x0d */
322   {"log_not", 0, 0, 1, 1},      /* 0x0e */
323   {"bit_and", 0, 0, 2, 1},      /* 0x0f */
324   {"bit_or", 0, 0, 2, 1},       /* 0x10 */
325   {"bit_xor", 0, 0, 2, 1},      /* 0x11 */
326   {"bit_not", 0, 0, 1, 1},      /* 0x12 */
327   {"equal", 0, 0, 2, 1},        /* 0x13 */
328   {"less_signed", 0, 0, 2, 1},  /* 0x14 */
329   {"less_unsigned", 0, 0, 2, 1},        /* 0x15 */
330   {"ext", 1, 0, 1, 1},          /* 0x16 */
331   {"ref8", 0, 8, 1, 1},         /* 0x17 */
332   {"ref16", 0, 16, 1, 1},       /* 0x18 */
333   {"ref32", 0, 32, 1, 1},       /* 0x19 */
334   {"ref64", 0, 64, 1, 1},       /* 0x1a */
335   {"ref_float", 0, 0, 1, 1},    /* 0x1b */
336   {"ref_double", 0, 0, 1, 1},   /* 0x1c */
337   {"ref_long_double", 0, 0, 1, 1},      /* 0x1d */
338   {"l_to_d", 0, 0, 1, 1},       /* 0x1e */
339   {"d_to_l", 0, 0, 1, 1},       /* 0x1f */
340   {"if_goto", 2, 0, 1, 0},      /* 0x20 */
341   {"goto", 2, 0, 0, 0},         /* 0x21 */
342   {"const8", 1, 8, 0, 1},       /* 0x22 */
343   {"const16", 2, 16, 0, 1},     /* 0x23 */
344   {"const32", 4, 32, 0, 1},     /* 0x24 */
345   {"const64", 8, 64, 0, 1},     /* 0x25 */
346   {"reg", 2, 0, 0, 1},          /* 0x26 */
347   {"end", 0, 0, 0, 0},          /* 0x27 */
348   {"dup", 0, 0, 1, 2},          /* 0x28 */
349   {"pop", 0, 0, 1, 0},          /* 0x29 */
350   {"zero_ext", 1, 0, 1, 1},     /* 0x2a */
351   {"swap", 0, 0, 2, 2},         /* 0x2b */
352   {"getv", 2, 0, 0, 1},         /* 0x2c */
353   {"setv", 2, 0, 0, 1},         /* 0x2d */
354   {"tracev", 2, 0, 0, 1},       /* 0x2e */
355   {0, 0, 0, 0, 0},              /* 0x2f */
356   {"trace16", 2, 0, 1, 1},      /* 0x30 */
357 };
358
359
360 /* Disassemble the expression EXPR, writing to F.  */
361 void
362 ax_print (struct ui_file *f, struct agent_expr *x)
363 {
364   int i;
365   int is_float = 0;
366
367   fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
368   fprintf_filtered (f, _("Reg mask:"));
369   for (i = 0; i < x->reg_mask_len; ++i)
370     fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
371   fprintf_filtered (f, _("\n"));
372
373   /* Check the size of the name array against the number of entries in
374      the enum, to catch additions that people didn't sync.  */
375   if ((sizeof (aop_map) / sizeof (aop_map[0]))
376       != aop_last)
377     error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
378
379   for (i = 0; i < x->len;)
380     {
381       enum agent_op op = x->buf[i];
382
383       if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
384           || !aop_map[op].name)
385         {
386           fprintf_filtered (f, _("%3d  <bad opcode %02x>\n"), i, op);
387           i++;
388           continue;
389         }
390       if (i + 1 + aop_map[op].op_size > x->len)
391         {
392           fprintf_filtered (f, _("%3d  <incomplete opcode %s>\n"),
393                             i, aop_map[op].name);
394           break;
395         }
396
397       fprintf_filtered (f, "%3d  %s", i, aop_map[op].name);
398       if (aop_map[op].op_size > 0)
399         {
400           fputs_filtered (" ", f);
401
402           print_longest (f, 'd', 0,
403                          read_const (x, i + 1, aop_map[op].op_size));
404         }
405       fprintf_filtered (f, "\n");
406       i += 1 + aop_map[op].op_size;
407
408       is_float = (op == aop_float);
409     }
410 }
411
412 /* Add register REG to the register mask for expression AX.  */
413 void
414 ax_reg_mask (struct agent_expr *ax, int reg)
415 {
416   int byte = reg / 8;
417
418   /* Grow the bit mask if necessary.  */
419   if (byte >= ax->reg_mask_len)
420     {
421       /* It's not appropriate to double here.  This isn't a
422          string buffer.  */
423       int new_len = byte + 1;
424       unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
425                                               new_len * sizeof (ax->reg_mask[0]));
426       memset (new_reg_mask + ax->reg_mask_len, 0,
427               (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
428       ax->reg_mask_len = new_len;
429       ax->reg_mask = new_reg_mask;
430     }
431
432   ax->reg_mask[byte] |= 1 << (reg % 8);
433 }
434
435 /* Given an agent expression AX, fill in requirements and other descriptive
436    bits.  */
437 void
438 ax_reqs (struct agent_expr *ax)
439 {
440   int i;
441   int height;
442
443   /* Jump target table.  targets[i] is non-zero iff we have found a
444      jump to offset i.  */
445   char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
446
447   /* Instruction boundary table.  boundary[i] is non-zero iff our scan
448      has reached an instruction starting at offset i.  */
449   char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
450
451   /* Stack height record.  If either targets[i] or boundary[i] is
452      non-zero, heights[i] is the height the stack should have before
453      executing the bytecode at that point.  */
454   int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
455
456   /* Pointer to a description of the present op.  */
457   struct aop_map *op;
458
459   memset (targets, 0, ax->len * sizeof (targets[0]));
460   memset (boundary, 0, ax->len * sizeof (boundary[0]));
461
462   ax->max_height = ax->min_height = height = 0;
463   ax->flaw = agent_flaw_none;
464   ax->max_data_size = 0;
465
466   for (i = 0; i < ax->len; i += 1 + op->op_size)
467     {
468       if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
469         {
470           ax->flaw = agent_flaw_bad_instruction;
471           return;
472         }
473
474       op = &aop_map[ax->buf[i]];
475
476       if (!op->name)
477         {
478           ax->flaw = agent_flaw_bad_instruction;
479           return;
480         }
481
482       if (i + 1 + op->op_size > ax->len)
483         {
484           ax->flaw = agent_flaw_incomplete_instruction;
485           return;
486         }
487
488       /* If this instruction is a forward jump target, does the
489          current stack height match the stack height at the jump
490          source?  */
491       if (targets[i] && (heights[i] != height))
492         {
493           ax->flaw = agent_flaw_height_mismatch;
494           return;
495         }
496
497       boundary[i] = 1;
498       heights[i] = height;
499
500       height -= op->consumed;
501       if (height < ax->min_height)
502         ax->min_height = height;
503       height += op->produced;
504       if (height > ax->max_height)
505         ax->max_height = height;
506
507       if (op->data_size > ax->max_data_size)
508         ax->max_data_size = op->data_size;
509
510       /* For jump instructions, check that the target is a valid
511          offset.  If it is, record the fact that that location is a
512          jump target, and record the height we expect there.  */
513       if (aop_goto == op - aop_map
514           || aop_if_goto == op - aop_map)
515         {
516           int target = read_const (ax, i + 1, 2);
517           if (target < 0 || target >= ax->len)
518             {
519               ax->flaw = agent_flaw_bad_jump;
520               return;
521             }
522
523           /* Do we have any information about what the stack height
524              should be at the target?  */
525           if (targets[target] || boundary[target])
526             {
527               if (heights[target] != height)
528                 {
529                   ax->flaw = agent_flaw_height_mismatch;
530                   return;
531                 }
532             }
533
534           /* Record the target, along with the stack height we expect.  */
535           targets[target] = 1;
536           heights[target] = height;
537         }
538
539       /* For unconditional jumps with a successor, check that the
540          successor is a target, and pick up its stack height.  */
541       if (aop_goto == op - aop_map
542           && i + 3 < ax->len)
543         {
544           if (!targets[i + 3])
545             {
546               ax->flaw = agent_flaw_hole;
547               return;
548             }
549
550           height = heights[i + 3];
551         }
552
553       /* For reg instructions, record the register in the bit mask.  */
554       if (aop_reg == op - aop_map)
555         {
556           int reg = read_const (ax, i + 1, 2);
557
558           ax_reg_mask (ax, reg);
559         }
560     }
561
562   /* Check that all the targets are on boundaries.  */
563   for (i = 0; i < ax->len; i++)
564     if (targets[i] && !boundary[i])
565       {
566         ax->flaw = agent_flaw_bad_jump;
567         return;
568       }
569
570   ax->final_height = height;
571 }