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