xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/ax-general.c (revision fdd524d4ccd2bb0c6f67401e938dabf773eb0372)
1 /* Functions for manipulating expressions designed to be executed on the agent
2    Copyright (C) 1998-2015 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 3 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, see <http://www.gnu.org/licenses/>.  */
18 
19 /* Despite what the above comment says about this file being part of
20    GDB, we would like to keep these functions free of GDB
21    dependencies, since we want to be able to use them in contexts
22    outside of GDB (test suites, the stub, etc.)  */
23 
24 #include "defs.h"
25 #include "ax.h"
26 
27 #include "value.h"
28 #include "user-regs.h"
29 
30 static void grow_expr (struct agent_expr *x, int n);
31 
32 static void append_const (struct agent_expr *x, LONGEST val, int n);
33 
34 static LONGEST read_const (struct agent_expr *x, int o, int n);
35 
36 static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
37 
38 /* Functions for building expressions.  */
39 
40 /* Allocate a new, empty agent expression.  */
41 struct agent_expr *
42 new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
43 {
44   struct agent_expr *x = xmalloc (sizeof (*x));
45 
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 
51   x->gdbarch = gdbarch;
52   x->scope = scope;
53 
54   /* Bit vector for registers used.  */
55   x->reg_mask_len = 1;
56   x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
57   memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
58 
59   x->tracing = 0;
60   x->trace_string = 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 /* Append a pick operator to EXPR.  DEPTH is the stack item to pick,
147    with 0 being top of stack.  */
148 
149 void
150 ax_pick (struct agent_expr *x, int depth)
151 {
152   if (depth < 0 || depth > 255)
153     error (_("GDB bug: ax-general.c (ax_pick): stack depth out of range"));
154   ax_simple (x, aop_pick);
155   append_const (x, 1, depth);
156 }
157 
158 
159 /* Append a sign-extension or zero-extension instruction to EXPR, to
160    extend an N-bit value.  */
161 static void
162 generic_ext (struct agent_expr *x, enum agent_op op, int n)
163 {
164   /* N must fit in a byte.  */
165   if (n < 0 || n > 255)
166     error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
167   /* That had better be enough range.  */
168   if (sizeof (LONGEST) * 8 > 255)
169     error (_("GDB bug: ax-general.c (generic_ext): "
170 	     "opcode has inadequate range"));
171 
172   grow_expr (x, 2);
173   x->buf[x->len++] = op;
174   x->buf[x->len++] = n;
175 }
176 
177 
178 /* Append a sign-extension instruction to EXPR, to extend an N-bit value.  */
179 void
180 ax_ext (struct agent_expr *x, int n)
181 {
182   generic_ext (x, aop_ext, n);
183 }
184 
185 
186 /* Append a zero-extension instruction to EXPR, to extend an N-bit value.  */
187 void
188 ax_zero_ext (struct agent_expr *x, int n)
189 {
190   generic_ext (x, aop_zero_ext, n);
191 }
192 
193 
194 /* Append a trace_quick instruction to EXPR, to record N bytes.  */
195 void
196 ax_trace_quick (struct agent_expr *x, int n)
197 {
198   /* N must fit in a byte.  */
199   if (n < 0 || n > 255)
200     error (_("GDB bug: ax-general.c (ax_trace_quick): "
201 	     "size out of range for trace_quick"));
202 
203   grow_expr (x, 2);
204   x->buf[x->len++] = aop_trace_quick;
205   x->buf[x->len++] = n;
206 }
207 
208 
209 /* Append a goto op to EXPR.  OP is the actual op (must be aop_goto or
210    aop_if_goto).  We assume we don't know the target offset yet,
211    because it's probably a forward branch, so we leave space in EXPR
212    for the target, and return the offset in EXPR of that space, so we
213    can backpatch it once we do know the target offset.  Use ax_label
214    to do the backpatching.  */
215 int
216 ax_goto (struct agent_expr *x, enum agent_op op)
217 {
218   grow_expr (x, 3);
219   x->buf[x->len + 0] = op;
220   x->buf[x->len + 1] = 0xff;
221   x->buf[x->len + 2] = 0xff;
222   x->len += 3;
223   return x->len - 2;
224 }
225 
226 /* Suppose a given call to ax_goto returns some value PATCH.  When you
227    know the offset TARGET that goto should jump to, call
228    ax_label (EXPR, PATCH, TARGET)
229    to patch TARGET into the ax_goto instruction.  */
230 void
231 ax_label (struct agent_expr *x, int patch, int target)
232 {
233   /* Make sure the value is in range.  Don't accept 0xffff as an
234      offset; that's our magic sentinel value for unpatched branches.  */
235   if (target < 0 || target >= 0xffff)
236     error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
237 
238   x->buf[patch] = (target >> 8) & 0xff;
239   x->buf[patch + 1] = target & 0xff;
240 }
241 
242 
243 /* Assemble code to push a constant on the stack.  */
244 void
245 ax_const_l (struct agent_expr *x, LONGEST l)
246 {
247   static enum agent_op ops[]
248   =
249   {aop_const8, aop_const16, aop_const32, aop_const64};
250   int size;
251   int op;
252 
253   /* How big is the number?  'op' keeps track of which opcode to use.
254      Notice that we don't really care whether the original number was
255      signed or unsigned; we always reproduce the value exactly, and
256      use the shortest representation.  */
257   for (op = 0, size = 8; size < 64; size *= 2, op++)
258     {
259       LONGEST lim = ((LONGEST) 1) << (size - 1);
260 
261       if (-lim <= l && l <= lim - 1)
262         break;
263     }
264 
265   /* Emit the right opcode...  */
266   ax_simple (x, ops[op]);
267 
268   /* Emit the low SIZE bytes as an unsigned number.  We know that
269      sign-extending this will yield l.  */
270   append_const (x, l, size / 8);
271 
272   /* Now, if it was negative, and not full-sized, sign-extend it.  */
273   if (l < 0 && size < 64)
274     ax_ext (x, size);
275 }
276 
277 
278 void
279 ax_const_d (struct agent_expr *x, LONGEST d)
280 {
281   /* FIXME: floating-point support not present yet.  */
282   error (_("GDB bug: ax-general.c (ax_const_d): "
283 	   "floating point not supported yet"));
284 }
285 
286 
287 /* Assemble code to push the value of register number REG on the
288    stack.  */
289 void
290 ax_reg (struct agent_expr *x, int reg)
291 {
292   if (reg >= gdbarch_num_regs (x->gdbarch))
293     {
294       /* This is a pseudo-register.  */
295       if (!gdbarch_ax_pseudo_register_push_stack_p (x->gdbarch))
296 	error (_("'%s' is a pseudo-register; "
297 		 "GDB cannot yet trace its contents."),
298 	       user_reg_map_regnum_to_name (x->gdbarch, reg));
299       if (gdbarch_ax_pseudo_register_push_stack (x->gdbarch, x, reg))
300 	error (_("Trace '%s' failed."),
301 	       user_reg_map_regnum_to_name (x->gdbarch, reg));
302     }
303   else
304     {
305       /* Make sure the register number is in range.  */
306       if (reg < 0 || reg > 0xffff)
307         error (_("GDB bug: ax-general.c (ax_reg): "
308 		 "register number out of range"));
309       grow_expr (x, 3);
310       x->buf[x->len] = aop_reg;
311       x->buf[x->len + 1] = (reg >> 8) & 0xff;
312       x->buf[x->len + 2] = (reg) & 0xff;
313       x->len += 3;
314     }
315 }
316 
317 /* Assemble code to operate on a trace state variable.  */
318 
319 void
320 ax_tsv (struct agent_expr *x, enum agent_op op, int num)
321 {
322   /* Make sure the tsv number is in range.  */
323   if (num < 0 || num > 0xffff)
324     internal_error (__FILE__, __LINE__,
325 		    _("ax-general.c (ax_tsv): variable "
326 		      "number is %d, out of range"), num);
327 
328   grow_expr (x, 3);
329   x->buf[x->len] = op;
330   x->buf[x->len + 1] = (num >> 8) & 0xff;
331   x->buf[x->len + 2] = (num) & 0xff;
332   x->len += 3;
333 }
334 
335 /* Append a string to the expression.  Note that the string is going
336    into the bytecodes directly, not on the stack.  As a precaution,
337    include both length as prefix, and terminate with a NUL.  (The NUL
338    is counted in the length.)  */
339 
340 void
341 ax_string (struct agent_expr *x, const char *str, int slen)
342 {
343   int i;
344 
345   /* Make sure the string length is reasonable.  */
346   if (slen < 0 || slen > 0xffff)
347     internal_error (__FILE__, __LINE__,
348 		    _("ax-general.c (ax_string): string "
349 		      "length is %d, out of allowed range"), slen);
350 
351   grow_expr (x, 2 + slen + 1);
352   x->buf[x->len++] = ((slen + 1) >> 8) & 0xff;
353   x->buf[x->len++] = (slen + 1) & 0xff;
354   for (i = 0; i < slen; ++i)
355     x->buf[x->len++] = str[i];
356   x->buf[x->len++] = '\0';
357 }
358 
359 
360 
361 /* Functions for disassembling agent expressions, and otherwise
362    debugging the expression compiler.  */
363 
364 struct aop_map aop_map[] =
365 {
366   {0, 0, 0, 0, 0}
367 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
368   , { # NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED }
369 #include "ax.def"
370 #undef DEFOP
371 };
372 
373 
374 /* Disassemble the expression EXPR, writing to F.  */
375 void
376 ax_print (struct ui_file *f, struct agent_expr *x)
377 {
378   int i;
379 
380   fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
381   fprintf_filtered (f, _("Reg mask:"));
382   for (i = 0; i < x->reg_mask_len; ++i)
383     fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
384   fprintf_filtered (f, _("\n"));
385 
386   /* Check the size of the name array against the number of entries in
387      the enum, to catch additions that people didn't sync.  */
388   if ((sizeof (aop_map) / sizeof (aop_map[0]))
389       != aop_last)
390     error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
391 
392   for (i = 0; i < x->len;)
393     {
394       enum agent_op op = x->buf[i];
395 
396       if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
397 	  || !aop_map[op].name)
398 	{
399 	  fprintf_filtered (f, _("%3d  <bad opcode %02x>\n"), i, op);
400 	  i++;
401 	  continue;
402 	}
403       if (i + 1 + aop_map[op].op_size > x->len)
404 	{
405 	  fprintf_filtered (f, _("%3d  <incomplete opcode %s>\n"),
406 			    i, aop_map[op].name);
407 	  break;
408 	}
409 
410       fprintf_filtered (f, "%3d  %s", i, aop_map[op].name);
411       if (aop_map[op].op_size > 0)
412 	{
413 	  fputs_filtered (" ", f);
414 
415 	  print_longest (f, 'd', 0,
416 			 read_const (x, i + 1, aop_map[op].op_size));
417 	}
418       /* Handle the complicated printf arguments specially.  */
419       else if (op == aop_printf)
420 	{
421 	  int slen, nargs;
422 
423 	  i++;
424 	  nargs = x->buf[i++];
425 	  slen = x->buf[i++];
426 	  slen = slen * 256 + x->buf[i++];
427 	  fprintf_filtered (f, _(" \"%s\", %d args"),
428 			    &(x->buf[i]), nargs);
429 	  i += slen - 1;
430 	}
431       fprintf_filtered (f, "\n");
432       i += 1 + aop_map[op].op_size;
433     }
434 }
435 
436 /* Add register REG to the register mask for expression AX.  */
437 void
438 ax_reg_mask (struct agent_expr *ax, int reg)
439 {
440   if (reg >= gdbarch_num_regs (ax->gdbarch))
441     {
442       /* This is a pseudo-register.  */
443       if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
444 	error (_("'%s' is a pseudo-register; "
445 		 "GDB cannot yet trace its contents."),
446 	       user_reg_map_regnum_to_name (ax->gdbarch, reg));
447       if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
448 	error (_("Trace '%s' failed."),
449 	       user_reg_map_regnum_to_name (ax->gdbarch, reg));
450     }
451   else
452     {
453       int byte = reg / 8;
454 
455       /* Grow the bit mask if necessary.  */
456       if (byte >= ax->reg_mask_len)
457         {
458           /* It's not appropriate to double here.  This isn't a
459 	     string buffer.  */
460           int new_len = byte + 1;
461           unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
462 					          new_len
463 					          * sizeof (ax->reg_mask[0]));
464           memset (new_reg_mask + ax->reg_mask_len, 0,
465 	          (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
466           ax->reg_mask_len = new_len;
467           ax->reg_mask = new_reg_mask;
468         }
469 
470       ax->reg_mask[byte] |= 1 << (reg % 8);
471     }
472 }
473 
474 /* Given an agent expression AX, fill in requirements and other descriptive
475    bits.  */
476 void
477 ax_reqs (struct agent_expr *ax)
478 {
479   int i;
480   int height;
481 
482   /* Jump target table.  targets[i] is non-zero iff we have found a
483      jump to offset i.  */
484   char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
485 
486   /* Instruction boundary table.  boundary[i] is non-zero iff our scan
487      has reached an instruction starting at offset i.  */
488   char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
489 
490   /* Stack height record.  If either targets[i] or boundary[i] is
491      non-zero, heights[i] is the height the stack should have before
492      executing the bytecode at that point.  */
493   int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
494 
495   /* Pointer to a description of the present op.  */
496   struct aop_map *op;
497 
498   memset (targets, 0, ax->len * sizeof (targets[0]));
499   memset (boundary, 0, ax->len * sizeof (boundary[0]));
500 
501   ax->max_height = ax->min_height = height = 0;
502   ax->flaw = agent_flaw_none;
503   ax->max_data_size = 0;
504 
505   for (i = 0; i < ax->len; i += 1 + op->op_size)
506     {
507       if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
508 	{
509 	  ax->flaw = agent_flaw_bad_instruction;
510 	  return;
511 	}
512 
513       op = &aop_map[ax->buf[i]];
514 
515       if (!op->name)
516 	{
517 	  ax->flaw = agent_flaw_bad_instruction;
518 	  return;
519 	}
520 
521       if (i + 1 + op->op_size > ax->len)
522 	{
523 	  ax->flaw = agent_flaw_incomplete_instruction;
524 	  return;
525 	}
526 
527       /* If this instruction is a forward jump target, does the
528          current stack height match the stack height at the jump
529          source?  */
530       if (targets[i] && (heights[i] != height))
531 	{
532 	  ax->flaw = agent_flaw_height_mismatch;
533 	  return;
534 	}
535 
536       boundary[i] = 1;
537       heights[i] = height;
538 
539       height -= op->consumed;
540       if (height < ax->min_height)
541 	ax->min_height = height;
542       height += op->produced;
543       if (height > ax->max_height)
544 	ax->max_height = height;
545 
546       if (op->data_size > ax->max_data_size)
547 	ax->max_data_size = op->data_size;
548 
549       /* For jump instructions, check that the target is a valid
550          offset.  If it is, record the fact that that location is a
551          jump target, and record the height we expect there.  */
552       if (aop_goto == op - aop_map
553 	  || aop_if_goto == op - aop_map)
554 	{
555 	  int target = read_const (ax, i + 1, 2);
556 	  if (target < 0 || target >= ax->len)
557 	    {
558 	      ax->flaw = agent_flaw_bad_jump;
559 	      return;
560 	    }
561 
562 	  /* Do we have any information about what the stack height
563              should be at the target?  */
564 	  if (targets[target] || boundary[target])
565 	    {
566 	      if (heights[target] != height)
567 		{
568 		  ax->flaw = agent_flaw_height_mismatch;
569 		  return;
570 		}
571 	    }
572 
573           /* Record the target, along with the stack height we expect.  */
574           targets[target] = 1;
575           heights[target] = height;
576 	}
577 
578       /* For unconditional jumps with a successor, check that the
579          successor is a target, and pick up its stack height.  */
580       if (aop_goto == op - aop_map
581 	  && i + 3 < ax->len)
582 	{
583 	  if (!targets[i + 3])
584 	    {
585 	      ax->flaw = agent_flaw_hole;
586 	      return;
587 	    }
588 
589 	  height = heights[i + 3];
590 	}
591 
592       /* For reg instructions, record the register in the bit mask.  */
593       if (aop_reg == op - aop_map)
594 	{
595 	  int reg = read_const (ax, i + 1, 2);
596 
597 	  ax_reg_mask (ax, reg);
598 	}
599     }
600 
601   /* Check that all the targets are on boundaries.  */
602   for (i = 0; i < ax->len; i++)
603     if (targets[i] && !boundary[i])
604       {
605 	ax->flaw = agent_flaw_bad_jump;
606 	return;
607       }
608 
609   ax->final_height = height;
610 }
611