HPCToolkit
x86-canonical.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 
48 #include "x86-decoder.h"
49 #include "x86-unwind-interval.h"
50 #include "x86-interval-arg.h"
51 
52 #include <messages/messages.h>
53 
54 #define HW_INITIALIZED 0x8
55 #define HW_BP_SAVED 0x4
56 #define HW_BP_OVERWRITTEN 0x2
57 #define HW_SP_DECREMENTED 0x1
58 #define HW_UNINITIALIZED 0x0
59 
60 
61 /******************************************************************************
62  * forward declarations
63  *****************************************************************************/
65 
67  unwind_interval *highwatermark);
68 
69 
70 
71 /******************************************************************************
72  * interface operations
73  *****************************************************************************/
74 
75 void
76 reset_to_canonical_interval(xed_decoded_inst_t *xptr, unwind_interval **next,
77  bool irdebug, interval_arg_t *iarg)
78 {
79  unwind_interval *current = iarg->current;
80  unwind_interval *first = iarg->first;
81  unwind_interval *hw_uwi = iarg->highwatermark.uwi;
82 
83  // if the return is not the last instruction in the interval,
84  // set up an interval for code after the return
85  if ((void*)nextInsn(iarg, xptr) < iarg->end) {
86  if (iarg->bp_frames_found) {
87  // look for first bp frame
88  first = find_first_bp_frame(first);
90  iarg->canonical_interval = first;
91  } else if (iarg->canonical_interval) {
92  x86recipe_t *xr = hw_uwi ? UWI_RECIPE(hw_uwi) : NULL;
93  if (xr && xr->reg.bp_status != BP_UNCHANGED) {
94  bp_loc bp_status = UWI_RECIPE(iarg->canonical_interval)->reg.bp_status;
95  if ((bp_status == BP_UNCHANGED) ||
96  ((bp_status == BP_SAVED) &&
97  (xr->reg.bp_status == BP_HOSED))) {
98  set_ui_canonical(hw_uwi, iarg->canonical_interval);
99  iarg->canonical_interval = hw_uwi;
100  }
101  }
102  first = iarg->canonical_interval;
103  } else {
104  // look for first nondecreasing with no jmp
105  first = find_first_non_decr(first, hw_uwi);
106  set_ui_canonical(first, iarg->canonical_interval);
107  iarg->canonical_interval = first;
108  }
109  {
110  x86recipe_t *xr = UWI_RECIPE(current);
111  x86recipe_t *r1 = UWI_RECIPE(first);
112  x86registers_t reg = r1->reg;
113  ra_loc ra_status = r1->ra_status;
114  bp_loc bp_status =
115  (xr->reg.bp_status == BP_HOSED) ? BP_HOSED : reg.bp_status;
117  if (xr->ra_status != ra_status) ||
118  xr->reg.bp_status != bp_status) ||
119  xr->reg.sp_ra_pos != reg.sp_ra_pos) ||
120  xr->reg.bp_ra_pos != reg.bp_ra_pos) ||
121  xr->reg.bp_bp_pos != reg.bp_bp_pos) ||
122  xr->reg.sp_bp_pos != reg.sp_bp_pos))
123 #endif
124  {
125  reg.bp_status = bp_status;
126  *next = new_ui(nextInsn(iarg, xptr), ra_status, &reg);
127  iarg->restored_canonical = *next;
128  set_ui_canonical(*next, UWI_RECIPE(iarg->canonical_interval)->prev_canonical);
129  if (r1->reg.bp_status != BP_HOSED && bp_status == BP_HOSED) {
130  set_ui_canonical(*next, iarg->canonical_interval);
131  iarg->canonical_interval = *next;
132  }
133  return;
134  }
135  }
136  }
137  *next = current;
138 }
139 
140 
141 
142 /******************************************************************************
143  * private operations
144  *****************************************************************************/
145 
146 
149 {
150  while (first && (UWI_RECIPE(first)->ra_status != RA_BP_FRAME))
151  first = UWI_NEXT(first);
152  return first;
153 }
154 
157 {
158  if (first == NULL)
159  return NULL;
160  int sp_ra_pos = UWI_RECIPE(first)->reg.sp_ra_pos;
161  int next_ra_pos;
162  unwind_interval *next;
163  while ((next = UWI_NEXT(first)) &&
164  (sp_ra_pos <= (next_ra_pos = UWI_RECIPE(next)->reg.sp_ra_pos)) &&
165  (first != highwatermark)) {
166  first = next;
167  sp_ra_pos = next_ra_pos;
168  }
169  return first;
170 }
171 
unwind_interval * restored_canonical
bitree_uwi_t * first
void reset_to_canonical_interval(xed_decoded_inst_t *xptr, unwind_interval **next, bool irdebug, interval_arg_t *iarg)
Definition: x86-canonical.c:76
#define FIX_INTERVALS_AT_RETURN
unwind_interval * find_first_bp_frame(unwind_interval *first)
bitree_uwi_t * current
unwind_interval * find_first_non_decr(unwind_interval *first, unwind_interval *highwatermark)
#define UWI_RECIPE(btuwi)
x86registers_t reg
bitree_uwi_t * canonical_interval
static char * nextInsn(uint32_t *insn)
highwatermark_t highwatermark
unwind_interval * new_ui(char *startaddr, sp_ty_t sp_ty, ra_ty_t ra_ty, int sp_arg, int ra_arg)
#define UWI_NEXT(btuwi)
#define NULL
Definition: ElfHelper.cpp:85
bitree_uwi_t unwind_interval
void set_ui_canonical(unwind_interval *u, unwind_interval *value)