HPCToolkit
x86-process-inst.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 #include <stdio.h>
48 #include <stdbool.h>
49 #include <assert.h>
50 
51 #include "x86-addsub.h"
52 #include "x86-and.h"
53 #include "x86-call.h"
54 #include "x86-decoder.h"
55 #include "x86-enter.h"
56 #include "x86-leave.h"
57 #include "x86-jump.h"
58 #include "x86-move.h"
59 #include "x86-push.h"
61 #include "x86-return.h"
62 #include "x86-cold-path.h"
63 #include "x86-interval-arg.h"
64 
65 #define UWRECIPE_DEBUG 1
66 
68 process_inst(xed_decoded_inst_t *xptr, interval_arg_t *iarg)
69 {
70  xed_iclass_enum_t xiclass = xed_decoded_inst_get_iclass(xptr);
71  const xed_inst_t *xi = xed_decoded_inst_inst(xptr);
72  unwind_interval *next;
73  int irdebug = 0;
74 
75  switch(xiclass) {
76 
77  case XED_ICLASS_JMP:
78  case XED_ICLASS_JMP_FAR:
79  next = process_unconditional_branch(xptr, irdebug, iarg);
80  if (hpcrun_is_cold_code(xptr, iarg)) {
81  TMSG(COLD_CODE," --cold code routine detected!");
82  TMSG(COLD_CODE,"fetching interval from location %p",iarg->return_addr);
83 
84  unwindr_info_t unwr_info;
85  bool found = uw_recipe_map_lookup(iarg->return_addr, NATIVE_UNWINDER, &unwr_info);
86 #if UWRECIPE_DEBUG
87  assert(found);
88 #endif
89  bitree_uwi_t *ui = unwr_info.btuwi;
90 
91  TMSG(COLD_CODE,"got unwind interval from hpcrun_addr_to_interval");
92  if (ENABLED(COLD_CODE)) {
93  dump_ui_stderr(ui);
94  }
95  // Fixup current intervals w.r.t. the warm code interval
96  hpcrun_cold_code_fixup(iarg->first, iarg->current, ui);
97  }
98 
99  break;
100 
101  case XED_ICLASS_JBE:
102  case XED_ICLASS_JL:
103  case XED_ICLASS_JLE:
104  case XED_ICLASS_JNB:
105  case XED_ICLASS_JNBE:
106  case XED_ICLASS_JNL:
107  case XED_ICLASS_JNLE:
108  case XED_ICLASS_JNO:
109  case XED_ICLASS_JNP:
110  case XED_ICLASS_JNS:
111  case XED_ICLASS_JNZ:
112  case XED_ICLASS_JO:
113  case XED_ICLASS_JP:
114  case XED_ICLASS_JRCXZ:
115  case XED_ICLASS_JS:
116  case XED_ICLASS_JZ:
117  next = process_conditional_branch(xptr, iarg);
118  break;
119 
120  case XED_ICLASS_FNSTCW:
121  case XED_ICLASS_STMXCSR:
122  if ((iarg->highwatermark).succ_inst_ptr == iarg->ins) {
123  //----------------------------------------------------------
124  // recognize Pathscale idiom for routine prefix and ignore
125  // any highwatermark setting that resulted from it.
126  //
127  // 20 December 2007 - John Mellor-Crummey
128  //----------------------------------------------------------
129  highwatermark_t empty_highwatermark = { NULL, NULL, HW_UNINITIALIZED };
130  iarg->highwatermark = empty_highwatermark;
131  }
132  next = iarg->current;
133  break;
134 
135  case XED_ICLASS_LEA:
136  next = process_lea(xptr, xi, iarg);
137  break;
138 
139  case XED_ICLASS_MOV:
140  next = process_move(xptr, xi, iarg);
141  break;
142 
143  case XED_ICLASS_ENTER:
144  next = process_enter(xptr, xi, iarg);
145  break;
146 
147  case XED_ICLASS_LEAVE:
148  next = process_leave(xptr, xi, iarg);
149  break;
150 
151  case XED_ICLASS_CALL_FAR:
152  case XED_ICLASS_CALL_NEAR:
153  next = process_call(xptr, xi, iarg);
154  break;
155 
156  case XED_ICLASS_RET_FAR:
157  case XED_ICLASS_RET_NEAR:
158  next = process_return(xptr, irdebug, iarg);
159  break;
160 
161  case XED_ICLASS_ADD:
162  case XED_ICLASS_SUB:
163  next = process_addsub(xptr, xi, iarg);
164  break;
165 
166  case XED_ICLASS_PUSH:
167  case XED_ICLASS_PUSHF:
168  case XED_ICLASS_PUSHFD:
169  case XED_ICLASS_PUSHFQ:
170  next = process_push(xptr, xi, iarg);
171  break;
172 
173  case XED_ICLASS_POP:
174  case XED_ICLASS_POPF:
175  case XED_ICLASS_POPFD:
176  case XED_ICLASS_POPFQ:
177  next = process_pop(xptr, xi, iarg);
178  break;
179 
180  case XED_ICLASS_AND:
181  next = process_and(xptr, xi, iarg);
182  break;
183 
184  default:
185  next = iarg->current;
186  break;
187  }
188 
189  return next;
190 }
bitree_uwi_t * first
static void process_push(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
unwind_interval * process_return(xed_decoded_inst_t *xptr, bool irdebug, interval_arg_t *iarg)
Definition: x86-return.c:66
static void process_call(char *ins, long offset, xed_decoded_inst_t *xptr, void *start, void *end)
bitree_uwi_t * current
static void process_enter(char *ins, long ins_offset)
static void process_leave(char *ins, long ins_offset)
unwind_interval * process_conditional_branch(xed_decoded_inst_t *xptr, interval_arg_t *iarg)
Definition: x86-jump.c:97
bitree_uwi_t * btuwi
Definition: unwindr_info.h:103
bool uw_recipe_map_lookup(void *addr, unwinder_t uw, unwindr_info_t *unwr_info)
unwind_interval * process_addsub(xed_decoded_inst_t *xptr, const xed_inst_t *xi, interval_arg_t *iarg)
Definition: x86-addsub.c:60
static void process_pop(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
struct bitree_uwi_s bitree_uwi_t
static void process_move(char *ins, xed_decoded_inst_t *xptr, long ins_offset)
highwatermark_t highwatermark
bool hpcrun_is_cold_code(xed_decoded_inst_t *xptr, interval_arg_t *iarg)
bool found
Definition: cct.c:129
#define TMSG(f,...)
Definition: messages.h:93
#define HW_UNINITIALIZED
Definition: x86-canonical.c:58
void dump_ui_stderr(unwind_interval *u)
unwind_interval * process_lea(xed_decoded_inst_t *xptr, const xed_inst_t *xi, interval_arg_t *iarg)
Definition: x86-lea.c:55
unwind_interval * process_unconditional_branch(xed_decoded_inst_t *xptr, bool irdebug, interval_arg_t *iarg)
Definition: x86-jump.c:68
#define NULL
Definition: ElfHelper.cpp:85
bitree_uwi_t unwind_interval
unwind_interval * process_and(xed_decoded_inst_t *xptr, const xed_inst_t *xi, interval_arg_t *iarg)
Definition: x86-and.c:59
unwind_interval * process_inst(xed_decoded_inst_t *xptr, interval_arg_t *iarg)
void hpcrun_cold_code_fixup(unwind_interval *first, unwind_interval *current, unwind_interval *warm)
#define ENABLED(f)
Definition: debug-flag.h:76