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