Home | History | Annotate | Line # | Download | only in arch
      1      1.1  christos /* Common Linux target-dependent functionality for AArch64 MTE
      2      1.1  christos 
      3  1.1.1.2  christos    Copyright (C) 2021-2024 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GDB.
      6      1.1  christos 
      7      1.1  christos    This program is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos    (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos    This program is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "arch/aarch64-mte-linux.h"
     21      1.1  christos 
     22      1.1  christos /* See arch/aarch64-mte-linux.h */
     23      1.1  christos 
     24      1.1  christos void
     25      1.1  christos aarch64_mte_pack_tags (gdb::byte_vector &tags)
     26      1.1  christos {
     27      1.1  christos   /* Nothing to pack?  */
     28      1.1  christos   if (tags.empty ())
     29      1.1  christos     return;
     30      1.1  christos 
     31      1.1  christos   /* If the tags vector has an odd number of elements, add another
     32      1.1  christos      zeroed-out element to make it even.  This facilitates packing.  */
     33      1.1  christos   if ((tags.size () % 2) != 0)
     34      1.1  christos     tags.emplace_back (0);
     35      1.1  christos 
     36      1.1  christos   for (int unpacked = 0, packed = 0; unpacked < tags.size ();
     37      1.1  christos        unpacked += 2, packed++)
     38      1.1  christos     tags[packed] = (tags[unpacked + 1] << 4) | tags[unpacked];
     39      1.1  christos 
     40      1.1  christos   /* Now we have half the size.  */
     41      1.1  christos   tags.resize (tags.size () / 2);
     42      1.1  christos }
     43      1.1  christos 
     44      1.1  christos /* See arch/aarch64-mte-linux.h */
     45      1.1  christos 
     46      1.1  christos void
     47      1.1  christos aarch64_mte_unpack_tags (gdb::byte_vector &tags, bool skip_first)
     48      1.1  christos {
     49      1.1  christos   /* Nothing to unpack?  */
     50      1.1  christos   if (tags.empty ())
     51      1.1  christos     return;
     52      1.1  christos 
     53      1.1  christos   /* An unpacked MTE tags vector will have twice the number of elements
     54      1.1  christos      compared to an unpacked one.  */
     55      1.1  christos   gdb::byte_vector unpacked_tags (tags.size () * 2);
     56      1.1  christos 
     57      1.1  christos   int unpacked = 0, packed = 0;
     58      1.1  christos 
     59      1.1  christos   if (skip_first)
     60      1.1  christos     {
     61      1.1  christos       /* We are not interested in the first unpacked element, just discard
     62      1.1  christos 	 it.  */
     63      1.1  christos       unpacked_tags[unpacked] = (tags[packed] >> 4) & 0xf;
     64      1.1  christos       unpacked++;
     65      1.1  christos       packed++;
     66      1.1  christos     }
     67      1.1  christos 
     68      1.1  christos   for (; packed < tags.size (); unpacked += 2, packed++)
     69      1.1  christos     {
     70      1.1  christos       unpacked_tags[unpacked] = tags[packed] & 0xf;
     71      1.1  christos       unpacked_tags[unpacked + 1] = (tags[packed] >> 4) & 0xf;
     72      1.1  christos     }
     73      1.1  christos 
     74      1.1  christos   /* Update the original tags vector.  */
     75      1.1  christos   tags = std::move (unpacked_tags);
     76      1.1  christos }
     77      1.1  christos 
     78