xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/print-utils.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
18dffb485Schristos /* Cell-based print utility routines for GDB, the GNU debugger.
28dffb485Schristos 
3*5ba1f45fSchristos    Copyright (C) 1986-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This file is part of GDB.
68dffb485Schristos 
78dffb485Schristos    This program is free software; you can redistribute it and/or modify
88dffb485Schristos    it under the terms of the GNU General Public License as published by
98dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
108dffb485Schristos    (at your option) any later version.
118dffb485Schristos 
128dffb485Schristos    This program is distributed in the hope that it will be useful,
138dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
148dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158dffb485Schristos    GNU General Public License for more details.
168dffb485Schristos 
178dffb485Schristos    You should have received a copy of the GNU General Public License
188dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
198dffb485Schristos 
208dffb485Schristos #include "print-utils.h"
218dffb485Schristos /* Temporary storage using circular buffer.  */
228dffb485Schristos 
238dffb485Schristos /* Number of cells in the circular buffer.  */
248dffb485Schristos #define NUMCELLS 16
258dffb485Schristos 
268dffb485Schristos /* Return the next entry in the circular buffer.  */
278dffb485Schristos 
288dffb485Schristos char *
298dffb485Schristos get_print_cell (void)
308dffb485Schristos {
318dffb485Schristos   static char buf[NUMCELLS][PRINT_CELL_SIZE];
328dffb485Schristos   static int cell = 0;
338dffb485Schristos 
348dffb485Schristos   if (++cell >= NUMCELLS)
358dffb485Schristos     cell = 0;
368dffb485Schristos   return buf[cell];
378dffb485Schristos }
388dffb485Schristos 
398dffb485Schristos static char *
408dffb485Schristos decimal2str (const char *sign, ULONGEST addr, int width)
418dffb485Schristos {
428dffb485Schristos   /* Steal code from valprint.c:print_decimal().  Should this worry
438dffb485Schristos      about the real size of addr as the above does?  */
448dffb485Schristos   unsigned long temp[3];
458dffb485Schristos   char *str = get_print_cell ();
468dffb485Schristos   int i = 0;
478dffb485Schristos 
488dffb485Schristos   do
498dffb485Schristos     {
508dffb485Schristos       temp[i] = addr % (1000 * 1000 * 1000);
518dffb485Schristos       addr /= (1000 * 1000 * 1000);
528dffb485Schristos       i++;
538dffb485Schristos       width -= 9;
548dffb485Schristos     }
558dffb485Schristos   while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
568dffb485Schristos 
578dffb485Schristos   width += 9;
588dffb485Schristos   if (width < 0)
598dffb485Schristos     width = 0;
608dffb485Schristos 
618dffb485Schristos   switch (i)
628dffb485Schristos     {
638dffb485Schristos     case 1:
648dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]);
658dffb485Schristos       break;
668dffb485Schristos     case 2:
678dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width,
688dffb485Schristos 		 temp[1], temp[0]);
698dffb485Schristos       break;
708dffb485Schristos     case 3:
718dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width,
728dffb485Schristos 		 temp[2], temp[1], temp[0]);
738dffb485Schristos       break;
748dffb485Schristos     default:
754b169a6bSchristos       internal_error (_("failed internal consistency check"));
768dffb485Schristos     }
778dffb485Schristos 
788dffb485Schristos   return str;
798dffb485Schristos }
808dffb485Schristos 
818dffb485Schristos static char *
828dffb485Schristos octal2str (ULONGEST addr, int width)
838dffb485Schristos {
848dffb485Schristos   unsigned long temp[3];
858dffb485Schristos   char *str = get_print_cell ();
868dffb485Schristos   int i = 0;
878dffb485Schristos 
888dffb485Schristos   do
898dffb485Schristos     {
908dffb485Schristos       temp[i] = addr % (0100000 * 0100000);
918dffb485Schristos       addr /= (0100000 * 0100000);
928dffb485Schristos       i++;
938dffb485Schristos       width -= 10;
948dffb485Schristos     }
958dffb485Schristos   while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
968dffb485Schristos 
978dffb485Schristos   width += 10;
988dffb485Schristos   if (width < 0)
998dffb485Schristos     width = 0;
1008dffb485Schristos 
1018dffb485Schristos   switch (i)
1028dffb485Schristos     {
1038dffb485Schristos     case 1:
1048dffb485Schristos       if (temp[0] == 0)
1058dffb485Schristos 	xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0);
1068dffb485Schristos       else
1078dffb485Schristos 	xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]);
1088dffb485Schristos       break;
1098dffb485Schristos     case 2:
1108dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]);
1118dffb485Schristos       break;
1128dffb485Schristos     case 3:
1138dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width,
1148dffb485Schristos 		 temp[2], temp[1], temp[0]);
1158dffb485Schristos       break;
1168dffb485Schristos     default:
1174b169a6bSchristos       internal_error (_("failed internal consistency check"));
1188dffb485Schristos     }
1198dffb485Schristos 
1208dffb485Schristos   return str;
1218dffb485Schristos }
1228dffb485Schristos 
1238dffb485Schristos /* See print-utils.h.  */
1248dffb485Schristos 
125*5ba1f45fSchristos const char *
1268dffb485Schristos pulongest (ULONGEST u)
1278dffb485Schristos {
1288dffb485Schristos   return decimal2str ("", u, 0);
1298dffb485Schristos }
1308dffb485Schristos 
1318dffb485Schristos /* See print-utils.h.  */
1328dffb485Schristos 
133*5ba1f45fSchristos const char *
1348dffb485Schristos plongest (LONGEST l)
1358dffb485Schristos {
1368dffb485Schristos   if (l < 0)
1378dffb485Schristos     return decimal2str ("-", -l, 0);
1388dffb485Schristos   else
1398dffb485Schristos     return decimal2str ("", l, 0);
1408dffb485Schristos }
1418dffb485Schristos 
1428dffb485Schristos /* Eliminate warning from compiler on 32-bit systems.  */
1438dffb485Schristos static int thirty_two = 32;
1448dffb485Schristos 
1458dffb485Schristos /* See print-utils.h.  */
1468dffb485Schristos 
147*5ba1f45fSchristos const char *
1488dffb485Schristos phex (ULONGEST l, int sizeof_l)
1498dffb485Schristos {
1508dffb485Schristos   char *str;
1518dffb485Schristos 
1528dffb485Schristos   switch (sizeof_l)
1538dffb485Schristos     {
1548dffb485Schristos     case 8:
1558dffb485Schristos       str = get_print_cell ();
1568dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx",
1578dffb485Schristos 		 (unsigned long) (l >> thirty_two),
1588dffb485Schristos 		 (unsigned long) (l & 0xffffffff));
1598dffb485Schristos       break;
1608dffb485Schristos     case 4:
1618dffb485Schristos       str = get_print_cell ();
1628dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l);
1638dffb485Schristos       break;
1648dffb485Schristos     case 2:
1658dffb485Schristos       str = get_print_cell ();
1668dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff));
1678dffb485Schristos       break;
1684b169a6bSchristos     case 1:
1694b169a6bSchristos       str = get_print_cell ();
1704b169a6bSchristos       xsnprintf (str, PRINT_CELL_SIZE, "%02x", (unsigned short) (l & 0xff));
1714b169a6bSchristos       break;
1728dffb485Schristos     default:
173*5ba1f45fSchristos       return phex (l, sizeof (l));
1748dffb485Schristos       break;
1758dffb485Schristos     }
1768dffb485Schristos 
1778dffb485Schristos   return str;
1788dffb485Schristos }
1798dffb485Schristos 
1808dffb485Schristos /* See print-utils.h.  */
1818dffb485Schristos 
182*5ba1f45fSchristos const char *
1838dffb485Schristos phex_nz (ULONGEST l, int sizeof_l)
1848dffb485Schristos {
1858dffb485Schristos   char *str;
1868dffb485Schristos 
1878dffb485Schristos   switch (sizeof_l)
1888dffb485Schristos     {
1898dffb485Schristos     case 8:
1908dffb485Schristos       {
1918dffb485Schristos 	unsigned long high = (unsigned long) (l >> thirty_two);
1928dffb485Schristos 
1938dffb485Schristos 	str = get_print_cell ();
1948dffb485Schristos 	if (high == 0)
1958dffb485Schristos 	  xsnprintf (str, PRINT_CELL_SIZE, "%lx",
1968dffb485Schristos 		     (unsigned long) (l & 0xffffffff));
1978dffb485Schristos 	else
1988dffb485Schristos 	  xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high,
1998dffb485Schristos 		     (unsigned long) (l & 0xffffffff));
2008dffb485Schristos 	break;
2018dffb485Schristos       }
2028dffb485Schristos     case 4:
2038dffb485Schristos       str = get_print_cell ();
2048dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l);
2058dffb485Schristos       break;
2068dffb485Schristos     case 2:
2078dffb485Schristos       str = get_print_cell ();
2088dffb485Schristos       xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff));
2098dffb485Schristos       break;
2104b169a6bSchristos     case 1:
2114b169a6bSchristos       str = get_print_cell ();
2124b169a6bSchristos       xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xff));
2134b169a6bSchristos       break;
2148dffb485Schristos     default:
215*5ba1f45fSchristos       return phex_nz (l, sizeof (l));
2168dffb485Schristos       break;
2178dffb485Schristos     }
2188dffb485Schristos 
2198dffb485Schristos   return str;
2208dffb485Schristos }
2218dffb485Schristos 
2228dffb485Schristos /* See print-utils.h.  */
2238dffb485Schristos 
224*5ba1f45fSchristos const char *
2258dffb485Schristos hex_string (LONGEST num)
2268dffb485Schristos {
2278dffb485Schristos   char *result = get_print_cell ();
2288dffb485Schristos 
2298dffb485Schristos   xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num)));
2308dffb485Schristos   return result;
2318dffb485Schristos }
2328dffb485Schristos 
2338dffb485Schristos /* See print-utils.h.  */
2348dffb485Schristos 
235*5ba1f45fSchristos const char *
2368dffb485Schristos hex_string_custom (LONGEST num, int width)
2378dffb485Schristos {
2388dffb485Schristos   char *result = get_print_cell ();
2398dffb485Schristos   char *result_end = result + PRINT_CELL_SIZE - 1;
2408dffb485Schristos   const char *hex = phex_nz (num, sizeof (num));
2418dffb485Schristos   int hex_len = strlen (hex);
2428dffb485Schristos 
2438dffb485Schristos   if (hex_len > width)
2448dffb485Schristos     width = hex_len;
2458dffb485Schristos   if (width + 2 >= PRINT_CELL_SIZE)
2464b169a6bSchristos     internal_error (_("\
2478dffb485Schristos hex_string_custom: insufficient space to store result"));
2488dffb485Schristos 
2498dffb485Schristos   strcpy (result_end - width - 2, "0x");
2508dffb485Schristos   memset (result_end - width, '0', width);
2518dffb485Schristos   strcpy (result_end - hex_len, hex);
2528dffb485Schristos   return result_end - width - 2;
2538dffb485Schristos }
2548dffb485Schristos 
2558dffb485Schristos /* See print-utils.h.  */
2568dffb485Schristos 
257*5ba1f45fSchristos const char *
2588dffb485Schristos int_string (LONGEST val, int radix, int is_signed, int width,
2598dffb485Schristos 	    int use_c_format)
2608dffb485Schristos {
2618dffb485Schristos   switch (radix)
2628dffb485Schristos     {
2638dffb485Schristos     case 16:
2648dffb485Schristos       {
265*5ba1f45fSchristos 	const char *result;
2668dffb485Schristos 
2678dffb485Schristos 	if (width == 0)
2688dffb485Schristos 	  result = hex_string (val);
2698dffb485Schristos 	else
2708dffb485Schristos 	  result = hex_string_custom (val, width);
2718dffb485Schristos 	if (! use_c_format)
2728dffb485Schristos 	  result += 2;
2738dffb485Schristos 	return result;
2748dffb485Schristos       }
2758dffb485Schristos     case 10:
2768dffb485Schristos       {
2778dffb485Schristos 	if (is_signed && val < 0)
2784b169a6bSchristos 	  /* Cast to unsigned before negating, to prevent runtime error:
2794b169a6bSchristos 	     negation of -9223372036854775808 cannot be represented in type
2804b169a6bSchristos 	     'long int'; cast to an unsigned type to negate this value to
2814b169a6bSchristos 	     itself.  */
2824b169a6bSchristos 	  return decimal2str ("-", -(ULONGEST)val, width);
2838dffb485Schristos 	else
2848dffb485Schristos 	  return decimal2str ("", val, width);
2858dffb485Schristos       }
2868dffb485Schristos     case 8:
2878dffb485Schristos       {
2888dffb485Schristos 	char *result = octal2str (val, width);
2898dffb485Schristos 
2908dffb485Schristos 	if (use_c_format || val == 0)
2918dffb485Schristos 	  return result;
2928dffb485Schristos 	else
2938dffb485Schristos 	  return result + 1;
2948dffb485Schristos       }
2958dffb485Schristos     default:
2964b169a6bSchristos       internal_error (_("failed internal consistency check"));
2978dffb485Schristos     }
2988dffb485Schristos }
2998dffb485Schristos 
3008dffb485Schristos /* See print-utils.h.  */
3018dffb485Schristos 
3028dffb485Schristos const char *
3038dffb485Schristos core_addr_to_string (const CORE_ADDR addr)
3048dffb485Schristos {
3058dffb485Schristos   char *str = get_print_cell ();
3068dffb485Schristos 
3078dffb485Schristos   strcpy (str, "0x");
3088dffb485Schristos   strcat (str, phex (addr, sizeof (addr)));
3098dffb485Schristos   return str;
3108dffb485Schristos }
3118dffb485Schristos 
3128dffb485Schristos /* See print-utils.h.  */
3138dffb485Schristos 
3148dffb485Schristos const char *
3158dffb485Schristos core_addr_to_string_nz (const CORE_ADDR addr)
3168dffb485Schristos {
3178dffb485Schristos   char *str = get_print_cell ();
3188dffb485Schristos 
3198dffb485Schristos   strcpy (str, "0x");
3208dffb485Schristos   strcat (str, phex_nz (addr, sizeof (addr)));
3218dffb485Schristos   return str;
3228dffb485Schristos }
3238dffb485Schristos 
3248dffb485Schristos /* See print-utils.h.  */
3258dffb485Schristos 
3268dffb485Schristos const char *
3278dffb485Schristos host_address_to_string_1 (const void *addr)
3288dffb485Schristos {
3298dffb485Schristos   char *str = get_print_cell ();
3308dffb485Schristos 
3318dffb485Schristos   xsnprintf (str, PRINT_CELL_SIZE, "0x%s",
3328dffb485Schristos 	     phex_nz ((uintptr_t) addr, sizeof (addr)));
3338dffb485Schristos   return str;
3348dffb485Schristos }
335