xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/btrace-common.cc (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /* Copyright (C) 2014-2024 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 "btrace-common.h"
21 
22 
23 /* See btrace-common.h.  */
24 
25 const char *
26 btrace_format_string (enum btrace_format format)
27 {
28   switch (format)
29     {
30     case BTRACE_FORMAT_NONE:
31       return _("No or unknown format");
32 
33     case BTRACE_FORMAT_BTS:
34       return _("Branch Trace Store");
35 
36     case BTRACE_FORMAT_PT:
37       return _("Intel Processor Trace");
38     }
39 
40   internal_error (_("Unknown branch trace format"));
41 }
42 
43 /* See btrace-common.h.  */
44 
45 const char *
46 btrace_format_short_string (enum btrace_format format)
47 {
48   switch (format)
49     {
50     case BTRACE_FORMAT_NONE:
51       return "unknown";
52 
53     case BTRACE_FORMAT_BTS:
54       return "bts";
55 
56     case BTRACE_FORMAT_PT:
57       return "pt";
58     }
59 
60   internal_error (_("Unknown branch trace format"));
61 }
62 
63 /* See btrace-common.h.  */
64 
65 void
66 btrace_data::fini ()
67 {
68   switch (format)
69     {
70     case BTRACE_FORMAT_NONE:
71       /* Nothing to do.  */
72       return;
73 
74     case BTRACE_FORMAT_BTS:
75       delete variant.bts.blocks;
76       variant.bts.blocks = nullptr;
77       return;
78 
79     case BTRACE_FORMAT_PT:
80       xfree (variant.pt.data);
81       return;
82     }
83 
84   internal_error (_("Unkown branch trace format."));
85 }
86 
87 /* See btrace-common.h.  */
88 
89 bool
90 btrace_data::empty () const
91 {
92   switch (format)
93     {
94     case BTRACE_FORMAT_NONE:
95       return true;
96 
97     case BTRACE_FORMAT_BTS:
98       return variant.bts.blocks->empty ();
99 
100     case BTRACE_FORMAT_PT:
101       return (variant.pt.size == 0);
102     }
103 
104   internal_error (_("Unkown branch trace format."));
105 }
106 
107 /* See btrace-common.h.  */
108 
109 void
110 btrace_data::clear ()
111 {
112   fini ();
113   format = BTRACE_FORMAT_NONE;
114 }
115 
116 /* See btrace-common.h.  */
117 
118 int
119 btrace_data_append (struct btrace_data *dst,
120 		    const struct btrace_data *src)
121 {
122   switch (src->format)
123     {
124     case BTRACE_FORMAT_NONE:
125       return 0;
126 
127     case BTRACE_FORMAT_BTS:
128       switch (dst->format)
129 	{
130 	default:
131 	  return -1;
132 
133 	case BTRACE_FORMAT_NONE:
134 	  dst->format = BTRACE_FORMAT_BTS;
135 	  dst->variant.bts.blocks = new std::vector<btrace_block>;
136 	  [[fallthrough]];
137 	case BTRACE_FORMAT_BTS:
138 	  {
139 	    unsigned int blk;
140 
141 	    /* We copy blocks in reverse order to have the oldest block at
142 	       index zero.  */
143 	    blk = src->variant.bts.blocks->size ();
144 	    while (blk != 0)
145 	      {
146 		const btrace_block &block
147 		  = src->variant.bts.blocks->at (--blk);
148 		dst->variant.bts.blocks->push_back (block);
149 	      }
150 	  }
151 	}
152       return 0;
153 
154     case BTRACE_FORMAT_PT:
155       switch (dst->format)
156 	{
157 	default:
158 	  return -1;
159 
160 	case BTRACE_FORMAT_NONE:
161 	  dst->format = BTRACE_FORMAT_PT;
162 	  dst->variant.pt.data = NULL;
163 	  dst->variant.pt.size = 0;
164 	  [[fallthrough]];
165 	case BTRACE_FORMAT_PT:
166 	  {
167 	    gdb_byte *data;
168 	    size_t size;
169 
170 	    size = src->variant.pt.size + dst->variant.pt.size;
171 	    data = (gdb_byte *) xmalloc (size);
172 
173 	    if (dst->variant.pt.size > 0)
174 	      memcpy (data, dst->variant.pt.data, dst->variant.pt.size);
175 	    memcpy (data + dst->variant.pt.size, src->variant.pt.data,
176 		    src->variant.pt.size);
177 
178 	    xfree (dst->variant.pt.data);
179 
180 	    dst->variant.pt.data = data;
181 	    dst->variant.pt.size = size;
182 	  }
183 	}
184       return 0;
185     }
186 
187   internal_error (_("Unkown branch trace format."));
188 }
189