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