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 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 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 } 548