1/* Copyright (C) 2014-2020 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
26const char *
27btrace_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
46const char *
47btrace_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
66void
67btrace_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
90bool
91btrace_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
110void
111btrace_data::clear ()
112{
113  fini ();
114  format = BTRACE_FORMAT_NONE;
115}
116
117/* See btrace-common.h.  */
118
119int
120btrace_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