2 * Copyright (c) 1996 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * This license is for research uses. For such uses, there is no
12 * charge. We define "research use" to mean you may freely use it
13 * inside your organization for whatever purposes you see fit. But you
14 * may not re-distribute Paradyn or parts of Paradyn, in any form
15 * source or binary (including derivatives), electronic or otherwise,
16 * to any other organization or entity without our permission.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
24 * By your use of Paradyn, you understand and agree that we (or any
25 * other person or entity with proprietary rights in Paradyn) are
26 * under no obligation to provide either maintenance services,
27 * update services, notices of latent defects, or correction of
28 * defects for Paradyn.
30 * Even if advised of the possibility of such damages, under no
31 * circumstances shall we (or any other person or entity with
32 * proprietary rights in the software licensed hereunder) be liable
33 * to you or any third party for direct, indirect, or consequential
34 * damages of any character regardless of type of action, including,
35 * without limitation, loss of profits, loss of use, loss of good
36 * will, or computer failure or malfunction. You agree to indemnify
37 * us (and any other person or entity with proprietary rights in the
38 * software licensed hereunder) for any and all liability it may
39 * incur to third parties resulting from your use of Paradyn.
48 #include "BPatch_snippet.h"
49 #include "BPatch_type.h"
51 /* XXX Should be in a dyninst API include file (right now in perfStream.h) */
52 extern double cyclesPerSecond;
55 * BPatch_snippet::BPatch_snippet
57 * Copy constructor for BPatch_snippet.
59 BPatch_snippet::BPatch_snippet(const BPatch_snippet &src)
61 ast = assignAst(src.ast);
66 * BPatch_snippet::operator=
68 * Assignment operator for BPatch_snippet. Needed to ensure that the
69 * reference counts for the asts contained in the snippets is correct.
71 BPatch_snippet &BPatch_snippet::operator=(const BPatch_snippet &src)
77 // Since we're copying over this snippet, release the old AST
81 // We'll now contain another reference to the ast in the other snippet
82 ast = assignAst(src.ast);
89 * BPatch_snippet:getCost
91 * Returns the estimated cost of executing the snippet, in seconds.
93 float BPatch_snippet::getCost()
95 return (double)ast->cost() / cyclesPerSecond;
100 * BPatch_snippet::~BPatch_snippet
102 * Destructor for BPatch_snippet. Deallocates memory allocated by the
105 BPatch_snippet::~BPatch_snippet()
113 * BPatch_arithExpr::BPatch_arithExpr
115 * Construct a snippet representing a binary arithmetic operation.
117 * op The desired operation.
118 * lOperand The left operand for the operation.
119 * rOperand The right operand.
121 BPatch_arithExpr::BPatch_arithExpr(BPatch_binOp op,
122 const BPatch_snippet &lOperand, const BPatch_snippet &rOperand)
124 assert(BPatch::bpatch != NULL);
144 /* XXX Not yet implemented. */
148 /* XXX Not yet implemented. */
152 ast = new AstNode(lOperand.ast, rOperand.ast);
153 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
156 /* XXX handle error */
160 ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
161 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
166 * BPatch_boolExpr::BPatch_boolExpr
168 * Constructs a snippet representing a boolean expression.
170 * op The operator for the boolean expression.
171 * lOperand The left operand.
172 * rOperand The right operand.
174 BPatch_boolExpr::BPatch_boolExpr(BPatch_relOp op,
175 const BPatch_snippet &lOperand,
176 const BPatch_snippet &rOperand)
205 /* XXX Handle the error case here */
209 ast = new AstNode(astOp, lOperand.ast, rOperand.ast);
210 assert(BPatch::bpatch != NULL);
211 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
216 * BPatch_constExpr::BPatch_constExpr
218 * Constructs a snippet representing a constant integer value.
220 * value The desired value.
222 BPatch_constExpr::BPatch_constExpr(int value)
224 ast = new AstNode(AstNode::Constant, (void *)value);
226 assert(BPatch::bpatch != NULL);
227 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
229 BPatch_type *type = BPatch::bpatch->stdTypes->findType("int");
230 assert(type != NULL);
237 * BPatch_constExpr::BPatch_constExpr
239 * Constructs a snippet representing a constant string value.
241 * value The desired constant string.
243 BPatch_constExpr::BPatch_constExpr(const char *value)
245 ast = new AstNode(AstNode::ConstantString, (void *)value);
247 assert(BPatch::bpatch != NULL);
248 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
250 BPatch_type *type = BPatch::bpatch->stdTypes->findType("char *");
251 assert(type != NULL);
258 * BPatch_funcCallExpr::BPatch_funcCallExpr
260 * Constructs a snippet representing a function call.
262 * func Identifies the function to call.
263 * args A vector of the arguments to be passed to the function.
265 BPatch_funcCallExpr::BPatch_funcCallExpr(
266 const BPatch_function &func,
267 const BPatch_Vector<BPatch_snippet *> &args)
269 vector<AstNode *> ast_args;
272 for (i = 0; i < args.size(); i++)
273 ast_args += assignAst(args[i]->ast);
275 ast = new AstNode(func.func->prettyName(), ast_args);
277 for (i = 0; i < args.size(); i++)
278 removeAst(ast_args[i]);
280 assert(BPatch::bpatch != NULL);
281 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
286 * BPatch_ifExpr::BPatch_ifExpr
288 * Constructs a snippet representing a conditional expression.
290 * conditional The conditional.
291 * tClause A snippet to execute if the conditional is true.
293 BPatch_ifExpr::BPatch_ifExpr(const BPatch_boolExpr &conditional,
294 const BPatch_snippet &tClause)
296 ast = new AstNode(ifOp, conditional.ast, tClause.ast);
298 assert(BPatch::bpatch != NULL);
299 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
304 * BPatch_ifExpr::BPatch_ifExpr
306 * Constructs a snippet representing a conditional expression with an else
309 * conditional The conditional.
310 * tClause A snippet to execute if the conditional is true.
312 BPatch_ifExpr::BPatch_ifExpr(const BPatch_boolExpr &conditional,
313 const BPatch_snippet &tClause,
314 const BPatch_snippet &fClause)
316 ast = new AstNode(ifOp, conditional.ast, tClause.ast, fClause.ast);
318 assert(BPatch::bpatch != NULL);
319 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
324 * BPatch_nullExpr::BPatch_nullExpr
326 * Construct a null snippet that can be used as a placeholder.
328 BPatch_nullExpr::BPatch_nullExpr()
332 assert(BPatch::bpatch != NULL);
333 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
338 * BPatch_paramExpr::BPatch_paramExpr
340 * Construct a snippet representing a parameter of the function in which
341 * the snippet is inserted.
343 * n The position of the parameter (0 is the first parameter, 1 the second,
346 BPatch_paramExpr::BPatch_paramExpr(int n)
348 ast = new AstNode(AstNode::Param, (void *)n);
350 assert(BPatch::bpatch != NULL);
351 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
356 * BPatch_retExpr::BPatch_retExpr
358 * Construct a snippet representing a return value from the function in which
359 * the snippet is inserted.
362 BPatch_retExpr::BPatch_retExpr()
364 ast = new AstNode(AstNode::ReturnVal, (void *)0);
366 assert(BPatch::bpatch != NULL);
367 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
371 * BPatch_sequence::BPatch_sequence
373 * Construct a snippet representing a sequence of snippets.
375 * items The snippets that are to make up the sequence.
377 BPatch_sequence::BPatch_sequence(const BPatch_Vector<BPatch_snippet *> &items)
379 if (items.size() == 0) {
380 // XXX do something to indicate an error
384 assert(BPatch::bpatch != NULL);
386 ast = new AstNode(items[0]->ast);
387 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
389 for (int i = 1; i < items.size(); i++) {
390 AstNode *tempAst = new AstNode(ast, items[i]->ast);
391 tempAst->setTypeChecking(BPatch::bpatch->isTypeChecked());
399 * BPatch_variableExpr::BPatch_variableExpr
401 * Construct a snippet representing a variable of the given type at the given
404 * in_process The process that the variable resides in.
405 * in_address The address of the variable in the inferior's address space.
406 * type The type of the variable.
408 BPatch_variableExpr::BPatch_variableExpr(process *in_process,
410 const BPatch_type *type) :
411 proc(in_process), address(in_address)
413 ast = new AstNode(AstNode::DataAddr, address);
415 assert(BPatch::bpatch != NULL);
416 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
420 size = type->getSize();
425 * BPatch_variableExpr::BPatch_variableExpr
427 * Construct a snippet representing an untyped variable of a given size at the
430 * in_address The address of the variable in the inferior's address space.
432 BPatch_variableExpr::BPatch_variableExpr(process *in_process,
435 proc(in_process), address(in_address)
437 ast = new AstNode(AstNode::DataAddr, address);
439 assert(BPatch::bpatch != NULL);
440 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
442 ast->setType(BPatch::bpatch->type_Untyped);
449 * BPatch_variableExpr::readValue
451 * Read the value of a variable in a thread's address space.
453 * dst A pointer to a buffer in which to place the value of the
454 * variable. It is assumed to be the same size as the variable.
456 void BPatch_variableExpr::readValue(void *dst)
458 proc->readDataSpace(address, size, dst, true);
463 * BPatch_variableExpr::readValue
465 * Read the a given number of bytes starting at the base address of a variable
466 * in the a thread's address space.
468 * dst A pointer to a buffer in which to place the value of the
469 * variable. It is assumed to be the same size as the variable.
470 * len Number of bytes to read.
472 void BPatch_variableExpr::readValue(void *dst, int len)
474 proc->readDataSpace(address, len, dst, true);
479 * BPatch_variableExpr::writeValue
481 * Write a value into a variable in a thread's address space.
483 * dst A pointer to a buffer in which to place the value of the
484 * variable. It is assumed to be the same size as the variable.
486 void BPatch_variableExpr::writeValue(const void *src)
488 proc->writeDataSpace(address, size, src);
493 * BPatch_variableExpr::writeValue
495 * Write the a given number of bytes starting at the base address of a
496 * variable in the a thread's address space.
498 * dst A pointer to a buffer in which to place the value of the
499 * variable. It is assumed to be the same size as the variable.
501 void BPatch_variableExpr::writeValue(const void *src, int len)
503 proc->writeDataSpace(address, len, src);
508 * BPatch_breakPointExpr::BPatch_breakPointExpr
510 * Construct a snippet representing a breakpoint.
513 BPatch_breakPointExpr::BPatch_breakPointExpr()
515 vector<AstNode *> null_args;
517 ast = new AstNode("DYNINSTbreakPoint", null_args);
519 assert(BPatch::bpatch != NULL);
521 ast->setType(BPatch::bpatch->type_Untyped);
522 ast->setTypeChecking(BPatch::bpatch->isTypeChecked());
526 /**************************************************************************
528 *************************************************************************/
531 * BPatch_function::getName
533 * Copies the name of the function into a buffer, up to a given maximum
534 * length. Returns a pointer to the beginning of the buffer that was
537 * s The buffer into which the name will be copied.
538 * len The size of the buffer.
540 char *BPatch_function::getName(char *s, int len)
543 string name = func->prettyName();
544 strncpy(s, name.string_of(), len);
551 * BPatch_function::findPoint
553 * Returns a vector of the instrumentation points from a procedure that is
554 * identified by the parameters, or returns NULL upon failure.
556 * loc The points within the procedure to return. The following
557 * values are valid for this parameter:
558 * BPatch_entry The function's entry point.
559 * BPatch_exit The function's exit point(s).
560 * BPatch_subroutine The points at which the procedure calls
562 * BPatch_longJump The points at which the procedure make
564 * BPatch_allLocations All of the points described above.
566 BPatch_Vector<BPatch_point*> *BPatch_function::findPoint(
567 const BPatch_procedureLocation loc)
569 if (func == NULL) return NULL;
571 BPatch_Vector<BPatch_point*> *result = new BPatch_Vector<BPatch_point *>;
573 if (loc == BPatch_entry || loc == BPatch_allLocations) {
574 BPatch_point *new_point = new BPatch_point(proc,
575 (instPoint *)func->funcEntry(proc),
577 result->push_back(new_point);
579 if (loc == BPatch_exit || loc == BPatch_allLocations) {
580 const vector<instPoint *> &points = func->funcExits(proc);
581 for (unsigned i = 0; i < points.size(); i++) {
582 BPatch_point *new_point = new BPatch_point(proc, points[i],
584 result->push_back(new_point);
587 if (loc == BPatch_subroutine || loc == BPatch_allLocations) {
588 const vector<instPoint *> &points = func->funcCalls(proc);
589 for (unsigned i = 0; i < points.size(); i++) {
590 BPatch_point *new_point = new BPatch_point(proc, points[i],
592 result->push_back(new_point);
595 if (loc == BPatch_longJump /* || loc == BPatch_allLocations */) {
596 /* XXX Not yet implemented */