]> Git Repo - binutils.git/blob - gdb/arch/aarch64-mte-linux.c
Automatic date update in version.in
[binutils.git] / gdb / arch / aarch64-mte-linux.c
1 /* Common Linux target-dependent functionality for AArch64 MTE
2
3    Copyright (C) 2021-2022 Free Software Foundation, Inc.
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 "arch/aarch64-mte-linux.h"
21
22 /* See arch/aarch64-mte-linux.h */
23
24 void
25 aarch64_mte_pack_tags (gdb::byte_vector &tags)
26 {
27   /* Nothing to pack?  */
28   if (tags.empty ())
29     return;
30
31   /* If the tags vector has an odd number of elements, add another
32      zeroed-out element to make it even.  This facilitates packing.  */
33   if ((tags.size () % 2) != 0)
34     tags.emplace_back (0);
35
36   for (int unpacked = 0, packed = 0; unpacked < tags.size ();
37        unpacked += 2, packed++)
38     tags[packed] = (tags[unpacked + 1] << 4) | tags[unpacked];
39
40   /* Now we have half the size.  */
41   tags.resize (tags.size () / 2);
42 }
43
44 /* See arch/aarch64-mte-linux.h */
45
46 void
47 aarch64_mte_unpack_tags (gdb::byte_vector &tags, bool skip_first)
48 {
49   /* Nothing to unpack?  */
50   if (tags.empty ())
51     return;
52
53   /* An unpacked MTE tags vector will have twice the number of elements
54      compared to an unpacked one.  */
55   gdb::byte_vector unpacked_tags (tags.size () * 2);
56
57   int unpacked = 0, packed = 0;
58
59   if (skip_first)
60     {
61       /* We are not interested in the first unpacked element, just discard
62          it.  */
63       unpacked_tags[unpacked] = (tags[packed] >> 4) & 0xf;
64       unpacked++;
65       packed++;
66     }
67
68   for (; packed < tags.size (); unpacked += 2, packed++)
69     {
70       unpacked_tags[unpacked] = tags[packed] & 0xf;
71       unpacked_tags[unpacked + 1] = (tags[packed] >> 4) & 0xf;
72     }
73
74   /* Update the original tags vector.  */
75   tags = std::move (unpacked_tags);
76 }
77
78 /* See arch/aarch64-mte-linux.h */
79
80 size_t
81 aarch64_mte_get_tag_granules (CORE_ADDR addr, size_t len, size_t granule_size)
82 {
83   /* An empty range has 0 tag granules.  */
84   if (len == 0)
85     return 0;
86
87   /* Start address */
88   CORE_ADDR s_addr = align_down (addr, granule_size);
89   /* End address */
90   CORE_ADDR e_addr = align_down (addr + len - 1, granule_size);
91
92   /* We always have at least 1 granule because len is non-zero at this
93      point.  */
94   return 1 + (e_addr - s_addr) / granule_size;
95 }
96
97 /* See arch/aarch64-mte-linux.h */
98
99 CORE_ADDR
100 aarch64_mte_make_ltag_bits (CORE_ADDR value)
101 {
102   return value & AARCH64_MTE_LOGICAL_MAX_VALUE;
103 }
104
105 /* See arch/aarch64-mte-linux.h */
106
107 CORE_ADDR
108 aarch64_mte_make_ltag (CORE_ADDR value)
109 {
110   return (aarch64_mte_make_ltag_bits (value)
111           << AARCH64_MTE_LOGICAL_TAG_START_BIT);
112 }
113
114 /* See arch/aarch64-mte-linux.h */
115
116 CORE_ADDR
117 aarch64_mte_set_ltag (CORE_ADDR address, CORE_ADDR tag)
118 {
119   /* Remove the existing tag.  */
120   address &= ~aarch64_mte_make_ltag (AARCH64_MTE_LOGICAL_MAX_VALUE);
121
122   /* Return the new tagged address.  */
123   return address | aarch64_mte_make_ltag (tag);
124 }
125
126 /* See arch/aarch64-mte-linux.h */
127
128 CORE_ADDR
129 aarch64_mte_get_ltag (CORE_ADDR address)
130 {
131   CORE_ADDR ltag_addr = address >> AARCH64_MTE_LOGICAL_TAG_START_BIT;
132   return aarch64_mte_make_ltag_bits (ltag_addr);
133 }
This page took 0.032101 seconds and 4 git commands to generate.