1 /* Copyright (C) 2014-2021 Free Software Foundation, Inc.
2 
3    Contributed by Intel Corp. <markus.t.metzger@intel.com>
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "common-defs.h"
21 #include "btrace-common.h"
22 
23 
24 /* See btrace-common.h.  */
25 
26 const char *
btrace_format_string(enum btrace_format format)27 btrace_format_string (enum btrace_format format)
28 {
29   switch (format)
30     {
31     case BTRACE_FORMAT_NONE:
32       return _("No or unknown format");
33 
34     case BTRACE_FORMAT_BTS:
35       return _("Branch Trace Store");
36 
37     case BTRACE_FORMAT_PT:
38       return _("Intel Processor Trace");
39     }
40 
41   internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
42 }
43 
44 /* See btrace-common.h.  */
45 
46 const char *
btrace_format_short_string(enum btrace_format format)47 btrace_format_short_string (enum btrace_format format)
48 {
49   switch (format)
50     {
51     case BTRACE_FORMAT_NONE:
52       return "unknown";
53 
54     case BTRACE_FORMAT_BTS:
55       return "bts";
56 
57     case BTRACE_FORMAT_PT:
58       return "pt";
59     }
60 
61   internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
62 }
63 
64 /* See btrace-common.h.  */
65 
66 void
fini()67 btrace_data::fini ()
68 {
69   switch (format)
70     {
71     case BTRACE_FORMAT_NONE:
72       /* Nothing to do.  */
73       return;
74 
75     case BTRACE_FORMAT_BTS:
76       delete variant.bts.blocks;
77       variant.bts.blocks = nullptr;
78       return;
79 
80     case BTRACE_FORMAT_PT:
81       xfree (variant.pt.data);
82       return;
83     }
84 
85   internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
86 }
87 
88 /* See btrace-common.h.  */
89 
90 bool
empty() const91 btrace_data::empty () const
92 {
93   switch (format)
94     {
95     case BTRACE_FORMAT_NONE:
96       return true;
97 
98     case BTRACE_FORMAT_BTS:
99       return variant.bts.blocks->empty ();
100 
101     case BTRACE_FORMAT_PT:
102       return (variant.pt.size == 0);
103     }
104 
105   internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
106 }
107 
108 /* See btrace-common.h.  */
109 
110 void
clear()111 btrace_data::clear ()
112 {
113   fini ();
114   format = BTRACE_FORMAT_NONE;
115 }
116 
117 /* See btrace-common.h.  */
118 
119 int
btrace_data_append(struct btrace_data * dst,const struct btrace_data * src)120 btrace_data_append (struct btrace_data *dst,
121 		    const struct btrace_data *src)
122 {
123   switch (src->format)
124     {
125     case BTRACE_FORMAT_NONE:
126       return 0;
127 
128     case BTRACE_FORMAT_BTS:
129       switch (dst->format)
130 	{
131 	default:
132 	  return -1;
133 
134 	case BTRACE_FORMAT_NONE:
135 	  dst->format = BTRACE_FORMAT_BTS;
136 	  dst->variant.bts.blocks = new std::vector<btrace_block>;
137 
138 	  /* Fall-through.  */
139 	case BTRACE_FORMAT_BTS:
140 	  {
141 	    unsigned int blk;
142 
143 	    /* We copy blocks in reverse order to have the oldest block at
144 	       index zero.  */
145 	    blk = src->variant.bts.blocks->size ();
146 	    while (blk != 0)
147 	      {
148 		const btrace_block &block
149 		  = src->variant.bts.blocks->at (--blk);
150 		dst->variant.bts.blocks->push_back (block);
151 	      }
152 	  }
153 	}
154       return 0;
155 
156     case BTRACE_FORMAT_PT:
157       switch (dst->format)
158 	{
159 	default:
160 	  return -1;
161 
162 	case BTRACE_FORMAT_NONE:
163 	  dst->format = BTRACE_FORMAT_PT;
164 	  dst->variant.pt.data = NULL;
165 	  dst->variant.pt.size = 0;
166 
167 	  /* fall-through.  */
168 	case BTRACE_FORMAT_PT:
169 	  {
170 	    gdb_byte *data;
171 	    size_t size;
172 
173 	    size = src->variant.pt.size + dst->variant.pt.size;
174 	    data = (gdb_byte *) xmalloc (size);
175 
176 	    if (dst->variant.pt.size > 0)
177 	      memcpy (data, dst->variant.pt.data, dst->variant.pt.size);
178 	    memcpy (data + dst->variant.pt.size, src->variant.pt.data,
179 		    src->variant.pt.size);
180 
181 	    xfree (dst->variant.pt.data);
182 
183 	    dst->variant.pt.data = data;
184 	    dst->variant.pt.size = size;
185 	  }
186 	}
187       return 0;
188     }
189 
190   internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
191 }
192