Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ 2009, 2010 Free Software Foundation, Inc.
This file is part of GDB.
#include "event-top.h"
#include "exceptions.h"
#include "gdbthread.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
#ifdef TUI
#include "tui/tui.h" /* For tui_get_command_dimension. */
#include "gdb_obstack.h"
#include "gdbcore.h"
#include "top.h"
+#include "main.h"
#include "inferior.h" /* for signed_pointer_to_address */
#include <sys/time.h>
#include <time.h>
+#include "gdb_usleep.h"
+#include "interps.h"
+
#if !HAVE_DECL_MALLOC
-extern PTR malloc (); /* OK: PTR */
+extern PTR malloc (); /* ARI: PTR */
#endif
#if !HAVE_DECL_REALLOC
-extern PTR realloc (); /* OK: PTR */
+extern PTR realloc (); /* ARI: PTR */
#endif
#if !HAVE_DECL_FREE
extern void free ();
/* Prototypes for local functions */
static void vfprintf_maybe_filtered (struct ui_file *, const char *,
- va_list, int) ATTR_FORMAT (printf, 2, 0);
+ va_list, int) ATTRIBUTE_PRINTF (2, 0);
static void fputs_maybe_filtered (const char *, struct ui_file *, int);
do_close_cleanup (void *arg)
{
int *fd = arg;
+
close (*fd);
}
make_cleanup_close (int fd)
{
int *saved_fd = xmalloc (sizeof (fd));
+
*saved_fd = fd;
return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
}
do_fclose_cleanup (void *arg)
{
FILE *file = arg;
- fclose (arg);
+
+ fclose (file);
}
/* Return a new cleanup that closes FILE. */
do_obstack_free (void *arg)
{
struct obstack *ob = arg;
+
obstack_free (ob, NULL);
}
restore_integer (void *p)
{
struct restore_integer_closure *closure = p;
+
*(closure->variable) = closure->value;
}
{
struct restore_integer_closure *c =
xmalloc (sizeof (struct restore_integer_closure));
+
c->variable = variable;
c->value = *variable;
struct cleanup *old_chain)
{
struct cleanup *ptr;
+
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next; /* Do this first incase recursion */
struct cleanup *old_chain)
{
struct cleanup *ptr;
+
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
free_current_contents (void *ptr)
{
void **location = ptr;
+
if (location == NULL)
internal_error (__FILE__, __LINE__,
_("free_current_contents: NULL pointer"));
void
do_all_inferior_continuations (void)
{
- struct cleanup *old_chain;
struct cleanup *as_cleanup;
struct inferior *inf = current_inferior ();
discard_all_inferior_continuations (struct inferior *inf)
{
struct cleanup *continuation_ptr = &inf->continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
inf->continuations = NULL;
}
restore_thread_cleanup (void *arg)
{
ptid_t *ptid_p = arg;
+
switch_to_thread (*ptid_p);
}
void *data)
{
struct cleanup *continuation_ptr = &thread->continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
thread->continuations = NULL;
return 0;
void *data)
{
struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
thread->intermediate_continuations = NULL;
return 0;
warning (const char *string, ...)
{
va_list args;
+
va_start (args, string);
vwarning (string, args);
va_end (args);
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
-NORETURN void
+void
verror (const char *string, va_list args)
{
throw_verror (GENERIC_ERROR, string, args);
}
-NORETURN void
+void
error (const char *string, ...)
{
va_list args;
+
va_start (args, string);
throw_verror (GENERIC_ERROR, string, args);
va_end (args);
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
-NORETURN void
+void
vfatal (const char *string, va_list args)
{
throw_vfatal (string, args);
}
-NORETURN void
+void
fatal (const char *string, ...)
{
va_list args;
+
va_start (args, string);
throw_vfatal (string, args);
va_end (args);
}
-NORETURN void
+void
error_stream (struct ui_file *stream)
{
- long len;
- char *message = ui_file_xstrdup (stream, &len);
+ char *message = ui_file_xstrdup (stream, NULL);
+
make_cleanup (xfree, message);
error (("%s"), message);
}
+/* Dump core trying to increase the core soft limit to hard limit first. */
+
+static void
+dump_core (void)
+{
+#ifdef HAVE_SETRLIMIT
+ struct rlimit rlim = { RLIM_INFINITY, RLIM_INFINITY };
+
+ setrlimit (RLIMIT_CORE, &rlim);
+#endif /* HAVE_SETRLIMIT */
+
+ abort (); /* NOTE: GDB has only three calls to abort(). */
+}
+
+/* Check whether GDB will be able to dump core using the dump_core function. */
+
+static int
+can_dump_core (const char *reason)
+{
+#ifdef HAVE_GETRLIMIT
+ struct rlimit rlim;
+
+ /* Be quiet and assume we can dump if an error is returned. */
+ if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+ return 1;
+
+ if (rlim.rlim_max == 0)
+ {
+ fprintf_unfiltered (gdb_stderr,
+ _("%s\nUnable to dump core, use `ulimit -c unlimited'"
+ " before executing GDB next time.\n"), reason);
+ return 0;
+ }
+#endif /* HAVE_GETRLIMIT */
+
+ return 1;
+}
+
/* Allow the user to configure the debugger behavior with respect to
what to do when an internal problem is detected. */
internal_problem_no,
NULL
};
-static const char *internal_problem_mode = internal_problem_ask;
/* Print a message reporting an internal error/warning. Ask the user
if they want to continue, dump core, or just exit. Return
has been reported, and assuming GDB didn't quit, the caller can
either allow execution to resume or throw an error. */
-static void ATTR_FORMAT (printf, 4, 0)
+static void ATTRIBUTE_PRINTF (4, 0)
internal_vproblem (struct internal_problem *problem,
const char *file, int line, const char *fmt, va_list ap)
{
/* Don't allow infinite error/warning recursion. */
{
static char msg[] = "Recursive internal problem.\n";
+
switch (dejavu)
{
case 0:
case 1:
dejavu = 2;
fputs_unfiltered (msg, gdb_stderr);
- abort (); /* NOTE: GDB has only four calls to abort(). */
+ abort (); /* NOTE: GDB has only three calls to abort(). */
default:
dejavu = 3;
/* Newer GLIBC versions put the warn_unused_result attribute
does not fix this problem. This is the solution suggested
at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509. */
if (write (STDERR_FILENO, msg, sizeof (msg)) != sizeof (msg))
- abort (); /* NOTE: GDB has only four calls to abort(). */
+ abort (); /* NOTE: GDB has only three calls to abort(). */
exit (1);
}
}
so that the user knows that they are living on the edge. */
{
char *msg;
+
msg = xstrvprintf (fmt, ap);
reason = xstrprintf ("\
%s:%d: %s: %s\n\
/* Default (yes/batch case) is to quit GDB. When in batch mode
this lessens the likelihood of GDB going into an infinite
loop. */
- quit_p = query (_("%s\nQuit this debugging session? "), reason);
+ if (caution == 0)
+ {
+ /* Emit the message and quit. */
+ fputs_unfiltered (reason, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ quit_p = 1;
+ }
+ else
+ quit_p = query (_("%s\nQuit this debugging session? "), reason);
}
else if (problem->should_quit == internal_problem_yes)
quit_p = 1;
if (problem->should_dump_core == internal_problem_ask)
{
- /* Default (yes/batch case) is to dump core. This leaves a GDB
- `dropping' so that it is easier to see that something went
- wrong in GDB. */
- dump_core_p = query (_("%s\nCreate a core file of GDB? "), reason);
+ if (!can_dump_core (reason))
+ dump_core_p = 0;
+ else
+ {
+ /* Default (yes/batch case) is to dump core. This leaves a GDB
+ `dropping' so that it is easier to see that something went
+ wrong in GDB. */
+ dump_core_p = query (_("%s\nCreate a core file of GDB? "), reason);
+ }
}
else if (problem->should_dump_core == internal_problem_yes)
- dump_core_p = 1;
+ dump_core_p = can_dump_core (reason);
else if (problem->should_dump_core == internal_problem_no)
dump_core_p = 0;
else
if (quit_p)
{
if (dump_core_p)
- abort (); /* NOTE: GDB has only four calls to abort(). */
+ dump_core ();
else
exit (1);
}
{
#ifdef HAVE_WORKING_FORK
if (fork () == 0)
- abort (); /* NOTE: GDB has only four calls to abort(). */
+ dump_core ();
#endif
}
}
"internal-error", internal_problem_ask, internal_problem_ask
};
-NORETURN void
+void
internal_verror (const char *file, int line, const char *fmt, va_list ap)
{
internal_vproblem (&internal_error_problem, file, line, fmt, ap);
deprecated_throw_reason (RETURN_ERROR);
}
-NORETURN void
+void
internal_error (const char *file, int line, const char *string, ...)
{
va_list ap;
+
va_start (ap, string);
internal_verror (file, line, string, ap);
va_end (ap);
internal_warning (const char *file, int line, const char *string, ...)
{
va_list ap;
+
va_start (ap, string);
internal_vwarning (file, line, string, ap);
va_end (ap);
add_prefix_cmd ((char*) problem->name,
class_maintenance, set_internal_problem_cmd, set_doc,
set_cmd_list,
- concat ("maintenance set ", problem->name, " ", NULL),
+ concat ("maintenance set ", problem->name, " ",
+ (char *) NULL),
0/*allow-unknown*/, &maintenance_set_cmdlist);
add_prefix_cmd ((char*) problem->name,
class_maintenance, show_internal_problem_cmd, show_doc,
show_cmd_list,
- concat ("maintenance show ", problem->name, " ", NULL),
+ concat ("maintenance show ", problem->name, " ",
+ (char *) NULL),
0/*allow-unknown*/, &maintenance_show_cmdlist);
set_doc = xstrprintf (_("\
set_cmd_list,
show_cmd_list);
+ xfree (set_doc);
+ xfree (show_doc);
+
set_doc = xstrprintf (_("\
Set whether GDB should create a core file of GDB when %s is detected"),
problem->name);
NULL, /* showfunc */
set_cmd_list,
show_cmd_list);
+
+ xfree (set_doc);
+ xfree (show_doc);
}
/* Print the system error message for errno, and also mention STRING
as the file name for which the error was encountered.
Then return to command level. */
-NORETURN void
+void
perror_with_name (const char *string)
{
char *err;
/* Called when a memory allocation fails, with the number of bytes of
memory requested in SIZE. */
-NORETURN void
+void
nomem (long size)
{
if (size > 0)
/* NOTE: These are declared using PTR to ensure consistency with
"libiberty.h". xfree() is GDB local. */
-PTR /* OK: PTR */
+PTR /* ARI: PTR */
xmalloc (size_t size)
{
void *val;
if (size == 0)
size = 1;
- val = malloc (size); /* OK: malloc */
+ val = malloc (size); /* ARI: malloc */
if (val == NULL)
nomem (size);
return xcalloc (1, size);
}
-PTR /* OK: PTR */
-xrealloc (PTR ptr, size_t size) /* OK: PTR */
+PTR /* ARI: PTR */
+xrealloc (PTR ptr, size_t size) /* ARI: PTR */
{
void *val;
size = 1;
if (ptr != NULL)
- val = realloc (ptr, size); /* OK: realloc */
+ val = realloc (ptr, size); /* ARI: realloc */
else
- val = malloc (size); /* OK: malloc */
+ val = malloc (size); /* ARI: malloc */
if (val == NULL)
nomem (size);
return (val);
}
-PTR /* OK: PTR */
+PTR /* ARI: PTR */
xcalloc (size_t number, size_t size)
{
void *mem;
size = 1;
}
- mem = calloc (number, size); /* OK: xcalloc */
+ mem = calloc (number, size); /* ARI: xcalloc */
if (mem == NULL)
nomem (number * size);
xfree (void *ptr)
{
if (ptr != NULL)
- free (ptr); /* OK: free */
+ free (ptr); /* ARI: free */
}
\f
{
char *ret;
va_list args;
+
va_start (args, format);
ret = xstrvprintf (format, args);
va_end (args);
xasprintf (char **ret, const char *format, ...)
{
va_list args;
+
va_start (args, format);
(*ret) = xstrvprintf (format, args);
va_end (args);
{
char *ret = NULL;
int status = vasprintf (&ret, format, ap);
+
/* NULL is returned when there was a memory allocation problem, or
any other error (for instance, a bad format string). A negative
status (the printed length) with a non-NULL buffer should never
savestring (const char *ptr, size_t size)
{
char *p = (char *) xmalloc (size + 1);
+
memcpy (p, ptr, size);
p[size] = 0;
return p;
ARGS are the arguments passed along with the CTLSTR argument to
printf. */
-static int ATTR_FORMAT (printf, 1, 0)
+static int ATTRIBUTE_PRINTF (1, 0)
defaulted_query (const char *ctlstr, const char defchar, va_list args)
{
int answer;
}
/* Automatically answer the default value if the user did not want
- prompts. */
- if (! caution)
+ prompts or the command was issued with the server prefix. */
+ if (! caution || server_command)
return def_value;
/* If input isn't coming from the user directly, just say what
- question we're asking, and then answer "yes" automatically. This
+ question we're asking, and then answer the default automatically. This
way, important error messages don't get lost when talking to GDB
over a pipe. */
- if (! input_from_terminal_p ())
+ if (batch_flag || ! input_from_terminal_p ())
{
wrap_here ("");
vfprintf_filtered (gdb_stdout, ctlstr, args);
return def_value;
}
- /* Automatically answer the default value if input is not from the user
- directly, or if the user did not want prompts. */
- if (!input_from_terminal_p () || !caution)
- return def_value;
-
if (deprecated_query_hook)
{
return deprecated_query_hook (ctlstr, args);
gdb_flush (gdb_stdout);
answer = fgetc (stdin);
+
+ /* We expect fgetc to block until a character is read. But
+ this may not be the case if the terminal was opened with
+ the NONBLOCK flag. In that case, if there is nothing to
+ read on stdin, fgetc returns EOF, but also sets the error
+ condition flag on stdin and errno to EAGAIN. With a true
+ EOF, stdin's error condition flag is not set.
+
+ A situation where this behavior was observed is a pseudo
+ terminal on AIX. */
+ while (answer == EOF && ferror (stdin) && errno == EAGAIN)
+ {
+ /* Not a real EOF. Wait a little while and try again until
+ we read something. */
+ clearerr (stdin);
+ gdb_usleep (10000);
+ answer = fgetc (stdin);
+ }
+
clearerr (stdin); /* in case of C-d */
if (answer == EOF) /* C-d */
{
function returns 1. Otherwise, the function returns 0. */
static int
-host_char_to_target (int c, int *target_c)
+host_char_to_target (struct gdbarch *gdbarch, int c, int *target_c)
{
struct obstack host_data;
char the_char = c;
obstack_init (&host_data);
cleanups = make_cleanup_obstack_free (&host_data);
- convert_between_encodings (target_charset (), host_charset (),
+ convert_between_encodings (target_charset (gdbarch), host_charset (),
&the_char, 1, 1, &host_data, translit_none);
if (obstack_object_size (&host_data) == 1)
after the zeros. A value of 0 does not mean end of string. */
int
-parse_escape (char **string_ptr)
+parse_escape (struct gdbarch *gdbarch, char **string_ptr)
{
int target_char = -2; /* initialize to avoid GCC warnings */
int c = *(*string_ptr)++;
+
switch (c)
{
case '\n':
break;
}
- if (!host_char_to_target (c, &target_char))
+ if (!host_char_to_target (gdbarch, c, &target_char))
error
("The escape sequence `\%c' is equivalent to plain `%c', which"
" has no equivalent\n" "in the `%s' character set.", c, c,
- target_charset ());
+ target_charset (gdbarch));
return target_char;
}
\f
void (*do_fprintf) (struct ui_file *, const char *, ...)
ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter)
{
-
c &= 0xFF; /* Avoid sign bit follies */
if (c < 0x20 || /* Low control chars */
struct ui_file *stream)
{
int i;
+
for (i = 0; i < n; i++)
printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
}
struct ui_file *stream)
{
int i;
+
for (i = 0; i < n; i++)
printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
}
if (ignore)
{
char *p = ignore;
+
while (*p == ' ' || *p == '\t')
++p;
if (p[0] == 'q')
return;
/* Don't do any filtering if it is disabled. */
- if ((stream != gdb_stdout) || !pagination_enabled
- || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX))
+ if (stream != gdb_stdout
+ || !pagination_enabled
+ || (lines_per_page == UINT_MAX && chars_per_line == UINT_MAX)
+ || top_level_interpreter () == NULL
+ || ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
{
fputs_unfiltered (linebuffer, stream);
return;
putchar_unfiltered (int c)
{
char buf = c;
+
ui_file_write (gdb_stdout, &buf, 1);
return c;
}
fputc_unfiltered (int c, struct ui_file *stream)
{
char buf = c;
+
ui_file_write (stream, &buf, 1);
return c;
}
fprintf_filtered (struct ui_file *stream, const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_filtered (stream, format, args);
va_end (args);
fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_unfiltered (stream, format, args);
va_end (args);
...)
{
va_list args;
+
va_start (args, format);
print_spaces_filtered (spaces, stream);
printf_filtered (const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_filtered (gdb_stdout, format, args);
va_end (args);
printf_unfiltered (const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_unfiltered (gdb_stdout, format, args);
va_end (args);
printfi_filtered (int spaces, const char *format, ...)
{
va_list args;
+
va_start (args, format);
print_spaces_filtered (spaces, gdb_stdout);
vfprintf_filtered (gdb_stdout, format, args);
subset_compare (char *string_to_compare, char *template_string)
{
int match;
+
if (template_string != (char *) NULL && string_to_compare != (char *) NULL
&& strlen (string_to_compare) <= strlen (template_string))
match =
void
initialize_utils (void)
{
- struct cmd_list_element *c;
-
add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
Set number of characters gdb thinks are in a line."), _("\
Show number of characters gdb thinks are in a line."), NULL,
{
static char buf[NUMCELLS][CELLSIZE];
static int cell = 0;
+
if (++cell >= NUMCELLS)
cell = 0;
return buf[cell];
}
-int
-strlen_paddr (void)
-{
- return (gdbarch_addr_bit (current_gdbarch) / 8 * 2);
-}
-
-char *
-paddr (CORE_ADDR addr)
-{
- return phex (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
-char *
-paddr_nz (CORE_ADDR addr)
-{
- return phex_nz (addr, gdbarch_addr_bit (current_gdbarch) / 8);
-}
-
const char *
-paddress (CORE_ADDR addr)
+paddress (struct gdbarch *gdbarch, CORE_ADDR addr)
{
/* Truncate address to the size of a target address, avoiding shifts
larger or equal than the width of a CORE_ADDR. The local
either zero or sign extended. Should gdbarch_address_to_pointer or
some ADDRESS_TO_PRINTABLE() be used to do the conversion? */
- int addr_bit = gdbarch_addr_bit (current_gdbarch);
+ int addr_bit = gdbarch_addr_bit (gdbarch);
if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
about the real size of addr as the above does? */
unsigned long temp[3];
char *str = get_cell ();
-
int i = 0;
+
do
{
temp[i] = addr % (1000 * 1000 * 1000);
{
unsigned long temp[3];
char *str = get_cell ();
-
int i = 0;
+
do
{
temp[i] = addr % (0100000 * 0100000);
case 8:
{
unsigned long high = (unsigned long) (l >> thirty_two);
+
str = get_cell ();
if (high == 0)
xsnprintf (str, CELLSIZE, "%lx",
hex_string (LONGEST num)
{
char *result = get_cell ();
+
xsnprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
return result;
}
case 16:
{
char *result;
+
if (width == 0)
result = hex_string (val);
else
case 8:
{
char *result = octal2str (val, width);
+
if (use_c_format || val == 0)
return result;
else
core_addr_to_string (const CORE_ADDR addr)
{
char *str = get_cell ();
+
strcpy (str, "0x");
strcat (str, phex (addr, sizeof (addr)));
return str;
core_addr_to_string_nz (const CORE_ADDR addr)
{
char *str = get_cell ();
+
strcpy (str, "0x");
strcat (str, phex_nz (addr, sizeof (addr)));
return str;
CORE_ADDR
string_to_core_addr (const char *my_string)
{
- int addr_bit = gdbarch_addr_bit (current_gdbarch);
CORE_ADDR addr = 0;
if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
{
/* Assume that it is in hex. */
int i;
+
for (i = 2; my_string[i] != '\0'; i++)
{
if (isdigit (my_string[i]))
else
error (_("invalid hex \"%s\""), my_string);
}
-
- /* Not very modular, but if the executable format expects
- addresses to be sign-extended, then do so if the address was
- specified with only 32 significant bits. Really this should
- be determined by the target architecture, not by the object
- file. */
- if (i - 2 == addr_bit / 4
- && exec_bfd
- && bfd_get_sign_extend_vma (exec_bfd))
- addr = (addr ^ ((CORE_ADDR) 1 << (addr_bit - 1)))
- - ((CORE_ADDR) 1 << (addr_bit - 1));
}
else
{
/* Assume that it is in decimal. */
int i;
+
for (i = 0; my_string[i] != '\0'; i++)
{
if (isdigit (my_string[i]))
# endif
# if defined (USE_REALPATH)
const char *rp = realpath (filename, buf);
+
if (rp == NULL)
rp = filename;
return xstrdup (rp);
#if defined(HAVE_CANONICALIZE_FILE_NAME)
{
char *rp = canonicalize_file_name (filename);
+
if (rp == NULL)
return xstrdup (filename);
else
{
/* Find out the max path size. */
long path_max = pathconf ("/", _PC_PATH_MAX);
+
if (path_max > 0)
{
/* PATH_MAX is bounded. */
char *buf = alloca (path_max);
char *rp = realpath (filename, buf);
+
return xstrdup (rp ? rp : filename);
}
}
directory separator, avoid doubling it. */
real_path = gdb_realpath (dir_name);
if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
- result = concat (real_path, base_name, (char *)NULL);
+ result = concat (real_path, base_name, (char *) NULL);
else
- result = concat (real_path, SLASH_STRING, base_name, (char *)NULL);
+ result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
xfree (real_path);
return result;
unsigned long
gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
{
- static const unsigned long crc32_table[256] = {
+ static const unsigned int crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
{
unsigned int total = size * count;
void *ptr = obstack_alloc ((struct obstack *) data, total);
+
memset (ptr, 0, total);
return ptr;
}
gdb_buildargv (const char *s)
{
char **argv = buildargv (s);
+
if (s != NULL && argv == NULL)
nomem (0);
return argv;
}
+int
+compare_positive_ints (const void *ap, const void *bp)
+{
+ /* Because we know we're comparing two ints which are positive,
+ there's no danger of overflow here. */
+ return * (int *) ap - * (int *) bp;
+}
+
+#define AMBIGUOUS_MESS1 ".\nMatching formats:"
+#define AMBIGUOUS_MESS2 ".\nUse \"set gnutarget format-name\" to specify the format."
+
+const char *
+gdb_bfd_errmsg (bfd_error_type error_tag, char **matching)
+{
+ char *ret, *retp;
+ int ret_len;
+ char **p;
+
+ /* Check if errmsg just need simple return. */
+ if (error_tag != bfd_error_file_ambiguously_recognized || matching == NULL)
+ return bfd_errmsg (error_tag);
+
+ ret_len = strlen (bfd_errmsg (error_tag)) + strlen (AMBIGUOUS_MESS1)
+ + strlen (AMBIGUOUS_MESS2);
+ for (p = matching; *p; p++)
+ ret_len += strlen (*p) + 1;
+ ret = xmalloc (ret_len + 1);
+ retp = ret;
+ make_cleanup (xfree, ret);
+
+ strcpy (retp, bfd_errmsg (error_tag));
+ retp += strlen (retp);
+
+ strcpy (retp, AMBIGUOUS_MESS1);
+ retp += strlen (retp);
+
+ for (p = matching; *p; p++)
+ {
+ sprintf (retp, " %s", *p);
+ retp += strlen (retp);
+ }
+ xfree (matching);
+
+ strcpy (retp, AMBIGUOUS_MESS2);
+
+ return ret;
+}
+
+/* Return ARGS parsed as a valid pid, or throw an error. */
+
+int
+parse_pid_to_attach (char *args)
+{
+ unsigned long pid;
+ char *dummy;
+
+ if (!args)
+ error_no_arg (_("process-id to attach"));
+
+ dummy = args;
+ pid = strtoul (args, &dummy, 0);
+ /* Some targets don't set errno on errors, grrr! */
+ if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
+ error (_("Illegal process-id: %s."), args);
+
+ return pid;
+}
+
/* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_utils;