xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/btrace-common.cc (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* Copyright (C) 2014-2023 Free Software Foundation, Inc.
27d62b00eSchristos 
37d62b00eSchristos    Contributed by Intel Corp. <markus.t.metzger@intel.com>
47d62b00eSchristos 
57d62b00eSchristos    This file is part of GDB.
67d62b00eSchristos 
77d62b00eSchristos    This program is free software; you can redistribute it and/or modify
87d62b00eSchristos    it under the terms of the GNU General Public License as published by
97d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
107d62b00eSchristos    (at your option) any later version.
117d62b00eSchristos 
127d62b00eSchristos    This program is distributed in the hope that it will be useful,
137d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
147d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157d62b00eSchristos    GNU General Public License for more details.
167d62b00eSchristos 
177d62b00eSchristos    You should have received a copy of the GNU General Public License
187d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
197d62b00eSchristos 
207d62b00eSchristos #include "common-defs.h"
217d62b00eSchristos #include "btrace-common.h"
227d62b00eSchristos 
237d62b00eSchristos 
247d62b00eSchristos /* See btrace-common.h.  */
257d62b00eSchristos 
267d62b00eSchristos const char *
277d62b00eSchristos btrace_format_string (enum btrace_format format)
287d62b00eSchristos {
297d62b00eSchristos   switch (format)
307d62b00eSchristos     {
317d62b00eSchristos     case BTRACE_FORMAT_NONE:
327d62b00eSchristos       return _("No or unknown format");
337d62b00eSchristos 
347d62b00eSchristos     case BTRACE_FORMAT_BTS:
357d62b00eSchristos       return _("Branch Trace Store");
367d62b00eSchristos 
377d62b00eSchristos     case BTRACE_FORMAT_PT:
387d62b00eSchristos       return _("Intel Processor Trace");
397d62b00eSchristos     }
407d62b00eSchristos 
41*6881a400Schristos   internal_error (_("Unknown branch trace format"));
427d62b00eSchristos }
437d62b00eSchristos 
447d62b00eSchristos /* See btrace-common.h.  */
457d62b00eSchristos 
467d62b00eSchristos const char *
477d62b00eSchristos btrace_format_short_string (enum btrace_format format)
487d62b00eSchristos {
497d62b00eSchristos   switch (format)
507d62b00eSchristos     {
517d62b00eSchristos     case BTRACE_FORMAT_NONE:
527d62b00eSchristos       return "unknown";
537d62b00eSchristos 
547d62b00eSchristos     case BTRACE_FORMAT_BTS:
557d62b00eSchristos       return "bts";
567d62b00eSchristos 
577d62b00eSchristos     case BTRACE_FORMAT_PT:
587d62b00eSchristos       return "pt";
597d62b00eSchristos     }
607d62b00eSchristos 
61*6881a400Schristos   internal_error (_("Unknown branch trace format"));
627d62b00eSchristos }
637d62b00eSchristos 
647d62b00eSchristos /* See btrace-common.h.  */
657d62b00eSchristos 
667d62b00eSchristos void
677d62b00eSchristos btrace_data::fini ()
687d62b00eSchristos {
697d62b00eSchristos   switch (format)
707d62b00eSchristos     {
717d62b00eSchristos     case BTRACE_FORMAT_NONE:
727d62b00eSchristos       /* Nothing to do.  */
737d62b00eSchristos       return;
747d62b00eSchristos 
757d62b00eSchristos     case BTRACE_FORMAT_BTS:
767d62b00eSchristos       delete variant.bts.blocks;
777d62b00eSchristos       variant.bts.blocks = nullptr;
787d62b00eSchristos       return;
797d62b00eSchristos 
807d62b00eSchristos     case BTRACE_FORMAT_PT:
817d62b00eSchristos       xfree (variant.pt.data);
827d62b00eSchristos       return;
837d62b00eSchristos     }
847d62b00eSchristos 
85*6881a400Schristos   internal_error (_("Unkown branch trace format."));
867d62b00eSchristos }
877d62b00eSchristos 
887d62b00eSchristos /* See btrace-common.h.  */
897d62b00eSchristos 
907d62b00eSchristos bool
917d62b00eSchristos btrace_data::empty () const
927d62b00eSchristos {
937d62b00eSchristos   switch (format)
947d62b00eSchristos     {
957d62b00eSchristos     case BTRACE_FORMAT_NONE:
967d62b00eSchristos       return true;
977d62b00eSchristos 
987d62b00eSchristos     case BTRACE_FORMAT_BTS:
997d62b00eSchristos       return variant.bts.blocks->empty ();
1007d62b00eSchristos 
1017d62b00eSchristos     case BTRACE_FORMAT_PT:
1027d62b00eSchristos       return (variant.pt.size == 0);
1037d62b00eSchristos     }
1047d62b00eSchristos 
105*6881a400Schristos   internal_error (_("Unkown branch trace format."));
1067d62b00eSchristos }
1077d62b00eSchristos 
1087d62b00eSchristos /* See btrace-common.h.  */
1097d62b00eSchristos 
1107d62b00eSchristos void
1117d62b00eSchristos btrace_data::clear ()
1127d62b00eSchristos {
1137d62b00eSchristos   fini ();
1147d62b00eSchristos   format = BTRACE_FORMAT_NONE;
1157d62b00eSchristos }
1167d62b00eSchristos 
1177d62b00eSchristos /* See btrace-common.h.  */
1187d62b00eSchristos 
1197d62b00eSchristos int
1207d62b00eSchristos btrace_data_append (struct btrace_data *dst,
1217d62b00eSchristos 		    const struct btrace_data *src)
1227d62b00eSchristos {
1237d62b00eSchristos   switch (src->format)
1247d62b00eSchristos     {
1257d62b00eSchristos     case BTRACE_FORMAT_NONE:
1267d62b00eSchristos       return 0;
1277d62b00eSchristos 
1287d62b00eSchristos     case BTRACE_FORMAT_BTS:
1297d62b00eSchristos       switch (dst->format)
1307d62b00eSchristos 	{
1317d62b00eSchristos 	default:
1327d62b00eSchristos 	  return -1;
1337d62b00eSchristos 
1347d62b00eSchristos 	case BTRACE_FORMAT_NONE:
1357d62b00eSchristos 	  dst->format = BTRACE_FORMAT_BTS;
1367d62b00eSchristos 	  dst->variant.bts.blocks = new std::vector<btrace_block>;
1377d62b00eSchristos 
1387d62b00eSchristos 	  /* Fall-through.  */
1397d62b00eSchristos 	case BTRACE_FORMAT_BTS:
1407d62b00eSchristos 	  {
1417d62b00eSchristos 	    unsigned int blk;
1427d62b00eSchristos 
1437d62b00eSchristos 	    /* We copy blocks in reverse order to have the oldest block at
1447d62b00eSchristos 	       index zero.  */
1457d62b00eSchristos 	    blk = src->variant.bts.blocks->size ();
1467d62b00eSchristos 	    while (blk != 0)
1477d62b00eSchristos 	      {
1487d62b00eSchristos 		const btrace_block &block
1497d62b00eSchristos 		  = src->variant.bts.blocks->at (--blk);
1507d62b00eSchristos 		dst->variant.bts.blocks->push_back (block);
1517d62b00eSchristos 	      }
1527d62b00eSchristos 	  }
1537d62b00eSchristos 	}
1547d62b00eSchristos       return 0;
1557d62b00eSchristos 
1567d62b00eSchristos     case BTRACE_FORMAT_PT:
1577d62b00eSchristos       switch (dst->format)
1587d62b00eSchristos 	{
1597d62b00eSchristos 	default:
1607d62b00eSchristos 	  return -1;
1617d62b00eSchristos 
1627d62b00eSchristos 	case BTRACE_FORMAT_NONE:
1637d62b00eSchristos 	  dst->format = BTRACE_FORMAT_PT;
1647d62b00eSchristos 	  dst->variant.pt.data = NULL;
1657d62b00eSchristos 	  dst->variant.pt.size = 0;
1667d62b00eSchristos 
1677d62b00eSchristos 	  /* fall-through.  */
1687d62b00eSchristos 	case BTRACE_FORMAT_PT:
1697d62b00eSchristos 	  {
1707d62b00eSchristos 	    gdb_byte *data;
1717d62b00eSchristos 	    size_t size;
1727d62b00eSchristos 
1737d62b00eSchristos 	    size = src->variant.pt.size + dst->variant.pt.size;
1747d62b00eSchristos 	    data = (gdb_byte *) xmalloc (size);
1757d62b00eSchristos 
1767d62b00eSchristos 	    if (dst->variant.pt.size > 0)
1777d62b00eSchristos 	      memcpy (data, dst->variant.pt.data, dst->variant.pt.size);
1787d62b00eSchristos 	    memcpy (data + dst->variant.pt.size, src->variant.pt.data,
1797d62b00eSchristos 		    src->variant.pt.size);
1807d62b00eSchristos 
1817d62b00eSchristos 	    xfree (dst->variant.pt.data);
1827d62b00eSchristos 
1837d62b00eSchristos 	    dst->variant.pt.data = data;
1847d62b00eSchristos 	    dst->variant.pt.size = size;
1857d62b00eSchristos 	  }
1867d62b00eSchristos 	}
1877d62b00eSchristos       return 0;
1887d62b00eSchristos     }
1897d62b00eSchristos 
190*6881a400Schristos   internal_error (_("Unkown branch trace format."));
1917d62b00eSchristos }
192