]>
Commit | Line | Data |
---|---|---|
01fd3ea5 TT |
1 | /* Cell-based print utility routines for GDB, the GNU debugger. |
2 | ||
1d506c26 | 3 | Copyright (C) 1986-2024 Free Software Foundation, Inc. |
01fd3ea5 TT |
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 | ||
01fd3ea5 | 20 | #include "print-utils.h" |
01fd3ea5 TT |
21 | /* Temporary storage using circular buffer. */ |
22 | ||
43792cf0 | 23 | /* Number of cells in the circular buffer. */ |
01fd3ea5 | 24 | #define NUMCELLS 16 |
01fd3ea5 TT |
25 | |
26 | /* Return the next entry in the circular buffer. */ | |
27 | ||
43792cf0 PA |
28 | char * |
29 | get_print_cell (void) | |
01fd3ea5 | 30 | { |
43792cf0 | 31 | static char buf[NUMCELLS][PRINT_CELL_SIZE]; |
01fd3ea5 TT |
32 | static int cell = 0; |
33 | ||
34 | if (++cell >= NUMCELLS) | |
35 | cell = 0; | |
36 | return buf[cell]; | |
37 | } | |
38 | ||
39 | static char * | |
a121b7c1 | 40 | decimal2str (const char *sign, ULONGEST addr, int width) |
01fd3ea5 TT |
41 | { |
42 | /* Steal code from valprint.c:print_decimal(). Should this worry | |
43 | about the real size of addr as the above does? */ | |
44 | unsigned long temp[3]; | |
43792cf0 | 45 | char *str = get_print_cell (); |
01fd3ea5 TT |
46 | int i = 0; |
47 | ||
48 | do | |
49 | { | |
50 | temp[i] = addr % (1000 * 1000 * 1000); | |
51 | addr /= (1000 * 1000 * 1000); | |
52 | i++; | |
53 | width -= 9; | |
54 | } | |
55 | while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); | |
56 | ||
57 | width += 9; | |
58 | if (width < 0) | |
59 | width = 0; | |
60 | ||
61 | switch (i) | |
62 | { | |
63 | case 1: | |
43792cf0 | 64 | xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]); |
01fd3ea5 TT |
65 | break; |
66 | case 2: | |
43792cf0 | 67 | xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width, |
01fd3ea5 TT |
68 | temp[1], temp[0]); |
69 | break; | |
70 | case 3: | |
43792cf0 | 71 | xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width, |
01fd3ea5 TT |
72 | temp[2], temp[1], temp[0]); |
73 | break; | |
74 | default: | |
f34652de | 75 | internal_error (_("failed internal consistency check")); |
01fd3ea5 TT |
76 | } |
77 | ||
78 | return str; | |
79 | } | |
80 | ||
81 | static char * | |
82 | octal2str (ULONGEST addr, int width) | |
83 | { | |
84 | unsigned long temp[3]; | |
43792cf0 | 85 | char *str = get_print_cell (); |
01fd3ea5 TT |
86 | int i = 0; |
87 | ||
88 | do | |
89 | { | |
90 | temp[i] = addr % (0100000 * 0100000); | |
91 | addr /= (0100000 * 0100000); | |
92 | i++; | |
93 | width -= 10; | |
94 | } | |
95 | while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); | |
96 | ||
97 | width += 10; | |
98 | if (width < 0) | |
99 | width = 0; | |
100 | ||
101 | switch (i) | |
102 | { | |
103 | case 1: | |
104 | if (temp[0] == 0) | |
43792cf0 | 105 | xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0); |
01fd3ea5 | 106 | else |
43792cf0 | 107 | xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]); |
01fd3ea5 TT |
108 | break; |
109 | case 2: | |
43792cf0 | 110 | xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]); |
01fd3ea5 TT |
111 | break; |
112 | case 3: | |
43792cf0 | 113 | xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width, |
01fd3ea5 TT |
114 | temp[2], temp[1], temp[0]); |
115 | break; | |
116 | default: | |
f34652de | 117 | internal_error (_("failed internal consistency check")); |
01fd3ea5 TT |
118 | } |
119 | ||
120 | return str; | |
121 | } | |
122 | ||
123 | /* See print-utils.h. */ | |
124 | ||
523e454f | 125 | const char * |
01fd3ea5 TT |
126 | pulongest (ULONGEST u) |
127 | { | |
128 | return decimal2str ("", u, 0); | |
129 | } | |
130 | ||
131 | /* See print-utils.h. */ | |
132 | ||
523e454f | 133 | const char * |
01fd3ea5 TT |
134 | plongest (LONGEST l) |
135 | { | |
136 | if (l < 0) | |
137 | return decimal2str ("-", -l, 0); | |
138 | else | |
139 | return decimal2str ("", l, 0); | |
140 | } | |
141 | ||
142 | /* Eliminate warning from compiler on 32-bit systems. */ | |
143 | static int thirty_two = 32; | |
144 | ||
145 | /* See print-utils.h. */ | |
146 | ||
523e454f | 147 | const char * |
01fd3ea5 TT |
148 | phex (ULONGEST l, int sizeof_l) |
149 | { | |
150 | char *str; | |
151 | ||
152 | switch (sizeof_l) | |
153 | { | |
154 | case 8: | |
43792cf0 PA |
155 | str = get_print_cell (); |
156 | xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx", | |
01fd3ea5 TT |
157 | (unsigned long) (l >> thirty_two), |
158 | (unsigned long) (l & 0xffffffff)); | |
159 | break; | |
160 | case 4: | |
43792cf0 PA |
161 | str = get_print_cell (); |
162 | xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l); | |
01fd3ea5 TT |
163 | break; |
164 | case 2: | |
43792cf0 PA |
165 | str = get_print_cell (); |
166 | xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff)); | |
01fd3ea5 | 167 | break; |
c8b76e1e TT |
168 | case 1: |
169 | str = get_print_cell (); | |
170 | xsnprintf (str, PRINT_CELL_SIZE, "%02x", (unsigned short) (l & 0xff)); | |
171 | break; | |
01fd3ea5 | 172 | default: |
523e454f | 173 | return phex (l, sizeof (l)); |
01fd3ea5 TT |
174 | break; |
175 | } | |
176 | ||
177 | return str; | |
178 | } | |
179 | ||
180 | /* See print-utils.h. */ | |
181 | ||
523e454f | 182 | const char * |
01fd3ea5 TT |
183 | phex_nz (ULONGEST l, int sizeof_l) |
184 | { | |
185 | char *str; | |
186 | ||
187 | switch (sizeof_l) | |
188 | { | |
189 | case 8: | |
190 | { | |
191 | unsigned long high = (unsigned long) (l >> thirty_two); | |
192 | ||
43792cf0 | 193 | str = get_print_cell (); |
01fd3ea5 | 194 | if (high == 0) |
43792cf0 | 195 | xsnprintf (str, PRINT_CELL_SIZE, "%lx", |
01fd3ea5 TT |
196 | (unsigned long) (l & 0xffffffff)); |
197 | else | |
43792cf0 | 198 | xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high, |
01fd3ea5 TT |
199 | (unsigned long) (l & 0xffffffff)); |
200 | break; | |
201 | } | |
202 | case 4: | |
43792cf0 PA |
203 | str = get_print_cell (); |
204 | xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l); | |
01fd3ea5 TT |
205 | break; |
206 | case 2: | |
43792cf0 PA |
207 | str = get_print_cell (); |
208 | xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff)); | |
01fd3ea5 | 209 | break; |
c8b76e1e TT |
210 | case 1: |
211 | str = get_print_cell (); | |
212 | xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xff)); | |
213 | break; | |
01fd3ea5 | 214 | default: |
523e454f | 215 | return phex_nz (l, sizeof (l)); |
01fd3ea5 TT |
216 | break; |
217 | } | |
218 | ||
219 | return str; | |
220 | } | |
221 | ||
222 | /* See print-utils.h. */ | |
223 | ||
523e454f | 224 | const char * |
01fd3ea5 TT |
225 | hex_string (LONGEST num) |
226 | { | |
43792cf0 | 227 | char *result = get_print_cell (); |
01fd3ea5 | 228 | |
43792cf0 | 229 | xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num))); |
01fd3ea5 TT |
230 | return result; |
231 | } | |
232 | ||
233 | /* See print-utils.h. */ | |
234 | ||
523e454f | 235 | const char * |
01fd3ea5 TT |
236 | hex_string_custom (LONGEST num, int width) |
237 | { | |
43792cf0 PA |
238 | char *result = get_print_cell (); |
239 | char *result_end = result + PRINT_CELL_SIZE - 1; | |
01fd3ea5 TT |
240 | const char *hex = phex_nz (num, sizeof (num)); |
241 | int hex_len = strlen (hex); | |
242 | ||
243 | if (hex_len > width) | |
244 | width = hex_len; | |
43792cf0 | 245 | if (width + 2 >= PRINT_CELL_SIZE) |
f34652de | 246 | internal_error (_("\ |
01fd3ea5 TT |
247 | hex_string_custom: insufficient space to store result")); |
248 | ||
249 | strcpy (result_end - width - 2, "0x"); | |
250 | memset (result_end - width, '0', width); | |
251 | strcpy (result_end - hex_len, hex); | |
252 | return result_end - width - 2; | |
253 | } | |
254 | ||
255 | /* See print-utils.h. */ | |
256 | ||
523e454f | 257 | const char * |
8b578f9c | 258 | int_string (LONGEST val, int radix, int is_signed, int width, |
01fd3ea5 TT |
259 | int use_c_format) |
260 | { | |
8b578f9c | 261 | switch (radix) |
01fd3ea5 TT |
262 | { |
263 | case 16: | |
264 | { | |
523e454f | 265 | const char *result; |
01fd3ea5 TT |
266 | |
267 | if (width == 0) | |
268 | result = hex_string (val); | |
269 | else | |
270 | result = hex_string_custom (val, width); | |
271 | if (! use_c_format) | |
272 | result += 2; | |
273 | return result; | |
274 | } | |
275 | case 10: | |
276 | { | |
277 | if (is_signed && val < 0) | |
735dfe02 TV |
278 | /* Cast to unsigned before negating, to prevent runtime error: |
279 | negation of -9223372036854775808 cannot be represented in type | |
280 | 'long int'; cast to an unsigned type to negate this value to | |
281 | itself. */ | |
282 | return decimal2str ("-", -(ULONGEST)val, width); | |
01fd3ea5 TT |
283 | else |
284 | return decimal2str ("", val, width); | |
285 | } | |
286 | case 8: | |
287 | { | |
288 | char *result = octal2str (val, width); | |
289 | ||
290 | if (use_c_format || val == 0) | |
291 | return result; | |
292 | else | |
293 | return result + 1; | |
294 | } | |
295 | default: | |
f34652de | 296 | internal_error (_("failed internal consistency check")); |
01fd3ea5 | 297 | } |
8b578f9c | 298 | } |
01fd3ea5 TT |
299 | |
300 | /* See print-utils.h. */ | |
301 | ||
302 | const char * | |
303 | core_addr_to_string (const CORE_ADDR addr) | |
304 | { | |
43792cf0 | 305 | char *str = get_print_cell (); |
01fd3ea5 TT |
306 | |
307 | strcpy (str, "0x"); | |
308 | strcat (str, phex (addr, sizeof (addr))); | |
309 | return str; | |
310 | } | |
311 | ||
312 | /* See print-utils.h. */ | |
313 | ||
314 | const char * | |
315 | core_addr_to_string_nz (const CORE_ADDR addr) | |
316 | { | |
43792cf0 | 317 | char *str = get_print_cell (); |
01fd3ea5 TT |
318 | |
319 | strcpy (str, "0x"); | |
320 | strcat (str, phex_nz (addr, sizeof (addr))); | |
321 | return str; | |
322 | } | |
323 | ||
324 | /* See print-utils.h. */ | |
325 | ||
326 | const char * | |
b80c3053 | 327 | host_address_to_string_1 (const void *addr) |
01fd3ea5 | 328 | { |
43792cf0 | 329 | char *str = get_print_cell (); |
01fd3ea5 | 330 | |
43792cf0 PA |
331 | xsnprintf (str, PRINT_CELL_SIZE, "0x%s", |
332 | phex_nz ((uintptr_t) addr, sizeof (addr))); | |
01fd3ea5 TT |
333 | return str; |
334 | } |