summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils/gdb/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/binutils/gdb/utils.c')
-rw-r--r--gnu/usr.bin/binutils/gdb/utils.c364
1 files changed, 207 insertions, 157 deletions
diff --git a/gnu/usr.bin/binutils/gdb/utils.c b/gnu/usr.bin/binutils/gdb/utils.c
index 3bc5fed2a30..e30808c38b4 100644
--- a/gnu/usr.bin/binutils/gdb/utils.c
+++ b/gnu/usr.bin/binutils/gdb/utils.c
@@ -51,6 +51,7 @@
#include "charset.h"
#include "annotate.h"
#include "filenames.h"
+#include "symfile.h"
#include "inferior.h" /* for signed_pointer_to_address */
@@ -83,7 +84,7 @@ extern char *canonicalize_file_name (const char *);
/* readline defines this. */
#undef savestring
-void (*error_begin_hook) (void);
+void (*deprecated_error_begin_hook) (void);
/* Holds the last error message issued by gdb */
@@ -260,6 +261,19 @@ make_cleanup_ui_file_delete (struct ui_file *arg)
return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg);
}
+static void
+do_free_section_addr_info (void *arg)
+{
+ free_section_addr_info (arg);
+}
+
+struct cleanup *
+make_cleanup_free_section_addr_info (struct section_addr_info *addrs)
+{
+ return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs);
+}
+
+
struct cleanup *
make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function,
void *arg)
@@ -566,8 +580,8 @@ discard_all_intermediate_continuations (void)
void
vwarning (const char *string, va_list args)
{
- if (warning_hook)
- (*warning_hook) (string, args);
+ if (deprecated_warning_hook)
+ (*deprecated_warning_hook) (string, args);
else
{
target_terminal_ours ();
@@ -659,8 +673,8 @@ error_output_message (char *pre_print, char *msg)
NORETURN void
error_stream (struct ui_file *stream)
{
- if (error_begin_hook)
- error_begin_hook ();
+ if (deprecated_error_begin_hook)
+ deprecated_error_begin_hook ();
/* Copy the stream into the GDB_LASTERR buffer. */
ui_file_rewind (gdb_lasterr);
@@ -752,8 +766,8 @@ internal_vproblem (struct internal_problem *problem,
so that the user knows that they are living on the edge. */
{
char *msg;
- xvasprintf (&msg, fmt, ap);
- xasprintf (&reason, "\
+ msg = xstrvprintf (fmt, ap);
+ reason = xstrprintf ("\
%s:%d: %s: %s\n\
A problem internal to GDB has been detected,\n\
further debugging may prove unreliable.", file, line, problem->name, msg);
@@ -838,7 +852,7 @@ internal_error (const char *file, int line, const char *string, ...)
}
static struct internal_problem internal_warning_problem = {
- "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+ "internal-warning", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
};
void
@@ -974,51 +988,14 @@ void
request_quit (int signo)
{
quit_flag = 1;
- /* Restore the signal handler. Harmless with BSD-style signals, needed
- for System V-style signals. So just always do it, rather than worrying
- about USG defines and stuff like that. */
+ /* Restore the signal handler. Harmless with BSD-style signals,
+ needed for System V-style signals. */
signal (signo, request_quit);
if (immediate_quit)
quit ();
}
-/* Memory management stuff (malloc friends). */
-
-static void *
-mmalloc (void *md, size_t size)
-{
- return malloc (size); /* NOTE: GDB's only call to malloc() */
-}
-
-static void *
-mrealloc (void *md, void *ptr, size_t size)
-{
- if (ptr == 0) /* Guard against old realloc's */
- return mmalloc (md, size);
- else
- return realloc (ptr, size); /* NOTE: GDB's only call to ralloc() */
-}
-
-static void *
-mcalloc (void *md, size_t number, size_t size)
-{
- return calloc (number, size); /* NOTE: GDB's only call to calloc() */
-}
-
-static void
-mfree (void *md, void *ptr)
-{
- free (ptr); /* NOTE: GDB's only call to free() */
-}
-
-/* This used to do something interesting with USE_MMALLOC.
- * It can be retired any time. -- chastain 2004-01-19. */
-void
-init_malloc (void *md)
-{
-}
-
/* Called when a memory allocation fails, with the number of bytes of
memory requested in SIZE. */
@@ -1037,18 +1014,17 @@ nomem (long size)
}
}
-/* The xmmalloc() family of memory management routines.
+/* The xmalloc() (libiberty.h) family of memory management routines.
- These are are like the mmalloc() family except that they implement
+ These are like the ISO-C malloc() family except that they implement
consistent semantics and guard against typical memory management
- problems: if a malloc fails, an internal error is thrown; if
- free(NULL) is called, it is ignored; if *alloc(0) is called, NULL
- is returned.
+ problems. */
- All these routines are implemented using the mmalloc() family. */
+/* NOTE: These are declared using PTR to ensure consistency with
+ "libiberty.h". xfree() is GDB local. */
-void *
-xmmalloc (void *md, size_t size)
+PTR /* OK: PTR */
+xmalloc (size_t size)
{
void *val;
@@ -1057,15 +1033,15 @@ xmmalloc (void *md, size_t size)
if (size == 0)
size = 1;
- val = mmalloc (md, size);
+ val = malloc (size); /* OK: malloc */
if (val == NULL)
nomem (size);
return (val);
}
-void *
-xmrealloc (void *md, void *ptr, size_t size)
+PTR /* OK: PTR */
+xrealloc (PTR ptr, size_t size) /* OK: PTR */
{
void *val;
@@ -1075,17 +1051,17 @@ xmrealloc (void *md, void *ptr, size_t size)
size = 1;
if (ptr != NULL)
- val = mrealloc (md, ptr, size);
+ val = realloc (ptr, size); /* OK: realloc */
else
- val = mmalloc (md, size);
+ val = malloc (size); /* OK: malloc */
if (val == NULL)
nomem (size);
return (val);
}
-void *
-xmcalloc (void *md, size_t number, size_t size)
+PTR /* OK: PTR */
+xcalloc (size_t number, size_t size)
{
void *mem;
@@ -1097,7 +1073,7 @@ xmcalloc (void *md, size_t number, size_t size)
size = 1;
}
- mem = mcalloc (md, number, size);
+ mem = calloc (number, size); /* OK: xcalloc */
if (mem == NULL)
nomem (number * size);
@@ -1105,45 +1081,10 @@ xmcalloc (void *md, size_t number, size_t size)
}
void
-xmfree (void *md, void *ptr)
-{
- if (ptr != NULL)
- mfree (md, ptr);
-}
-
-/* The xmalloc() (libiberty.h) family of memory management routines.
-
- These are like the ISO-C malloc() family except that they implement
- consistent semantics and guard against typical memory management
- problems. See xmmalloc() above for further information.
-
- All these routines are wrappers to the xmmalloc() family. */
-
-/* NOTE: These are declared using PTR to ensure consistency with
- "libiberty.h". xfree() is GDB local. */
-
-PTR /* OK: PTR */
-xmalloc (size_t size)
-{
- return xmmalloc (NULL, size);
-}
-
-PTR /* OK: PTR */
-xrealloc (PTR ptr, size_t size) /* OK: PTR */
-{
- return xmrealloc (NULL, ptr, size);
-}
-
-PTR /* OK: PTR */
-xcalloc (size_t number, size_t size)
-{
- return xmcalloc (NULL, number, size);
-}
-
-void
xfree (void *ptr)
{
- xmfree (NULL, ptr);
+ if (ptr != NULL)
+ free (ptr); /* OK: free */
}
@@ -1156,7 +1097,7 @@ xstrprintf (const char *format, ...)
char *ret;
va_list args;
va_start (args, format);
- xvasprintf (&ret, format, args);
+ ret = xstrvprintf (format, args);
va_end (args);
return ret;
}
@@ -1166,27 +1107,32 @@ xasprintf (char **ret, const char *format, ...)
{
va_list args;
va_start (args, format);
- xvasprintf (ret, format, args);
+ (*ret) = xstrvprintf (format, args);
va_end (args);
}
void
xvasprintf (char **ret, const char *format, va_list ap)
{
- int status = vasprintf (ret, format, ap);
- /* NULL could be returned due to a memory allocation problem; a
- badly format string; or something else. */
- if ((*ret) == NULL)
- internal_error (__FILE__, __LINE__,
- "vasprintf returned NULL buffer (errno %d)", errno);
- /* A negative status with a non-NULL buffer shouldn't never
- happen. But to be sure. */
+ (*ret) = xstrvprintf (format, ap);
+}
+
+char *
+xstrvprintf (const char *format, va_list ap)
+{
+ char *ret = NULL;
+ int status = vasprintf (&ret, format, ap);
+ /* NULL is returned when there was a memory allocation problem. */
+ if (ret == NULL)
+ nomem (0);
+ /* A negative status (the printed length) with a non-NULL buffer
+ should never happen, but just to be sure. */
if (status < 0)
internal_error (__FILE__, __LINE__,
"vasprintf call failed (errno %d)", errno);
+ return ret;
}
-
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
@@ -1222,21 +1168,6 @@ savestring (const char *ptr, size_t size)
return p;
}
-char *
-msavestring (void *md, const char *ptr, size_t size)
-{
- char *p = (char *) xmmalloc (md, size + 1);
- memcpy (p, ptr, size);
- p[size] = 0;
- return p;
-}
-
-char *
-mstrsave (void *md, const char *ptr)
-{
- return (msavestring (md, ptr, strlen (ptr)));
-}
-
void
print_spaces (int n, struct ui_file *file)
{
@@ -1270,11 +1201,10 @@ query (const char *ctlstr, ...)
int ans2;
int retval;
- va_start (args, ctlstr);
-
- if (query_hook)
+ if (deprecated_query_hook)
{
- return query_hook (ctlstr, args);
+ va_start (args, ctlstr);
+ return deprecated_query_hook (ctlstr, args);
}
/* Automatically answer "yes" if input is not from a terminal. */
@@ -1289,7 +1219,9 @@ query (const char *ctlstr, ...)
if (annotation_level > 1)
printf_filtered ("\n\032\032pre-query\n");
+ va_start (args, ctlstr);
vfprintf_filtered (gdb_stdout, ctlstr, args);
+ va_end (args);
printf_filtered ("(y or n) ");
if (annotation_level > 1)
@@ -1372,9 +1304,9 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
n_string = "[n]";
}
- if (query_hook)
+ if (deprecated_query_hook)
{
- return query_hook (ctlstr, args);
+ return deprecated_query_hook (ctlstr, args);
}
/* Automatically answer default value if input is not from a terminal. */
@@ -1387,13 +1319,13 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
gdb_flush (gdb_stdout);
if (annotation_level > 1)
- printf_filtered ("\n\032\032pre-%cquery\n", defchar);
+ printf_filtered ("\n\032\032pre-query\n");
vfprintf_filtered (gdb_stdout, ctlstr, args);
printf_filtered ("(%s or %s) ", y_string, n_string);
if (annotation_level > 1)
- printf_filtered ("\n\032\032%cquery\n", defchar);
+ printf_filtered ("\n\032\032query\n");
wrap_here ("");
gdb_flush (gdb_stdout);
@@ -1437,7 +1369,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
}
if (annotation_level > 1)
- printf_filtered ("\n\032\032post-%cquery\n", defchar);
+ printf_filtered ("\n\032\032post-query\n");
return retval;
}
@@ -1855,12 +1787,7 @@ prompt_for_continue (void)
while (*p == ' ' || *p == '\t')
++p;
if (p[0] == 'q')
- {
- if (!event_loop_p)
- request_quit (SIGINT);
- else
- async_request_quit (0);
- }
+ async_request_quit (0);
xfree (ignore);
}
immediate_quit--;
@@ -2259,7 +2186,7 @@ vfprintf_maybe_filtered (struct ui_file *stream, const char *format,
char *linebuffer;
struct cleanup *old_cleanups;
- xvasprintf (&linebuffer, format, args);
+ linebuffer = xstrvprintf (format, args);
old_cleanups = make_cleanup (xfree, linebuffer);
fputs_maybe_filtered (linebuffer, stream, filter);
do_cleanups (old_cleanups);
@@ -2278,7 +2205,7 @@ vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
char *linebuffer;
struct cleanup *old_cleanups;
- xvasprintf (&linebuffer, format, args);
+ linebuffer = xstrvprintf (format, args);
old_cleanups = make_cleanup (xfree, linebuffer);
fputs_unfiltered (linebuffer, stream);
do_cleanups (old_cleanups);
@@ -2609,23 +2536,23 @@ initialize_utils (void)
c = add_set_cmd ("width", class_support, var_uinteger, &chars_per_line,
"Set number of characters gdb thinks are in a line.",
&setlist);
- add_show_from_set (c, &showlist);
+ deprecated_add_show_from_set (c, &showlist);
set_cmd_sfunc (c, set_width_command);
c = add_set_cmd ("height", class_support, var_uinteger, &lines_per_page,
"Set number of lines gdb thinks are in a page.", &setlist);
- add_show_from_set (c, &showlist);
+ deprecated_add_show_from_set (c, &showlist);
set_cmd_sfunc (c, set_height_command);
init_page_info ();
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("demangle", class_support, var_boolean,
(char *) &demangle,
"Set demangling of encoded C++/ObjC names when displaying symbols.",
&setprintlist), &showprintlist);
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("pagination", class_support,
var_boolean, (char *) &pagination_enabled,
"Set state of pagination.", &setlist), &showlist);
@@ -2638,13 +2565,13 @@ initialize_utils (void)
"Disable pagination");
}
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("sevenbit-strings", class_support, var_boolean,
(char *) &sevenbit_strings,
"Set printing of 8-bit characters in strings as \\nnn.",
&setprintlist), &showprintlist);
- add_show_from_set
+ deprecated_add_show_from_set
(add_set_cmd ("asm-demangle", class_support, var_boolean,
(char *) &asm_demangle,
"Set demangling of C++/ObjC names in disassembly listings.",
@@ -2659,7 +2586,7 @@ SIGWINCH_HANDLER_BODY
/* print routines to handle variable size regs, etc. */
/* temporary storage using circular buffer */
#define NUMCELLS 16
-#define CELLSIZE 32
+#define CELLSIZE 50
static char *
get_cell (void)
{
@@ -2689,7 +2616,7 @@ paddr_nz (CORE_ADDR addr)
}
static void
-decimal2str (char *paddr_str, char *sign, ULONGEST addr)
+decimal2str (char *paddr_str, char *sign, ULONGEST addr, int width)
{
/* steal code from valprint.c:print_decimal(). Should this worry
about the real size of addr as the above does? */
@@ -2700,18 +2627,60 @@ decimal2str (char *paddr_str, char *sign, ULONGEST addr)
temp[i] = addr % (1000 * 1000 * 1000);
addr /= (1000 * 1000 * 1000);
i++;
+ width -= 9;
+ }
+ while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+ width += 9;
+ if (width < 0)
+ width = 0;
+ switch (i)
+ {
+ case 1:
+ sprintf (paddr_str, "%s%0*lu", sign, width, temp[0]);
+ break;
+ case 2:
+ sprintf (paddr_str, "%s%0*lu%09lu", sign, width, temp[1], temp[0]);
+ break;
+ case 3:
+ sprintf (paddr_str, "%s%0*lu%09lu%09lu", sign, width,
+ temp[2], temp[1], temp[0]);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ "failed internal consistency check");
+ }
+}
+
+static void
+octal2str (char *paddr_str, ULONGEST addr, int width)
+{
+ unsigned long temp[3];
+ int i = 0;
+ do
+ {
+ temp[i] = addr % (0100000 * 0100000);
+ addr /= (0100000 * 0100000);
+ i++;
+ width -= 10;
}
while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0])));
+ width += 10;
+ if (width < 0)
+ width = 0;
switch (i)
{
case 1:
- sprintf (paddr_str, "%s%lu", sign, temp[0]);
+ if (temp[0] == 0)
+ sprintf (paddr_str, "%*o", width, 0);
+ else
+ sprintf (paddr_str, "0%0*lo", width, temp[0]);
break;
case 2:
- sprintf (paddr_str, "%s%lu%09lu", sign, temp[1], temp[0]);
+ sprintf (paddr_str, "0%0*lo%010lo", width, temp[1], temp[0]);
break;
case 3:
- sprintf (paddr_str, "%s%lu%09lu%09lu", sign, temp[2], temp[1], temp[0]);
+ sprintf (paddr_str, "0%0*lo%010lo%010lo", width,
+ temp[2], temp[1], temp[0]);
break;
default:
internal_error (__FILE__, __LINE__,
@@ -2723,7 +2692,7 @@ char *
paddr_u (CORE_ADDR addr)
{
char *paddr_str = get_cell ();
- decimal2str (paddr_str, "", addr);
+ decimal2str (paddr_str, "", addr, 0);
return paddr_str;
}
@@ -2732,9 +2701,9 @@ paddr_d (LONGEST addr)
{
char *paddr_str = get_cell ();
if (addr < 0)
- decimal2str (paddr_str, "-", -addr);
+ decimal2str (paddr_str, "-", -addr, 0);
else
- decimal2str (paddr_str, "", addr);
+ decimal2str (paddr_str, "", addr, 0);
return paddr_str;
}
@@ -2799,6 +2768,87 @@ phex_nz (ULONGEST l, int sizeof_l)
return str;
}
+/* Converts a LONGEST to a C-format hexadecimal literal and stores it
+ in a static string. Returns a pointer to this string. */
+char *
+hex_string (LONGEST num)
+{
+ char *result = get_cell ();
+ snprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
+ return result;
+}
+
+/* Converts a LONGEST number to a C-format hexadecimal literal and
+ stores it in a static string. Returns a pointer to this string
+ that is valid until the next call. The number is padded on the
+ left with 0s to at least WIDTH characters. */
+char *
+hex_string_custom (LONGEST num, int width)
+{
+ char *result = get_cell ();
+ char *result_end = result + CELLSIZE - 1;
+ const char *hex = phex_nz (num, sizeof (num));
+ int hex_len = strlen (hex);
+
+ if (hex_len > width)
+ width = hex_len;
+ if (width + 2 >= CELLSIZE)
+ internal_error (__FILE__, __LINE__,
+ "hex_string_custom: insufficient space to store result");
+
+ strcpy (result_end - width - 2, "0x");
+ memset (result_end - width, '0', width);
+ strcpy (result_end - hex_len, hex);
+ return result_end - width - 2;
+}
+
+/* Convert VAL to a numeral in the given radix. For
+ * radix 10, IS_SIGNED may be true, indicating a signed quantity;
+ * otherwise VAL is interpreted as unsigned. If WIDTH is supplied,
+ * it is the minimum width (0-padded if needed). USE_C_FORMAT means
+ * to use C format in all cases. If it is false, then 'x'
+ * and 'o' formats do not include a prefix (0x or leading 0). */
+
+char *
+int_string (LONGEST val, int radix, int is_signed, int width,
+ int use_c_format)
+{
+ switch (radix)
+ {
+ case 16:
+ {
+ char *result;
+ if (width == 0)
+ result = hex_string (val);
+ else
+ result = hex_string_custom (val, width);
+ if (! use_c_format)
+ result += 2;
+ return result;
+ }
+ case 10:
+ {
+ char *result = get_cell ();
+ if (is_signed && val < 0)
+ decimal2str (result, "-", -val, width);
+ else
+ decimal2str (result, "", val, width);
+ return result;
+ }
+ case 8:
+ {
+ char *result = get_cell ();
+ octal2str (result, val, width);
+ if (use_c_format || val == 0)
+ return result;
+ else
+ return result + 1;
+ }
+ default:
+ internal_error (__FILE__, __LINE__,
+ "failed internal consistency check");
+ }
+}
/* Convert a CORE_ADDR into a string. */
const char *