2011-05-23 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / ax-general.c
CommitLineData
c906108c 1/* Functions for manipulating expressions designed to be executed on the agent
7b6bb8da 2 Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
0fb0cc75 3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 19
c906108c
SS
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
7a292a7a 28#include "value.h"
b66d6d2e 29#include "gdb_string.h"
7a292a7a 30
175ff332
HZ
31#include "user-regs.h"
32
a14ed312 33static void grow_expr (struct agent_expr *x, int n);
392a587b 34
a14ed312 35static void append_const (struct agent_expr *x, LONGEST val, int n);
392a587b 36
a14ed312 37static LONGEST read_const (struct agent_expr *x, int o, int n);
392a587b 38
a14ed312 39static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
c906108c
SS
40\f
41/* Functions for building expressions. */
42
43/* Allocate a new, empty agent expression. */
44struct agent_expr *
35c9c7ba 45new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
c906108c
SS
46{
47 struct agent_expr *x = xmalloc (sizeof (*x));
35c9c7ba 48
c5aa993b 49 x->len = 0;
c906108c
SS
50 x->size = 1; /* Change this to a larger value once
51 reallocation code is tested. */
c5aa993b 52 x->buf = xmalloc (x->size);
35c9c7ba
SS
53
54 x->gdbarch = gdbarch;
c906108c
SS
55 x->scope = scope;
56
35c9c7ba
SS
57 /* Bit vector for registers used. */
58 x->reg_mask_len = 1;
59 x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
60 memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
61
c906108c
SS
62 return x;
63}
64
65/* Free a agent expression. */
66void
fba45db2 67free_agent_expr (struct agent_expr *x)
c906108c 68{
b8c9b27d 69 xfree (x->buf);
35c9c7ba 70 xfree (x->reg_mask);
b8c9b27d 71 xfree (x);
c906108c
SS
72}
73
f23d52e0
AC
74static void
75do_free_agent_expr_cleanup (void *x)
76{
77 free_agent_expr (x);
78}
79
80struct cleanup *
81make_cleanup_free_agent_expr (struct agent_expr *x)
82{
83 return make_cleanup (do_free_agent_expr_cleanup, x);
84}
85
c906108c
SS
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. */
89static void
fba45db2 90grow_expr (struct agent_expr *x, int n)
c906108c
SS
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. */
104static void
fba45db2 105append_const (struct agent_expr *x, LONGEST val, int n)
c906108c
SS
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. */
121static LONGEST
fba45db2 122read_const (struct agent_expr *x, int o, int n)
c906108c
SS
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)
3d263c1d 129 error (_("GDB bug: ax-general.c (read_const): incomplete constant"));
c906108c
SS
130
131 for (i = 0; i < n; i++)
132 accum = (accum << 8) | x->buf[o + i];
c5aa993b 133
c906108c
SS
134 return accum;
135}
136
137
138/* Append a simple operator OP to EXPR. */
139void
fba45db2 140ax_simple (struct agent_expr *x, enum agent_op op)
c906108c
SS
141{
142 grow_expr (x, 1);
143 x->buf[x->len++] = op;
144}
145
c7f96d2b
TT
146/* Append a pick operator to EXPR. DEPTH is the stack item to pick,
147 with 0 being top of stack. */
2b52013f 148
c7f96d2b
TT
149void
150ax_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
c906108c
SS
158
159/* Append a sign-extension or zero-extension instruction to EXPR, to
160 extend an N-bit value. */
161static void
fba45db2 162generic_ext (struct agent_expr *x, enum agent_op op, int n)
c906108c
SS
163{
164 /* N must fit in a byte. */
165 if (n < 0 || n > 255)
3d263c1d 166 error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
c906108c
SS
167 /* That had better be enough range. */
168 if (sizeof (LONGEST) * 8 > 255)
3e43a32a
MS
169 error (_("GDB bug: ax-general.c (generic_ext): "
170 "opcode has inadequate range"));
c906108c
SS
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. */
179void
fba45db2 180ax_ext (struct agent_expr *x, int n)
c906108c
SS
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. */
187void
fba45db2 188ax_zero_ext (struct agent_expr *x, int n)
c906108c
SS
189{
190 generic_ext (x, aop_zero_ext, n);
191}
192
193
194/* Append a trace_quick instruction to EXPR, to record N bytes. */
195void
fba45db2 196ax_trace_quick (struct agent_expr *x, int n)
c906108c
SS
197{
198 /* N must fit in a byte. */
199 if (n < 0 || n > 255)
3e43a32a
MS
200 error (_("GDB bug: ax-general.c (ax_trace_quick): "
201 "size out of range for trace_quick"));
c906108c
SS
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. */
c5aa993b 215int
fba45db2 216ax_goto (struct agent_expr *x, enum agent_op op)
c906108c
SS
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
c5aa993b 228 ax_label (EXPR, PATCH, TARGET)
c906108c
SS
229 to patch TARGET into the ax_goto instruction. */
230void
fba45db2 231ax_label (struct agent_expr *x, int patch, int target)
c906108c
SS
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)
3d263c1d 236 error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
c5aa993b 237
c906108c
SS
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. */
244void
fba45db2 245ax_const_l (struct agent_expr *x, LONGEST l)
c906108c
SS
246{
247 static enum agent_op ops[]
c5aa993b
JM
248 =
249 {aop_const8, aop_const16, aop_const32, aop_const64};
c906108c
SS
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++)
44a81774 258 {
cf3e25ca 259 LONGEST lim = ((LONGEST) 1) << (size - 1);
44a81774
JB
260
261 if (-lim <= l && l <= lim - 1)
262 break;
263 }
c906108c 264
0e2de366 265 /* Emit the right opcode... */
c906108c
SS
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
278void
fba45db2 279ax_const_d (struct agent_expr *x, LONGEST d)
c906108c
SS
280{
281 /* FIXME: floating-point support not present yet. */
3e43a32a
MS
282 error (_("GDB bug: ax-general.c (ax_const_d): "
283 "floating point not supported yet"));
c906108c
SS
284}
285
286
287/* Assemble code to push the value of register number REG on the
288 stack. */
c5aa993b 289void
fba45db2 290ax_reg (struct agent_expr *x, int reg)
c906108c 291{
175ff332
HZ
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)
3e43a32a
MS
307 error (_("GDB bug: ax-general.c (ax_reg): "
308 "register number out of range"));
175ff332
HZ
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 }
c906108c 315}
f61e138d
SS
316
317/* Assemble code to operate on a trace state variable. */
318
319void
320ax_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)
3e43a32a
MS
324 internal_error (__FILE__, __LINE__,
325 _("ax-general.c (ax_tsv): variable "
326 "number is %d, out of range"), num);
f61e138d
SS
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}
c5aa993b 334\f
c906108c
SS
335
336
c906108c
SS
337/* Functions for disassembling agent expressions, and otherwise
338 debugging the expression compiler. */
339
c5aa993b
JM
340struct aop_map aop_map[] =
341{
94d5e490
TT
342 {0, 0, 0, 0, 0}
343#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
344 , { # NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED }
345#include "ax.def"
346#undef DEFOP
c906108c
SS
347};
348
349
350/* Disassemble the expression EXPR, writing to F. */
351void
fba45db2 352ax_print (struct ui_file *f, struct agent_expr *x)
c906108c
SS
353{
354 int i;
355 int is_float = 0;
356
35c9c7ba
SS
357 fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
358 fprintf_filtered (f, _("Reg mask:"));
359 for (i = 0; i < x->reg_mask_len; ++i)
360 fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
361 fprintf_filtered (f, _("\n"));
362
c906108c
SS
363 /* Check the size of the name array against the number of entries in
364 the enum, to catch additions that people didn't sync. */
365 if ((sizeof (aop_map) / sizeof (aop_map[0]))
366 != aop_last)
3d263c1d 367 error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
c5aa993b
JM
368
369 for (i = 0; i < x->len;)
c906108c
SS
370 {
371 enum agent_op op = x->buf[i];
372
373 if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
c5aa993b 374 || !aop_map[op].name)
c906108c 375 {
3d263c1d 376 fprintf_filtered (f, _("%3d <bad opcode %02x>\n"), i, op);
c906108c
SS
377 i++;
378 continue;
379 }
a04b0428 380 if (i + 1 + aop_map[op].op_size > x->len)
c906108c 381 {
3d263c1d 382 fprintf_filtered (f, _("%3d <incomplete opcode %s>\n"),
c906108c
SS
383 i, aop_map[op].name);
384 break;
385 }
386
387 fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
a04b0428 388 if (aop_map[op].op_size > 0)
c906108c
SS
389 {
390 fputs_filtered (" ", f);
c5aa993b 391
c906108c 392 print_longest (f, 'd', 0,
a04b0428 393 read_const (x, i + 1, aop_map[op].op_size));
c906108c
SS
394 }
395 fprintf_filtered (f, "\n");
a04b0428 396 i += 1 + aop_map[op].op_size;
c906108c
SS
397
398 is_float = (op == aop_float);
399 }
400}
401
35c9c7ba
SS
402/* Add register REG to the register mask for expression AX. */
403void
404ax_reg_mask (struct agent_expr *ax, int reg)
405{
175ff332 406 if (reg >= gdbarch_num_regs (ax->gdbarch))
35c9c7ba 407 {
175ff332
HZ
408 /* This is a pseudo-register. */
409 if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
410 error (_("'%s' is a pseudo-register; "
411 "GDB cannot yet trace its contents."),
412 user_reg_map_regnum_to_name (ax->gdbarch, reg));
413 if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
414 error (_("Trace '%s' failed."),
415 user_reg_map_regnum_to_name (ax->gdbarch, reg));
416 }
417 else
418 {
419 int byte = reg / 8;
420
421 /* Grow the bit mask if necessary. */
422 if (byte >= ax->reg_mask_len)
423 {
424 /* It's not appropriate to double here. This isn't a
425 string buffer. */
426 int new_len = byte + 1;
427 unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
428 new_len
429 * sizeof (ax->reg_mask[0]));
430 memset (new_reg_mask + ax->reg_mask_len, 0,
431 (new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
432 ax->reg_mask_len = new_len;
433 ax->reg_mask = new_reg_mask;
434 }
435
436 ax->reg_mask[byte] |= 1 << (reg % 8);
35c9c7ba 437 }
35c9c7ba
SS
438}
439
440/* Given an agent expression AX, fill in requirements and other descriptive
441 bits. */
c906108c 442void
35c9c7ba 443ax_reqs (struct agent_expr *ax)
c906108c
SS
444{
445 int i;
446 int height;
447
3d269a59
JB
448 /* Jump target table. targets[i] is non-zero iff we have found a
449 jump to offset i. */
c906108c
SS
450 char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
451
3d269a59
JB
452 /* Instruction boundary table. boundary[i] is non-zero iff our scan
453 has reached an instruction starting at offset i. */
c906108c
SS
454 char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
455
3d269a59 456 /* Stack height record. If either targets[i] or boundary[i] is
c906108c
SS
457 non-zero, heights[i] is the height the stack should have before
458 executing the bytecode at that point. */
459 int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
460
461 /* Pointer to a description of the present op. */
462 struct aop_map *op;
463
c906108c
SS
464 memset (targets, 0, ax->len * sizeof (targets[0]));
465 memset (boundary, 0, ax->len * sizeof (boundary[0]));
466
35c9c7ba
SS
467 ax->max_height = ax->min_height = height = 0;
468 ax->flaw = agent_flaw_none;
469 ax->max_data_size = 0;
c906108c 470
a04b0428 471 for (i = 0; i < ax->len; i += 1 + op->op_size)
c906108c
SS
472 {
473 if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
474 {
35c9c7ba 475 ax->flaw = agent_flaw_bad_instruction;
c906108c
SS
476 return;
477 }
478
479 op = &aop_map[ax->buf[i]];
480
c5aa993b 481 if (!op->name)
c906108c 482 {
35c9c7ba 483 ax->flaw = agent_flaw_bad_instruction;
c906108c
SS
484 return;
485 }
c5aa993b 486
a04b0428 487 if (i + 1 + op->op_size > ax->len)
c906108c 488 {
35c9c7ba 489 ax->flaw = agent_flaw_incomplete_instruction;
c906108c
SS
490 return;
491 }
492
3d269a59
JB
493 /* If this instruction is a forward jump target, does the
494 current stack height match the stack height at the jump
495 source? */
c906108c
SS
496 if (targets[i] && (heights[i] != height))
497 {
35c9c7ba 498 ax->flaw = agent_flaw_height_mismatch;
c906108c
SS
499 return;
500 }
501
502 boundary[i] = 1;
503 heights[i] = height;
504
a04b0428 505 height -= op->consumed;
35c9c7ba
SS
506 if (height < ax->min_height)
507 ax->min_height = height;
c906108c 508 height += op->produced;
35c9c7ba
SS
509 if (height > ax->max_height)
510 ax->max_height = height;
c906108c 511
35c9c7ba
SS
512 if (op->data_size > ax->max_data_size)
513 ax->max_data_size = op->data_size;
c906108c
SS
514
515 /* For jump instructions, check that the target is a valid
c5aa993b
JM
516 offset. If it is, record the fact that that location is a
517 jump target, and record the height we expect there. */
c906108c
SS
518 if (aop_goto == op - aop_map
519 || aop_if_goto == op - aop_map)
520 {
521 int target = read_const (ax, i + 1, 2);
522 if (target < 0 || target >= ax->len)
523 {
35c9c7ba 524 ax->flaw = agent_flaw_bad_jump;
c906108c
SS
525 return;
526 }
3d269a59
JB
527
528 /* Do we have any information about what the stack height
529 should be at the target? */
530 if (targets[target] || boundary[target])
c906108c 531 {
3d269a59 532 if (heights[target] != height)
c906108c 533 {
35c9c7ba 534 ax->flaw = agent_flaw_height_mismatch;
c906108c
SS
535 return;
536 }
537 }
3d269a59
JB
538
539 /* Record the target, along with the stack height we expect. */
540 targets[target] = 1;
541 heights[target] = height;
c906108c 542 }
c5aa993b 543
c906108c
SS
544 /* For unconditional jumps with a successor, check that the
545 successor is a target, and pick up its stack height. */
546 if (aop_goto == op - aop_map
547 && i + 3 < ax->len)
548 {
c5aa993b 549 if (!targets[i + 3])
c906108c 550 {
35c9c7ba 551 ax->flaw = agent_flaw_hole;
c906108c
SS
552 return;
553 }
554
555 height = heights[i + 3];
556 }
557
558 /* For reg instructions, record the register in the bit mask. */
559 if (aop_reg == op - aop_map)
560 {
561 int reg = read_const (ax, i + 1, 2);
c906108c 562
35c9c7ba 563 ax_reg_mask (ax, reg);
c906108c
SS
564 }
565 }
566
567 /* Check that all the targets are on boundaries. */
568 for (i = 0; i < ax->len; i++)
569 if (targets[i] && !boundary[i])
570 {
35c9c7ba 571 ax->flaw = agent_flaw_bad_jump;
c906108c
SS
572 return;
573 }
574
35c9c7ba 575 ax->final_height = height;
c906108c 576}
This page took 0.713376 seconds and 4 git commands to generate.