17d62b00eSchristos /* Shared general utility routines for GDB, the GNU debugger. 27d62b00eSchristos 3*6881a400Schristos Copyright (C) 1986-2023 Free Software Foundation, Inc. 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 "common-utils.h" 227d62b00eSchristos #include "host-defs.h" 23*6881a400Schristos #include "safe-ctype.h" 24*6881a400Schristos #include "gdbsupport/gdb-xfree.h" 257d62b00eSchristos 267d62b00eSchristos void * 277d62b00eSchristos xzalloc (size_t size) 287d62b00eSchristos { 297d62b00eSchristos return xcalloc (1, size); 307d62b00eSchristos } 317d62b00eSchristos 327d62b00eSchristos /* Like asprintf/vasprintf but get an internal_error if the call 337d62b00eSchristos fails. */ 347d62b00eSchristos 35*6881a400Schristos gdb::unique_xmalloc_ptr<char> 367d62b00eSchristos xstrprintf (const char *format, ...) 377d62b00eSchristos { 387d62b00eSchristos va_list args; 397d62b00eSchristos 407d62b00eSchristos va_start (args, format); 41*6881a400Schristos gdb::unique_xmalloc_ptr<char> ret = xstrvprintf (format, args); 427d62b00eSchristos va_end (args); 437d62b00eSchristos return ret; 447d62b00eSchristos } 457d62b00eSchristos 46*6881a400Schristos gdb::unique_xmalloc_ptr<char> 477d62b00eSchristos xstrvprintf (const char *format, va_list ap) 487d62b00eSchristos { 497d62b00eSchristos char *ret = NULL; 507d62b00eSchristos int status = vasprintf (&ret, format, ap); 517d62b00eSchristos 527d62b00eSchristos /* NULL is returned when there was a memory allocation problem, or 537d62b00eSchristos any other error (for instance, a bad format string). A negative 547d62b00eSchristos status (the printed length) with a non-NULL buffer should never 557d62b00eSchristos happen, but just to be sure. */ 567d62b00eSchristos if (ret == NULL || status < 0) 57*6881a400Schristos internal_error (_("vasprintf call failed")); 58*6881a400Schristos return gdb::unique_xmalloc_ptr<char> (ret); 597d62b00eSchristos } 607d62b00eSchristos 617d62b00eSchristos int 627d62b00eSchristos xsnprintf (char *str, size_t size, const char *format, ...) 637d62b00eSchristos { 647d62b00eSchristos va_list args; 657d62b00eSchristos int ret; 667d62b00eSchristos 677d62b00eSchristos va_start (args, format); 687d62b00eSchristos ret = vsnprintf (str, size, format, args); 697d62b00eSchristos gdb_assert (ret < size); 707d62b00eSchristos va_end (args); 717d62b00eSchristos 727d62b00eSchristos return ret; 737d62b00eSchristos } 747d62b00eSchristos 757d62b00eSchristos /* See documentation in common-utils.h. */ 767d62b00eSchristos 777d62b00eSchristos std::string 787d62b00eSchristos string_printf (const char* fmt, ...) 797d62b00eSchristos { 807d62b00eSchristos va_list vp; 817d62b00eSchristos int size; 827d62b00eSchristos 837d62b00eSchristos va_start (vp, fmt); 847d62b00eSchristos size = vsnprintf (NULL, 0, fmt, vp); 857d62b00eSchristos va_end (vp); 867d62b00eSchristos 877d62b00eSchristos std::string str (size, '\0'); 887d62b00eSchristos 897d62b00eSchristos /* C++11 and later guarantee std::string uses contiguous memory and 907d62b00eSchristos always includes the terminating '\0'. */ 917d62b00eSchristos va_start (vp, fmt); 927d62b00eSchristos vsprintf (&str[0], fmt, vp); /* ARI: vsprintf */ 937d62b00eSchristos va_end (vp); 947d62b00eSchristos 957d62b00eSchristos return str; 967d62b00eSchristos } 977d62b00eSchristos 987d62b00eSchristos /* See documentation in common-utils.h. */ 997d62b00eSchristos 1007d62b00eSchristos std::string 1017d62b00eSchristos string_vprintf (const char* fmt, va_list args) 1027d62b00eSchristos { 1037d62b00eSchristos va_list vp; 1047d62b00eSchristos size_t size; 1057d62b00eSchristos 1067d62b00eSchristos va_copy (vp, args); 1077d62b00eSchristos size = vsnprintf (NULL, 0, fmt, vp); 1087d62b00eSchristos va_end (vp); 1097d62b00eSchristos 1107d62b00eSchristos std::string str (size, '\0'); 1117d62b00eSchristos 1127d62b00eSchristos /* C++11 and later guarantee std::string uses contiguous memory and 1137d62b00eSchristos always includes the terminating '\0'. */ 1147d62b00eSchristos vsprintf (&str[0], fmt, args); /* ARI: vsprintf */ 1157d62b00eSchristos 1167d62b00eSchristos return str; 1177d62b00eSchristos } 1187d62b00eSchristos 1197d62b00eSchristos 1207d62b00eSchristos /* See documentation in common-utils.h. */ 1217d62b00eSchristos 122*6881a400Schristos std::string & 1237d62b00eSchristos string_appendf (std::string &str, const char *fmt, ...) 1247d62b00eSchristos { 1257d62b00eSchristos va_list vp; 1267d62b00eSchristos 1277d62b00eSchristos va_start (vp, fmt); 1287d62b00eSchristos string_vappendf (str, fmt, vp); 1297d62b00eSchristos va_end (vp); 130*6881a400Schristos 131*6881a400Schristos return str; 1327d62b00eSchristos } 1337d62b00eSchristos 1347d62b00eSchristos 1357d62b00eSchristos /* See documentation in common-utils.h. */ 1367d62b00eSchristos 137*6881a400Schristos std::string & 1387d62b00eSchristos string_vappendf (std::string &str, const char *fmt, va_list args) 1397d62b00eSchristos { 1407d62b00eSchristos va_list vp; 1417d62b00eSchristos int grow_size; 1427d62b00eSchristos 1437d62b00eSchristos va_copy (vp, args); 1447d62b00eSchristos grow_size = vsnprintf (NULL, 0, fmt, vp); 1457d62b00eSchristos va_end (vp); 1467d62b00eSchristos 1477d62b00eSchristos size_t curr_size = str.size (); 1487d62b00eSchristos str.resize (curr_size + grow_size); 1497d62b00eSchristos 1507d62b00eSchristos /* C++11 and later guarantee std::string uses contiguous memory and 1517d62b00eSchristos always includes the terminating '\0'. */ 1527d62b00eSchristos vsprintf (&str[curr_size], fmt, args); /* ARI: vsprintf */ 153*6881a400Schristos 154*6881a400Schristos return str; 1557d62b00eSchristos } 1567d62b00eSchristos 1577d62b00eSchristos char * 1587d62b00eSchristos savestring (const char *ptr, size_t len) 1597d62b00eSchristos { 1607d62b00eSchristos char *p = (char *) xmalloc (len + 1); 1617d62b00eSchristos 1627d62b00eSchristos memcpy (p, ptr, len); 1637d62b00eSchristos p[len] = 0; 1647d62b00eSchristos return p; 1657d62b00eSchristos } 1667d62b00eSchristos 1677d62b00eSchristos /* See documentation in common-utils.h. */ 1687d62b00eSchristos 1697d62b00eSchristos std::string 1707d62b00eSchristos extract_string_maybe_quoted (const char **arg) 1717d62b00eSchristos { 1727d62b00eSchristos bool squote = false; 1737d62b00eSchristos bool dquote = false; 1747d62b00eSchristos bool bsquote = false; 1757d62b00eSchristos std::string result; 1767d62b00eSchristos const char *p = *arg; 1777d62b00eSchristos 1787d62b00eSchristos /* Find the start of the argument. */ 1797d62b00eSchristos p = skip_spaces (p); 1807d62b00eSchristos 1817d62b00eSchristos /* Parse p similarly to gdb_argv buildargv function. */ 1827d62b00eSchristos while (*p != '\0') 1837d62b00eSchristos { 184*6881a400Schristos if (ISSPACE (*p) && !squote && !dquote && !bsquote) 1857d62b00eSchristos break; 1867d62b00eSchristos else 1877d62b00eSchristos { 1887d62b00eSchristos if (bsquote) 1897d62b00eSchristos { 1907d62b00eSchristos bsquote = false; 1917d62b00eSchristos result += *p; 1927d62b00eSchristos } 1937d62b00eSchristos else if (*p == '\\') 1947d62b00eSchristos bsquote = true; 1957d62b00eSchristos else if (squote) 1967d62b00eSchristos { 1977d62b00eSchristos if (*p == '\'') 1987d62b00eSchristos squote = false; 1997d62b00eSchristos else 2007d62b00eSchristos result += *p; 2017d62b00eSchristos } 2027d62b00eSchristos else if (dquote) 2037d62b00eSchristos { 2047d62b00eSchristos if (*p == '"') 2057d62b00eSchristos dquote = false; 2067d62b00eSchristos else 2077d62b00eSchristos result += *p; 2087d62b00eSchristos } 2097d62b00eSchristos else 2107d62b00eSchristos { 2117d62b00eSchristos if (*p == '\'') 2127d62b00eSchristos squote = true; 2137d62b00eSchristos else if (*p == '"') 2147d62b00eSchristos dquote = true; 2157d62b00eSchristos else 2167d62b00eSchristos result += *p; 2177d62b00eSchristos } 2187d62b00eSchristos p++; 2197d62b00eSchristos } 2207d62b00eSchristos } 2217d62b00eSchristos 2227d62b00eSchristos *arg = p; 2237d62b00eSchristos return result; 2247d62b00eSchristos } 2257d62b00eSchristos 2267d62b00eSchristos /* The bit offset of the highest byte in a ULONGEST, for overflow 2277d62b00eSchristos checking. */ 2287d62b00eSchristos 2297d62b00eSchristos #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT) 2307d62b00eSchristos 2317d62b00eSchristos /* True (non-zero) iff DIGIT is a valid digit in radix BASE, 2327d62b00eSchristos where 2 <= BASE <= 36. */ 2337d62b00eSchristos 2347d62b00eSchristos static int 2357d62b00eSchristos is_digit_in_base (unsigned char digit, int base) 2367d62b00eSchristos { 237*6881a400Schristos if (!ISALNUM (digit)) 2387d62b00eSchristos return 0; 2397d62b00eSchristos if (base <= 10) 240*6881a400Schristos return (ISDIGIT (digit) && digit < base + '0'); 2417d62b00eSchristos else 242*6881a400Schristos return (ISDIGIT (digit) || TOLOWER (digit) < base - 10 + 'a'); 2437d62b00eSchristos } 2447d62b00eSchristos 2457d62b00eSchristos static int 2467d62b00eSchristos digit_to_int (unsigned char c) 2477d62b00eSchristos { 248*6881a400Schristos if (ISDIGIT (c)) 2497d62b00eSchristos return c - '0'; 2507d62b00eSchristos else 251*6881a400Schristos return TOLOWER (c) - 'a' + 10; 2527d62b00eSchristos } 2537d62b00eSchristos 2547d62b00eSchristos /* As for strtoul, but for ULONGEST results. */ 2557d62b00eSchristos 2567d62b00eSchristos ULONGEST 2577d62b00eSchristos strtoulst (const char *num, const char **trailer, int base) 2587d62b00eSchristos { 2597d62b00eSchristos unsigned int high_part; 2607d62b00eSchristos ULONGEST result; 2617d62b00eSchristos int minus = 0; 2627d62b00eSchristos int i = 0; 2637d62b00eSchristos 2647d62b00eSchristos /* Skip leading whitespace. */ 265*6881a400Schristos while (ISSPACE (num[i])) 2667d62b00eSchristos i++; 2677d62b00eSchristos 2687d62b00eSchristos /* Handle prefixes. */ 2697d62b00eSchristos if (num[i] == '+') 2707d62b00eSchristos i++; 2717d62b00eSchristos else if (num[i] == '-') 2727d62b00eSchristos { 2737d62b00eSchristos minus = 1; 2747d62b00eSchristos i++; 2757d62b00eSchristos } 2767d62b00eSchristos 2777d62b00eSchristos if (base == 0 || base == 16) 2787d62b00eSchristos { 2797d62b00eSchristos if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X')) 2807d62b00eSchristos { 2817d62b00eSchristos i += 2; 2827d62b00eSchristos if (base == 0) 2837d62b00eSchristos base = 16; 2847d62b00eSchristos } 2857d62b00eSchristos } 2867d62b00eSchristos 2877d62b00eSchristos if (base == 0 && num[i] == '0') 2887d62b00eSchristos base = 8; 2897d62b00eSchristos 2907d62b00eSchristos if (base == 0) 2917d62b00eSchristos base = 10; 2927d62b00eSchristos 2937d62b00eSchristos if (base < 2 || base > 36) 2947d62b00eSchristos { 2957d62b00eSchristos errno = EINVAL; 2967d62b00eSchristos return 0; 2977d62b00eSchristos } 2987d62b00eSchristos 2997d62b00eSchristos result = high_part = 0; 3007d62b00eSchristos for (; is_digit_in_base (num[i], base); i += 1) 3017d62b00eSchristos { 3027d62b00eSchristos result = result * base + digit_to_int (num[i]); 3037d62b00eSchristos high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN); 3047d62b00eSchristos result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1; 3057d62b00eSchristos if (high_part > 0xff) 3067d62b00eSchristos { 3077d62b00eSchristos errno = ERANGE; 3087d62b00eSchristos result = ~ (ULONGEST) 0; 3097d62b00eSchristos high_part = 0; 3107d62b00eSchristos minus = 0; 3117d62b00eSchristos break; 3127d62b00eSchristos } 3137d62b00eSchristos } 3147d62b00eSchristos 3157d62b00eSchristos if (trailer != NULL) 3167d62b00eSchristos *trailer = &num[i]; 3177d62b00eSchristos 3187d62b00eSchristos result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN); 3197d62b00eSchristos if (minus) 3207d62b00eSchristos return -result; 3217d62b00eSchristos else 3227d62b00eSchristos return result; 3237d62b00eSchristos } 3247d62b00eSchristos 3257d62b00eSchristos /* See documentation in common-utils.h. */ 3267d62b00eSchristos 3277d62b00eSchristos char * 3287d62b00eSchristos skip_spaces (char *chp) 3297d62b00eSchristos { 3307d62b00eSchristos if (chp == NULL) 3317d62b00eSchristos return NULL; 332*6881a400Schristos while (*chp && ISSPACE (*chp)) 3337d62b00eSchristos chp++; 3347d62b00eSchristos return chp; 3357d62b00eSchristos } 3367d62b00eSchristos 3377d62b00eSchristos /* A const-correct version of the above. */ 3387d62b00eSchristos 3397d62b00eSchristos const char * 3407d62b00eSchristos skip_spaces (const char *chp) 3417d62b00eSchristos { 3427d62b00eSchristos if (chp == NULL) 3437d62b00eSchristos return NULL; 344*6881a400Schristos while (*chp && ISSPACE (*chp)) 3457d62b00eSchristos chp++; 3467d62b00eSchristos return chp; 3477d62b00eSchristos } 3487d62b00eSchristos 3497d62b00eSchristos /* See documentation in common-utils.h. */ 3507d62b00eSchristos 3517d62b00eSchristos const char * 3527d62b00eSchristos skip_to_space (const char *chp) 3537d62b00eSchristos { 3547d62b00eSchristos if (chp == NULL) 3557d62b00eSchristos return NULL; 356*6881a400Schristos while (*chp && !ISSPACE (*chp)) 3577d62b00eSchristos chp++; 3587d62b00eSchristos return chp; 3597d62b00eSchristos } 3607d62b00eSchristos 3617d62b00eSchristos /* See documentation in common-utils.h. */ 3627d62b00eSchristos 3637d62b00eSchristos char * 3647d62b00eSchristos skip_to_space (char *chp) 3657d62b00eSchristos { 3667d62b00eSchristos return (char *) skip_to_space ((const char *) chp); 3677d62b00eSchristos } 3687d62b00eSchristos 3697d62b00eSchristos /* See gdbsupport/common-utils.h. */ 3707d62b00eSchristos 3717d62b00eSchristos void 3727d62b00eSchristos free_vector_argv (std::vector<char *> &v) 3737d62b00eSchristos { 3747d62b00eSchristos for (char *el : v) 3757d62b00eSchristos xfree (el); 3767d62b00eSchristos 3777d62b00eSchristos v.clear (); 3787d62b00eSchristos } 3797d62b00eSchristos 3807d62b00eSchristos /* See gdbsupport/common-utils.h. */ 3817d62b00eSchristos 3827d62b00eSchristos ULONGEST 3837d62b00eSchristos align_up (ULONGEST v, int n) 3847d62b00eSchristos { 3857d62b00eSchristos /* Check that N is really a power of two. */ 3867d62b00eSchristos gdb_assert (n && (n & (n-1)) == 0); 3877d62b00eSchristos return (v + n - 1) & -n; 3887d62b00eSchristos } 3897d62b00eSchristos 3907d62b00eSchristos /* See gdbsupport/common-utils.h. */ 3917d62b00eSchristos 3927d62b00eSchristos ULONGEST 3937d62b00eSchristos align_down (ULONGEST v, int n) 3947d62b00eSchristos { 3957d62b00eSchristos /* Check that N is really a power of two. */ 3967d62b00eSchristos gdb_assert (n && (n & (n-1)) == 0); 3977d62b00eSchristos return (v & -n); 3987d62b00eSchristos } 399*6881a400Schristos 400*6881a400Schristos /* See gdbsupport/common-utils.h. */ 401*6881a400Schristos 402*6881a400Schristos int 403*6881a400Schristos fromhex (int a) 404*6881a400Schristos { 405*6881a400Schristos if (a >= '0' && a <= '9') 406*6881a400Schristos return a - '0'; 407*6881a400Schristos else if (a >= 'a' && a <= 'f') 408*6881a400Schristos return a - 'a' + 10; 409*6881a400Schristos else if (a >= 'A' && a <= 'F') 410*6881a400Schristos return a - 'A' + 10; 411*6881a400Schristos else 412*6881a400Schristos error (_("Invalid hex digit %d"), a); 413*6881a400Schristos } 414*6881a400Schristos 415*6881a400Schristos /* See gdbsupport/common-utils.h. */ 416*6881a400Schristos 417*6881a400Schristos int 418*6881a400Schristos hex2bin (const char *hex, gdb_byte *bin, int count) 419*6881a400Schristos { 420*6881a400Schristos int i; 421*6881a400Schristos 422*6881a400Schristos for (i = 0; i < count; i++) 423*6881a400Schristos { 424*6881a400Schristos if (hex[0] == 0 || hex[1] == 0) 425*6881a400Schristos { 426*6881a400Schristos /* Hex string is short, or of uneven length. 427*6881a400Schristos Return the count that has been converted so far. */ 428*6881a400Schristos return i; 429*6881a400Schristos } 430*6881a400Schristos *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); 431*6881a400Schristos hex += 2; 432*6881a400Schristos } 433*6881a400Schristos return i; 434*6881a400Schristos } 435*6881a400Schristos 436*6881a400Schristos /* See gdbsupport/common-utils.h. */ 437*6881a400Schristos 438*6881a400Schristos gdb::byte_vector 439*6881a400Schristos hex2bin (const char *hex) 440*6881a400Schristos { 441*6881a400Schristos size_t bin_len = strlen (hex) / 2; 442*6881a400Schristos gdb::byte_vector bin (bin_len); 443*6881a400Schristos 444*6881a400Schristos hex2bin (hex, bin.data (), bin_len); 445*6881a400Schristos 446*6881a400Schristos return bin; 447*6881a400Schristos } 448