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