enum {
PV_VACANT = 0,
PV_POINTER,
+ PV_SIGNED_INT,
+ PV_UNSIGNED_INT,
+ PV_FP
} kind;
- uintptr_t value;
+ union {
+ uintptr_t ptr_value;
+ int64_t int_val;
+ uint64_t uint_val;
+ double fp_val;
+ };
};
struct event {
fprintf (stderr, " Param values follow:\n");
for (i = 0; i < tc->num_params; i++)
fprintf (stderr, " Param %s: 0x%p\n", tc->param_names[i],
- (void *)tuple->param_vals[i].value);
+ (void *)tuple->param_vals[i].ptr_value);
}
else
{
continue; /* Vacant values always match. */
case PV_POINTER:
if (tuple->param_vals[i].kind != PV_POINTER
- || event->param_vals[i].value != tuple->param_vals[i].value)
+ || event->param_vals[i].ptr_value != tuple->param_vals[i].ptr_value)
+ return 0; /* Mismatch. */
+ else
+ ; /* This param matches; keep looking. */
+ break;
+ case PV_SIGNED_INT:
+ if (tuple->param_vals[i].kind != PV_SIGNED_INT
+ || event->param_vals[i].int_val != tuple->param_vals[i].int_val)
+ return 0; /* Mismatch. */
+ else
+ ; /* This param matches; keep looking. */
+ break;
+ case PV_UNSIGNED_INT:
+ if (tuple->param_vals[i].kind != PV_UNSIGNED_INT
+ || event->param_vals[i].uint_val != tuple->param_vals[i].uint_val)
+ return 0; /* Mismatch. */
+ else
+ ; /* This param matches; keep looking. */
+ break;
+ case PV_FP:
+ if (tuple->param_vals[i].kind != PV_FP
+ || event->param_vals[i].fp_val != tuple->param_vals[i].fp_val)
return 0; /* Mismatch. */
else
; /* This param matches; keep looking. */
}
current_event->param_vals[param_index].kind = PV_POINTER;
- current_event->param_vals[param_index].value = (uintptr_t)param_val;
+ current_event->param_vals[param_index].ptr_value = (uintptr_t)param_val;
}
+ADVICE_FUNC void
+_tc_capture_signed_int_param (int tc_index, int symbol_index, int param_index,
+ int64_t param_val)
+{
+ if (current_event == NULL)
+ {
+ return;
+ }
+ else if (current_event->tc_index != tc_index)
+ {
+ fatal_tracecut_error ("Misplaced param value.");
+ return;
+ }
+ else if (param_index < 0
+ || param_index >= current_event->tracecut->num_params)
+ {
+ fatal_tracecut_error ("Out-of-bounds param value.");
+ }
+
+ current_event->param_vals[param_index].kind = PV_SIGNED_INT;
+ current_event->param_vals[param_index].int_val = param_val;
+}
+
+ADVICE_FUNC void
+_tc_capture_unsigned_int_param (int tc_index, int symbol_index, int param_index,
+ uint64_t param_val)
+{
+ if (current_event == NULL)
+ {
+ return;
+ }
+ else if (current_event->tc_index != tc_index)
+ {
+ fatal_tracecut_error ("Misplaced param value.");
+ return;
+ }
+ else if (param_index < 0
+ || param_index >= current_event->tracecut->num_params)
+ {
+ fatal_tracecut_error ("Out-of-bounds param value.");
+ }
+
+ current_event->param_vals[param_index].kind = PV_UNSIGNED_INT;
+ current_event->param_vals[param_index].uint_val = param_val;
+}
+
+ADVICE_FUNC void
+_tc_capture_float_param (int tc_index, int symbol_index, int param_index,
+ double param_val)
+{
+ if (current_event == NULL)
+ {
+ return;
+ }
+ else if (current_event->tc_index != tc_index)
+ {
+ fatal_tracecut_error ("Misplaced param value.");
+ return;
+ }
+ else if (param_index < 0
+ || param_index >= current_event->tracecut->num_params)
+ {
+ fatal_tracecut_error ("Out-of-bounds param value.");
+ }
+
+ current_event->param_vals[param_index].kind = PV_FP;
+ current_event->param_vals[param_index].fp_val = param_val;
+}
+
+
ADVICE_FUNC void
_tc_event_transition (int tc_index, int symbol_index)
{
return NULL;
}
+enum tc_error
+tc_check_param_type(const struct aop_type *type)
+{
+ if(aop_is_pointer_type (type) ||
+ aop_is_all_signed_subtype (type) ||
+ aop_is_all_unsigned_subtype (type) ||
+ aop_is_all_fp_subtype (type)) {
+ return TC_SUCCESS;
+ }
+
+ return TC_INVAL;
+}
+
/**
* Add a new tracecut parameter. Each tracecut tracks several
* objects, so a tracecut event must be <i>parameterized</i> to
const struct aop_type *type)
{
struct tc_param *param = NULL;
+ enum tc_error tc_err = TC_SUCCESS;
if (tc_in_compilation)
return TC_BAD_CONTEXT;
- if (!aop_is_pointer_type (type))
- return TC_INVAL;
+ tc_err = tc_check_param_type(type);
+ if(tc_err != TC_SUCCESS)
+ return tc_err;
if (lookup_param (tc, name) != NULL)
return TC_DUPLICATE;;
AOP_INT_CST (binding->param->index),
AOP_DYNVAL (param_val), AOP_TERM_ARG);
}
+ else if (aop_is_all_signed_subtype (param_type))
+ {
+ aop_cast_to_all_signed (param_val);
+ aop_insert_advice (jp, "_tc_capture_signed_int_param", symbol->location,
+ AOP_INT_CST (tc_index),
+ AOP_INT_CST (symbol->index),
+ AOP_INT_CST (binding->param->index),
+ AOP_DYNVAL (param_val), AOP_TERM_ARG);
+ }
+ else if (aop_is_all_unsigned_subtype (param_type))
+ {
+ aop_cast_to_all_unsigned (param_val);
+ aop_insert_advice (jp, "_tc_capture_unsigned_int_param", symbol->location,
+ AOP_INT_CST (tc_index),
+ AOP_INT_CST (symbol->index),
+ AOP_INT_CST (binding->param->index),
+ AOP_DYNVAL (param_val), AOP_TERM_ARG);
+ }
+ else if (aop_is_all_fp_subtype (param_type))
+ {
+ aop_cast_to_all_fp (param_val);
+ aop_insert_advice (jp, "_tc_capture_float_param", symbol->location,
+ AOP_INT_CST (tc_index),
+ AOP_INT_CST (symbol->index),
+ AOP_INT_CST (binding->param->index),
+ AOP_DYNVAL (param_val), AOP_TERM_ARG);
+ }
else
{
/* TODO: Provide support for more kinds of data. */