56 #include <include/hpctoolkit-config.h> 63 #include <include/hpctoolkit-config.h> 64 #include <xed-interface.h> 65 #if defined(ENABLE_XOP) && defined (HOST_CPU_x86_64) 73 #if defined (HOST_CPU_x86_64) 74 { XED_MACHINE_MODE_LONG_64,
75 XED_ADDRESS_WIDTH_64b };
77 { XED_MACHINE_MODE_LONG_COMPAT_32,
78 XED_ADDRESS_WIDTH_32b };
84 xed_decoded_inst_t
xedd;
85 xed_decoded_inst_t *xptr = &
xedd;
87 xed_decoded_inst_zero_set_mode(xptr, &dbg_xed_machine_state);
89 xed_error_enum_t xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
90 if (xed_error != XED_ERROR_NONE) {
91 fprintf(stderr,
"!! XED decode failure of insruction @ %p", ins);
92 return XED_ICLASS_INVALID;
94 return xed_decoded_inst_get_iclass(xptr);
108 #include <include/hpctoolkit-config.h> 116 static void process_call(
char *ins,
long offset, xed_decoded_inst_t *xptr,
117 void *start,
void *end);
127 static void process_branch(
char *ins,
long offset, xed_decoded_inst_t *xptr,
char* vstart,
char* vend);
133 static void addsub(
char *ins, xed_decoded_inst_t *xptr, xed_iclass_enum_t
iclass,
136 static void process_move(
char *ins, xed_decoded_inst_t *xptr,
long ins_offset);
138 static void process_push(
char *ins, xed_decoded_inst_t *xptr,
long ins_offset);
140 static void process_pop(
char *ins, xed_decoded_inst_t *xptr,
long ins_offset);
147 xed_decoded_inst_t *xptr);
150 xed_decoded_inst_t *xptr);
153 xed_decoded_inst_t *xptrin);
157 #define RELOCATE(u, offset) (((char *) (u)) - (offset)) 165 #if defined (HOST_CPU_x86_64) 166 { XED_MACHINE_MODE_LONG_64,
167 XED_ADDRESS_WIDTH_64b };
169 { XED_MACHINE_MODE_LONG_COMPAT_32,
170 XED_ADDRESS_WIDTH_32b };
202 static size_t rel_offset = 0;
204 # define SAVE_REL_OFFSET(offset) rel_offset = offset 205 # define KILL_REL_OFFSET() rel_offset = 0 208 # define SAVE_REL_OFFSET(offset) 209 # define KILL_REL_OFFSET() 211 #endif // DBG_INST_STRM 235 xed_decoded_inst_t
xedd;
236 xed_decoded_inst_t *xptr = &
xedd;
237 xed_error_enum_t xed_error;
240 char *ins = (
char *) vstart;
241 char *end = (
char *) vend;
242 vector<void *> fstarts;
245 void **fstart = &fstarts[0];
246 char *guidepost =
RELOCATE(*fstart, offset);
251 xed_iclass_enum_t prev_xiclass = XED_ICLASS_INVALID;
259 char *vins = ins + offset;
262 if (ins >= guidepost) {
263 if (ins > guidepost) {
268 #ifdef DEBUG_GUIDEPOST 269 printf(
"resetting ins to guidepost %p from %p\n",
270 guidepost + offset, ins + offset);
282 fstart++; guidepost =
RELOCATE(*fstart, offset);
285 xed_decoded_inst_zero_keep_mode(xptr);
286 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
288 if (xed_error != XED_ERROR_NONE) {
289 #if defined(ENABLE_XOP) && defined (HOST_CPU_x86_64) 293 if (decode_res.
weak) {
296 ins += decode_res.
len;
299 #endif // ENABLE_XOP && HOST_CPU_x86_64 306 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
310 addsub(ins, xptr, xiclass, offset);
312 case XED_ICLASS_CALL_FAR:
313 case XED_ICLASS_CALL_NEAR:
319 case XED_ICLASS_JMP_FAR:
320 if (xed_decoded_inst_noperands(xptr) == 2) {
321 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
322 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
323 const xed_operand_t *op1 = xed_inst_operand(xi, 1);
326 if ((xed_operand_name(op0) == XED_OPERAND_MEM0) &&
327 (xed_operand_name(op1) == XED_OPERAND_REG0) &&
328 x86_isReg_IP(xed_decoded_inst_get_base_reg(xptr, 1))) {
333 if ((xed_operand_name(op0) == XED_OPERAND_REG0) &&
334 (xed_operand_name(op1) == XED_OPERAND_REG1) &&
335 x86_isReg_IP(xed_decoded_inst_get_base_reg(xptr, 1))) {
348 case XED_ICLASS_RET_FAR:
349 case XED_ICLASS_RET_NEAR:
360 case XED_ICLASS_JNBE:
362 case XED_ICLASS_JNLE:
369 case XED_ICLASS_JRCXZ:
377 case XED_ICLASS_LOOP:
378 case XED_ICLASS_LOOPE:
379 case XED_ICLASS_LOOPNE:
385 case XED_ICLASS_PUSH:
386 case XED_ICLASS_PUSHFQ:
387 case XED_ICLASS_PUSHFD:
388 case XED_ICLASS_PUSHF:
393 case XED_ICLASS_POPF:
394 case XED_ICLASS_POPFD:
395 case XED_ICLASS_POPFQ:
399 case XED_ICLASS_ENTER:
407 case XED_ICLASS_LEAVE:
416 prev_xiclass = xiclass;
419 ins += xed_decoded_inst_get_length(xptr);
432 return (c == 0x66) || (c == 0x90);
439 xed_decoded_inst_t xedd_tmp;
440 xed_decoded_inst_t *xptr = &xedd_tmp;
441 xed_error_enum_t xed_error;
446 xed_decoded_inst_zero_keep_mode(xptr);
447 xed_error = xed_decode(xptr, (uint8_t*) *ins, 15);
449 if (xed_error != XED_ERROR_NONE)
return false;
451 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
457 case XED_ICLASS_NOP:
case XED_ICLASS_NOP2:
case XED_ICLASS_NOP3:
458 case XED_ICLASS_NOP4:
case XED_ICLASS_NOP5:
case XED_ICLASS_NOP6:
459 case XED_ICLASS_NOP7:
case XED_ICLASS_NOP8:
case XED_ICLASS_NOP9:
461 *ins = *ins + xed_decoded_inst_get_length(xptr);
481 ins += xed_decoded_inst_get_length(xptr);
485 unsigned char *new_func_addr = (
unsigned char *) ins;
518 xed_operand_values_t *vals)
520 int offset = xed_operand_values_get_branch_displacement_int32(vals);
521 char* insn_end = ins + xed_decoded_inst_get_length(xptr);
522 void* target = (
void*)(insn_end + offset);
524 #if defined(DBG_BR_TARG_2) && defined(DBG_INST_STRM) 525 int bytes = xed_operand_values_get_branch_displacement_length(vals);
528 fprintf(stderr,
"Reached case 2 @ location: %p, offset32 = %x\n", ins, offset);
529 fprintf(stderr,
"byte seq @ %p = \n ", ins);
530 for (
struct {
unsigned i;
unsigned char* p;} l = {0, (
unsigned char*)(ins - rel_offset)};
531 l.i < xed_decoded_inst_get_length(xptr);
533 fprintf(stderr,
"%x ", *l.p);
535 fprintf(stderr,
"\n");
537 #endif // DBG_BR_TARG_2 && DBG_INST_STRM 549 xed_decoded_inst_t xedd_tmp;
550 xed_decoded_inst_t *xptr = &xedd_tmp;
551 xed_error_enum_t xed_error;
555 xed_decoded_inst_zero_keep_mode(xptr);
557 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
559 if (xed_error != XED_ERROR_NONE)
return false;
561 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
564 case XED_ICLASS_PUSH:
565 case XED_ICLASS_PUSHFQ:
566 case XED_ICLASS_PUSHFD:
567 case XED_ICLASS_PUSHF:
572 const xed_inst_t* xi = xed_decoded_inst_inst(xptr);
573 const xed_operand_t* op0 = xed_inst_operand(xi, 0);
574 xed_operand_enum_t op0_name = xed_operand_name(op0);
576 if (op0_name == XED_OPERAND_REG0) {
577 xed_reg_enum_t regname = xed_decoded_inst_get_reg(xptr, op0_name);
578 return x86_isReg_BP(regname);
602 for (
size_t n = 0;
n < window;
n++) {
603 xed_decoded_inst_t xedd_tmp;
604 xed_decoded_inst_t *xptr = &xedd_tmp;
605 xed_error_enum_t xed_error;
608 xed_decoded_inst_zero_keep_mode(xptr);
610 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
612 if (xed_error != XED_ERROR_NONE)
return false;
614 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
616 if (xiclass == XED_ICLASS_MOV) {
617 const xed_inst_t* xi = xed_decoded_inst_inst(xptr);
618 const xed_operand_t* op0 = xed_inst_operand(xi, 0);
619 xed_operand_enum_t op0_name = xed_operand_name(op0);
620 const xed_operand_t* op1 = xed_inst_operand(xi,1);
621 xed_operand_enum_t op1_name = xed_operand_name(op1);
623 if ((op0_name == XED_OPERAND_MEM0) && (op1_name == XED_OPERAND_REG0)) {
625 xed_reg_enum_t basereg = xed_decoded_inst_get_base_reg(xptr, 0);
626 if (x86_isReg_SP(basereg)) {
627 xed_reg_enum_t reg1 = xed_decoded_inst_get_reg(xptr, op1_name);
628 if (x86_isReg_BP(reg1))
return true;
632 ins += xed_decoded_inst_get_length(xptr);
652 xed_decoded_inst_t xedd_tmp;
653 xed_decoded_inst_t *xptr = &xedd_tmp;
654 xed_error_enum_t xed_error;
658 xed_decoded_inst_zero_keep_mode(xptr);
660 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
662 if (xed_error != XED_ERROR_NONE)
return false;
664 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
666 if (xiclass != XED_ICLASS_SUB)
return false;
670 const xed_inst_t* xi = xed_decoded_inst_inst(xptr);
671 const xed_operand_t* op0 = xed_inst_operand(xi, 0);
672 xed_operand_enum_t op0_name = xed_operand_name(op0);
674 if (op0_name != XED_OPERAND_REG0)
return false;
676 xed_reg_enum_t regname = xed_decoded_inst_get_reg(xptr, op0_name);
677 const xed_operand_t* op1 = xed_inst_operand(xi,1);
678 *next = ins + xed_decoded_inst_get_length(xptr);
680 return (x86_isReg_SP(regname) && (xed_operand_name(op1) == XED_OPERAND_IMM0));
721 void *start,
void *end)
723 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
724 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
725 xed_operand_enum_t op0_name = xed_operand_name(op0);
726 xed_operand_type_enum_t op0_type = xed_operand_type(op0);
728 if (op0_name == XED_OPERAND_RELBR &&
729 op0_type == XED_OPERAND_TYPE_IMM_CONST) {
730 xed_operand_values_t *vals = xed_decoded_inst_operands(xptr);
732 if (xed_operand_values_has_branch_displacement(vals)) {
733 int call_inst_len = xed_decoded_inst_get_length(xptr);
734 void *next_inst_vaddr = ((
char *)ins) + offset + call_inst_len;
776 char *relocated_ins = ins + offset;
777 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
778 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
779 xed_operand_enum_t op0_name = xed_operand_name(op0);
780 xed_operand_type_enum_t op0_type = xed_operand_type(op0);
782 if (op0_name == XED_OPERAND_RELBR &&
783 op0_type == XED_OPERAND_TYPE_IMM_CONST) {
784 xed_operand_values_t *vals = xed_decoded_inst_operands(xptr);
786 if (xed_operand_values_has_branch_displacement(vals)) {
795 if (target < relocated_ins) {
797 int branch_inst_len = xed_decoded_inst_get_length(xptr);
798 end = relocated_ins + branch_inst_len;
812 xed_decoded_inst_t xedd_tmp;
813 xed_decoded_inst_t *xptr = &xedd_tmp;
816 char *ins = (
char *) vstart;
817 char *end = (
char *) vend;
820 xed_error_enum_t xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
822 if (xed_error != XED_ERROR_NONE) {
827 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
830 case XED_ICLASS_JMP:
case XED_ICLASS_JMP_FAR:
833 case XED_ICLASS_RET_FAR:
case XED_ICLASS_RET_NEAR:
836 case XED_ICLASS_JB:
case XED_ICLASS_JBE:
837 case XED_ICLASS_JL:
case XED_ICLASS_JLE:
838 case XED_ICLASS_JNB:
case XED_ICLASS_JNBE:
839 case XED_ICLASS_JNL:
case XED_ICLASS_JNLE:
840 case XED_ICLASS_JNO:
case XED_ICLASS_JNP:
841 case XED_ICLASS_JNS:
case XED_ICLASS_JNZ:
842 case XED_ICLASS_JO:
case XED_ICLASS_JP:
843 case XED_ICLASS_JRCXZ:
case XED_ICLASS_JS:
850 ins += xed_decoded_inst_get_length(xptr);
859 char *relocated_ins = ins + offset;
860 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
861 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
862 xed_operand_enum_t op0_name = xed_operand_name(op0);
863 xed_operand_type_enum_t op0_type = xed_operand_type(op0);
865 if (op0_name == XED_OPERAND_RELBR &&
866 op0_type == XED_OPERAND_TYPE_IMM_CONST) {
867 xed_operand_values_t *vals = xed_decoded_inst_operands(xptr);
869 if (xed_operand_values_has_branch_displacement(vals)) {
877 if (target < relocated_ins) {
885 char *target_addr_in_memory = target - offset;
887 xed_decoded_inst_t xtmp;
888 xed_decoded_inst_t *xptr = &xtmp;
891 xed_error_enum_t xed_error =
892 xed_decode(xptr, (uint8_t*) target_addr_in_memory, 15);
893 if (xed_error != XED_ERROR_NONE)
return false;
895 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
896 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
899 case XED_ICLASS_PUSH:
900 case XED_ICLASS_PUSHFQ:
901 case XED_ICLASS_PUSHFD:
902 case XED_ICLASS_PUSHF:
904 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
905 xed_operand_enum_t op0_name = xed_operand_name(op0);
907 if (op0_name == XED_OPERAND_REG0) {
908 xed_reg_enum_t regname =
909 xed_decoded_inst_get_reg(xptr, op0_name);
910 if (x86_isReg_BP(regname)) {
920 const xed_operand_t* op0 = xed_inst_operand(xi,0);
921 const xed_operand_t* op1 = xed_inst_operand(xi,1);
922 xed_operand_enum_t op0_name = xed_operand_name(op0);
924 if ((op0_name == XED_OPERAND_REG0)
925 && x86_isReg_SP(xed_decoded_inst_get_reg(xptr, op0_name))) {
927 if (xed_operand_name(op1) == XED_OPERAND_IMM0) {
931 int sign = (xiclass == XED_ICLASS_ADD) ? 1 : -1;
933 xed_decoded_inst_get_signed_immediate(xptr);
958 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
959 const xed_operand_t *op1 = xed_inst_operand(xi, 1);
960 xed_operand_enum_t op1_name = xed_operand_name(op1);
961 if (op1_name == XED_OPERAND_AGEN) {
962 int64_t offset = xed_decoded_inst_get_memory_displacement(xptr, 0);
963 if (offset == 0)
return true;
974 xed_decoded_inst_t xedd_tmp;
975 xed_decoded_inst_t* xptr = &xedd_tmp;
976 xed_error_enum_t xed_error;
980 xed_decoded_inst_zero_keep_mode(xptr);
982 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
983 if (xed_error == XED_ERROR_NONE) {
984 offset = xed_decoded_inst_get_length(xptr);
992 xed_decoded_inst_t xedd_tmp;
993 xed_decoded_inst_t* xptr = &xedd_tmp;
994 xed_error_enum_t xed_error;
997 xed_decoded_inst_zero_keep_mode(xptr);
999 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
1000 if (xed_error != XED_ERROR_NONE)
return false;
1002 if (xed_decoded_inst_get_iclass(xptr) != XED_ICLASS_MOV)
1005 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1006 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1007 const xed_operand_t *op1 = xed_inst_operand(xi, 1);
1009 xed_operand_enum_t op0_name = xed_operand_name(op0);
1010 xed_operand_enum_t op1_name = xed_operand_name(op1);
1012 if ((op0_name == XED_OPERAND_REG0) && (op1_name == XED_OPERAND_REG1)) {
1016 xed_reg_enum_t reg0 = xed_decoded_inst_get_reg(xptr, op0_name);
1017 xed_reg_enum_t reg1 = xed_decoded_inst_get_reg(xptr, op1_name);
1018 return x86_isReg_BP(reg0) && x86_isReg_SP(reg1);
1034 xed_decoded_inst_t xedd_tmp;
1035 xed_decoded_inst_t* xptr = &xedd_tmp;
1036 xed_error_enum_t xed_error;
1039 xed_decoded_inst_zero_keep_mode(xptr);
1042 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
1043 if (xed_error != XED_ERROR_NONE) {
1047 if (xed_decoded_inst_get_iclass(xptr) == XED_ICLASS_MOV) {
1048 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1049 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1050 const xed_operand_t *op1 = xed_inst_operand(xi, 1);
1052 xed_operand_enum_t op0_name = xed_operand_name(op0);
1053 xed_operand_enum_t op1_name = xed_operand_name(op1);
1055 if ((op0_name == XED_OPERAND_REG0) && (op1_name == XED_OPERAND_REG1)) {
1059 xed_reg_enum_t reg0 = xed_decoded_inst_get_reg(xptr, op0_name);
1060 if (x86_isReg_BP(reg0))
1064 ins += xed_decoded_inst_get_length(xptr);
1087 xed_decoded_inst_t xedd_tmp;
1088 xed_decoded_inst_t *xptr = &xedd_tmp;
1089 xed_error_enum_t xed_error;
1091 ins = ins + xed_decoded_inst_get_length(xptrin);
1098 xed_decoded_inst_zero_keep_mode(xptr);
1099 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
1101 if (xed_error != XED_ERROR_NONE)
return false;
1103 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
1105 case XED_ICLASS_LEA:
1110 case XED_ICLASS_NOP:
case XED_ICLASS_NOP2:
case XED_ICLASS_NOP3:
1111 case XED_ICLASS_NOP4:
case XED_ICLASS_NOP5:
case XED_ICLASS_NOP6:
1112 case XED_ICLASS_NOP7:
case XED_ICLASS_NOP8:
case XED_ICLASS_NOP9:
1114 ins = ins + xed_decoded_inst_get_length(xptr);
1116 case XED_ICLASS_PUSH:
1117 case XED_ICLASS_PUSHFQ:
1118 case XED_ICLASS_PUSHFD:
1119 case XED_ICLASS_PUSHF:
1123 case XED_ICLASS_ADD:
1124 case XED_ICLASS_SUB:
1126 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1127 const xed_operand_t* op0 = xed_inst_operand(xi,0);
1128 const xed_operand_t* op1 = xed_inst_operand(xi,1);
1129 xed_operand_enum_t op0_name = xed_operand_name(op0);
1131 if ((op0_name == XED_OPERAND_REG0) &&
1132 (x86_isReg_SP(xed_decoded_inst_get_reg(xptr, op0_name)))) {
1134 if (xed_operand_name(op1) == XED_OPERAND_IMM0) {
1138 int sign = (xiclass == XED_ICLASS_ADD) ? 1 : -1;
1139 long immedv = sign * xed_decoded_inst_get_signed_immediate(xptr);
1160 process_branch(
char *ins,
long offset, xed_decoded_inst_t *xptr,
char* vstart,
char* vend)
1162 char *relocated_ins = ins + offset;
1163 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1164 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1165 xed_operand_enum_t op0_name = xed_operand_name(op0);
1166 xed_operand_type_enum_t op0_type = xed_operand_type(op0);
1168 if (op0_name == XED_OPERAND_RELBR &&
1169 op0_type == XED_OPERAND_TYPE_IMM_CONST) {
1170 xed_operand_values_t *vals = xed_decoded_inst_operands(xptr);
1172 if (xed_operand_values_has_branch_displacement(vals)) {
1183 if (! (((vstart + offset) <= target) && (target <= (vend + offset)))) {
1187 if (target < relocated_ins) {
1188 unsigned char *tloc = (
unsigned char *) target - offset;
1196 int branch_inst_len = xed_decoded_inst_get_length(xptr);
1197 end = relocated_ins + branch_inst_len;
1199 start = relocated_ins;
1204 end = ((
char *) target) + 1;
1214 xed_reg_enum_t basereg = xed_decoded_inst_get_base_reg(xptr, oindex);
1215 if (x86_isReg_BP(basereg)) {
1217 }
else if (x86_isReg_SP(basereg)) {
1219 xed_decoded_inst_get_memory_displacement(xptr, oindex);
1223 }
else if (x86_isReg_AX(basereg)) {
1236 int noperands = xed_decoded_inst_number_of_memory_operands(xptr);
1238 switch (noperands) {
1244 assert(0 &&
"unexpected number of memory operands");
1246 if (not_my_mem)
return true;
1254 static xed_operand_enum_t regops[] = { XED_OPERAND_REG0, XED_OPERAND_REG1 };
1255 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1256 int noperands = xed_decoded_inst_noperands(xptr);
1258 if (noperands > 2) noperands = 2;
1259 for (
int opid = 0; opid < noperands; opid++) {
1260 const xed_operand_t *op = xed_inst_operand(xi, opid);
1261 xed_operand_enum_t op_name = xed_operand_name(op);
1262 if (op_name == regops[opid]) {
1263 xed_reg_enum_t regname = xed_decoded_inst_get_reg(xptr, op_name);
1264 if ((regname == XED_REG_RAX) || (regname == XED_REG_EAX) || (regname == XED_REG_AX)) {
1266 switch(xed_operand_rw(op)) {
1267 case XED_OPERAND_ACTION_R:
1269 case XED_OPERAND_ACTION_RCW:
1270 case XED_OPERAND_ACTION_CR:
1271 case XED_OPERAND_ACTION_CRW:
1286 unsigned char result = 0;
1287 unsigned char *end = ins +
n;
1288 while (ins < end) result |= *ins++;
1289 if (result == 0)
return true;
1296 xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
1298 case XED_ICLASS_INT:
1299 case XED_ICLASS_INT1:
1300 case XED_ICLASS_INT3:
1311 xed_decoded_inst_t xdi;
1312 xed_decoded_inst_t *xptr = &xdi;
1315 xed_error_enum_t xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
1317 if (xed_error != XED_ERROR_NONE)
return true;
1319 if (
is_null(ins, xed_decoded_inst_get_length(xptr)))
return true;
1330 xed_decoded_inst_t
xedd;
1331 xed_decoded_inst_t *xptr = &
xedd;
1332 xed_error_enum_t xed_error;
1333 char inst_buf[1024];
1336 xed_error = xed_decode(xptr, (uint8_t*) ins, 15);
1338 if (xed_error == XED_ERROR_NONE) {
1339 xed_decoded_inst_dump_xed_format(xptr, inst_buf,
sizeof(inst_buf), (uint64_t) ins);
1340 printf(
"(%p, %d bytes, %s) %s \n" , ins, xed_decoded_inst_get_length(xptr),
1341 xed_iclass_enum_t2str(xed_decoded_inst_get_iclass(xptr)), inst_buf);
1343 printf(
"x86_dump_ins: xed decode addr=%p, error = %d\n", ins, xed_error);
1351 addsub(
char *ins, xed_decoded_inst_t *xptr, xed_iclass_enum_t
iclass,
long ins_offset)
1353 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1354 const xed_operand_t* op0 = xed_inst_operand(xi,0);
1355 const xed_operand_t* op1 = xed_inst_operand(xi,1);
1356 xed_operand_enum_t op0_name = xed_operand_name(op0);
1357 static long prologue_offset = 0;
1359 if ((op0_name == XED_OPERAND_REG0) &&
1360 x86_isReg_SP(xed_decoded_inst_get_reg(xptr, op0_name))) {
1362 if (xed_operand_name(op1) == XED_OPERAND_IMM0) {
1366 int sign = (iclass == XED_ICLASS_ADD) ? 1 : -1;
1367 long immedv = sign * xed_decoded_inst_get_signed_immediate(xptr);
1370 prologue_offset = -immedv;
1372 fprintf(stderr,
"prologue %ld\n", immedv);
1376 fprintf(stderr,
"epilogue %ld\n", immedv);
1378 if (immedv == prologue_offset) {
1385 ins + ins_offset + 1);
1387 char *end = ins + 1;
1388 fprintf(stderr,
"range [%p, %p] offset %ld\n",
1402 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1403 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1404 const xed_operand_t *op1 = xed_inst_operand(xi, 1);
1406 xed_operand_enum_t op0_name = xed_operand_name(op0);
1407 xed_operand_enum_t op1_name = xed_operand_name(op1);
1409 if ((op0_name == XED_OPERAND_REG0) && (op1_name == XED_OPERAND_REG1)) {
1413 xed_reg_enum_t reg0 = xed_decoded_inst_get_reg(xptr, op0_name);
1414 xed_reg_enum_t reg1 = xed_decoded_inst_get_reg(xptr, op1_name);
1415 if ((x86_isReg_BP(reg0)) && (x86_isReg_SP(reg1))) {
1428 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1429 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1430 xed_operand_enum_t op0_name = xed_operand_name(op0);
1432 if (op0_name == XED_OPERAND_REG0) {
1433 xed_reg_enum_t regname = xed_decoded_inst_get_reg(xptr, op0_name);
1434 if (x86_isReg_BP(regname)) {
1439 if (fn_start == WEAK_FN){
1441 fn_start == MODERATE_FN;
1455 const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
1456 const xed_operand_t *op0 = xed_inst_operand(xi, 0);
1457 xed_operand_enum_t op0_name = xed_operand_name(op0);
1459 if (op0_name == XED_OPERAND_REG0) {
1460 xed_reg_enum_t regname = xed_decoded_inst_get_reg(xptr, op0_name);
1461 if (x86_isReg_BP(regname)) {
1469 ins + ins_offset + 1);
1479 ins + ins_offset + 1);
static const size_t WINDOW
static bool is_sub_immed_sp(char *ins, char **next)
static bool is_push_bp(char *ins)
static bool skip_padding(unsigned char **ins)
void adv_amd_decode(amd_decode_t *stat, void *ins)
static int mem_below_rsp_or_rbp(xed_decoded_inst_t *xptr, int oindex)
static bool lea_has_zero_offset(xed_decoded_inst_t *xptr)
static void * get_branch_target(char *ins, xed_decoded_inst_t *xptr, xed_operand_values_t *vals)
static void process_push(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
bool query_function_entry(void *addr)
static bool contains_bp_save(char *ins)
static void addsub(char *ins, xed_decoded_inst_t *xptr, xed_iclass_enum_t iclass, long ins_offset)
static bool is_sub_immed_prologue(char *ins)
static bool invalid_routine_start(unsigned char *ins)
static void process_call(char *ins, long offset, xed_decoded_inst_t *xptr, void *start, void *end)
void add_stripped_function_entry(void *addr, int call_count)
static int is_padding(int c)
xed_iclass_enum_t xed_iclass(char *ins)
static void process_enter(char *ins, long ins_offset)
static void process_leave(char *ins, long ins_offset)
void x86_dump_ins(void *ins)
bool consider_possible_fn_address(void *addr)
static bool bkwd_jump_into_protected_range(char *ins, long offset, xed_decoded_inst_t *xptr)
static bool ins_seq_is_std_frame(char *ins)
static void process_branch(char *ins, long offset, xed_decoded_inst_t *xptr, char *vstart, char *vend)
#define RELOCATE(u, offset)
static xed_state_t xed_machine_state
void add_function_entry(void *addr, const string *comment, bool isvisible, int call_count)
static bool ins_seq_has_reg_move_to_bp(char *ins)
static void process_pop(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
static xed_reg_enum_t push_other_reg
static const size_t FRAMELESS_PROC_WINDOW
static char * xed_next(char *ins)
static bool is_mov_sp_2_bp(char *ins)
static bool inst_accesses_callers_mem(xed_decoded_inst_t *xptr)
void process_range_init()
static bool is_2step_push_bp(char *ins)
static void process_move(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
static xed_decoded_inst_t xedd
void entries_in_range(void *start, void *end, vector< void *> &result)
int inside_protected_range(void *addr)
#define KILL_REL_OFFSET()
static bool is_breakpoint(xed_decoded_inst_t *xptr)
static bool is_push_bp_seq(char *ins)
static bool from_ax_reg(xed_decoded_inst_t *xptr)
static bool contains_bp_save_window(char *ins, size_t window)
static bool is_null(unsigned char *ins, int n)
static xed_state_t dbg_xed_machine_state
static bool ins_seq_is_common_frameless_proc(char *ins)
static bool nextins_looks_like_fn_start(char *ins, long offset, xed_decoded_inst_t *xptrin)
void process_range(const char *name, long offset, void *vstart, void *vend, DiscoverFnTy fn_discovery)
#define SAVE_REL_OFFSET(offset)
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
bool range_contains_control_flow(void *vstart, void *vend)
static void after_unconditional(char *ins, long offset, xed_decoded_inst_t *xptr)
void add_protected_range(void *start, void *end)
static bool validate_tail_call_from_jump(char *ins, long offset, xed_decoded_inst_t *xptr)
bool contains_function_entry(void *address)
static char * prologue_start