You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
-#if !defined(__GO32__) && !defined(WIN32)
+#if !defined(__GO32__) && !defined(__WIN32__) && !defined(MPW)
#include <sys/ioctl.h>
#include <sys/param.h>
#include <pwd.h>
#include <varargs.h>
#endif
#include <ctype.h>
-#include <string.h>
+#include "gdb_string.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* Prototypes for local functions */
-#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK)
-#else
+static void vfprintf_maybe_filtered PARAMS ((FILE *, const char *, va_list, int));
-static void
-malloc_botch PARAMS ((void));
+static void fputs_maybe_filtered PARAMS ((const char *, FILE *, int));
-#endif /* NO_MMALLOC, etc */
+#if !defined (NO_MMALLOC) && !defined (NO_MMCHECK)
+static void malloc_botch PARAMS ((void));
+#endif
static void
fatal_dump_core PARAMS((char *, ...));
/* ARGSUSED */
void
null_cleanup (arg)
- char **arg;
+ PTR arg;
{
}
}
-#if defined(__GO32__)||defined(WIN32)
+#if defined(__GO32__)||defined(WINGDB)
/* In the absence of signals, poll keyboard for a quit.
Called from #define QUIT pollquit() in xm-go32.h. */
#endif
-#if defined(__GO32__)||defined(WIN32)
+#if defined(__GO32__)||defined(WINGDB)
void notice_quit()
{
if (kbhit ())
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. */
signal (signo, request_quit);
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC
+ target_kill ();
+#endif /* GENERAL_MAGIC */
+/* end-sanitize-gm */
+
#ifdef REQUEST_QUIT
REQUEST_QUIT;
#else
- if (immediate_quit)
+ if (immediate_quit)
quit ();
#endif
}
#endif /* NO_MMALLOC */
-#if defined (NO_MMALLOC) || defined (NO_MMALLOC_CHECK)
+#if defined (NO_MMALLOC) || defined (NO_MMCHECK)
void
init_malloc (md)
{
}
-#else /* have mmalloc and want corruption checking */
+#else /* Have mmalloc and want corruption checking */
static void
malloc_botch ()
by MD, to detect memory corruption. Note that MD may be NULL to specify
the default heap that grows via sbrk.
- Note that for freshly created regions, we must call mmcheck prior to any
+ Note that for freshly created regions, we must call mmcheckf prior to any
mallocs in the region. Otherwise, any region which was allocated prior to
installing the checking hooks, which is later reallocated or freed, will
fail the checks! The mmcheck function only allows initial hooks to be
Returns zero on failure, non-zero on success. */
+#ifndef MMCHECK_FORCE
+#define MMCHECK_FORCE 0
+#endif
+
void
init_malloc (md)
PTR md;
{
- if (!mmcheck (md, malloc_botch))
+ if (!mmcheckf (md, malloc_botch, MMCHECK_FORCE))
{
- warning ("internal error: failed to install memory consistency checks");
+ /* Don't use warning(), which relies on current_target being set
+ to something other than dummy_target, until after
+ initialize_all_files(). */
+
+ fprintf_unfiltered
+ (gdb_stderr, "warning: failed to install memory consistency checks; ");
+ fprintf_unfiltered
+ (gdb_stderr, "configuration should define NO_MMCHECK or MMCHECK_FORCE\n");
}
mmtrace ();
static void
vfprintf_maybe_filtered (stream, format, args, filter)
FILE *stream;
- char *format;
+ const char *format;
va_list args;
int filter;
{
void
vfprintf_filtered (stream, format, args)
FILE *stream;
- char *format;
+ const char *format;
va_list args;
{
vfprintf_maybe_filtered (stream, format, args, 1);
void
vfprintf_unfiltered (stream, format, args)
FILE *stream;
- char *format;
+ const char *format;
va_list args;
{
char *linebuffer;
void
vprintf_filtered (format, args)
- char *format;
+ const char *format;
va_list args;
{
vfprintf_maybe_filtered (gdb_stdout, format, args, 1);
void
vprintf_unfiltered (format, args)
- char *format;
+ const char *format;
va_list args;
{
vfprintf_unfiltered (gdb_stdout, format, args);
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintf_filtered (FILE *stream, char *format, ...)
+fprintf_filtered (FILE *stream, const char *format, ...)
#else
fprintf_filtered (va_alist)
va_dcl
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintf_unfiltered (FILE *stream, char *format, ...)
+fprintf_unfiltered (FILE *stream, const char *format, ...)
#else
fprintf_unfiltered (va_alist)
va_dcl
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-fprintfi_filtered (int spaces, FILE *stream, char *format, ...)
+fprintfi_filtered (int spaces, FILE *stream, const char *format, ...)
#else
fprintfi_filtered (va_alist)
va_dcl
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-printf_filtered (char *format, ...)
+printf_filtered (const char *format, ...)
#else
printf_filtered (va_alist)
va_dcl
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-printf_unfiltered (char *format, ...)
+printf_unfiltered (const char *format, ...)
#else
printf_unfiltered (va_alist)
va_dcl
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
-printfi_filtered (int spaces, char *format, ...)
+printfi_filtered (int spaces, const char *format, ...)
#else
printfi_filtered (va_alist)
va_dcl
void
puts_filtered (string)
- char *string;
+ const char *string;
{
fputs_filtered (string, gdb_stdout);
}
void
puts_unfiltered (string)
- char *string;
+ const char *string;
{
fputs_unfiltered (string, gdb_stdout);
}
/* These defaults will be used if we are unable to get the correct
values from termcap. */
-#if defined(__GO32__) || defined(WIN32)
+#if defined(__GO32__) || defined(__WIN32__)
lines_per_page = ScreenRows();
chars_per_line = ScreenCols();
#else
#ifdef SIGWINCH_HANDLER_BODY
SIGWINCH_HANDLER_BODY
#endif
+\f
+/* Support for converting target fp numbers into host DOUBLEST format. */
+
+/* XXX - This code should really be in libiberty/floatformat.c, however
+ configuration issues with libiberty made this very difficult to do in the
+ available time. */
+
+#include "floatformat.h"
+#include <math.h> /* ldexp */
+
+/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
+ going to bother with trying to muck around with whether it is defined in
+ a system header, what we do if not, etc. */
+#define FLOATFORMAT_CHAR_BIT 8
+
+static unsigned long get_field PARAMS ((unsigned char *,
+ enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int));
+
+/* Extract a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static unsigned long
+get_field (data, order, total_len, start, len)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+{
+ unsigned long result;
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ result = *(data + cur_byte) >> (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ /* This is the last byte; zero out the bits which are not part of
+ this field. */
+ result |=
+ (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
+ << cur_bitshift;
+ else
+ result |= *(data + cur_byte) << cur_bitshift;
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+ return result;
+}
+
+/* Convert from FMT to a DOUBLEST.
+ FROM is the address of the extended float.
+ Store the DOUBLEST in *TO. */
+
+void
+floatformat_to_doublest (fmt, from, to)
+ const struct floatformat *fmt;
+ char *from;
+ DOUBLEST *to;
+{
+ unsigned char *ufrom = (unsigned char *)from;
+ DOUBLEST dto;
+ long exponent;
+ unsigned long mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ int special_exponent; /* It's a NaN, denorm or zero */
+
+ exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ fmt->exp_start, fmt->exp_len);
+ /* Note that if exponent indicates a NaN, we can't really do anything useful
+ (not knowing if the host has NaN's, or how to build one). So it will
+ end up as an infinity or something close; that is OK. */
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ dto = 0.0;
+
+ special_exponent = exponent == 0 || exponent == fmt->exp_nan;
+
+/* Don't bias zero's, denorms or NaNs. */
+ if (!special_exponent)
+ exponent -= fmt->exp_bias;
+
+ /* Build the result algebraically. Might go infinite, underflow, etc;
+ who cares. */
+
+/* If this format uses a hidden bit, explicitly add it in now. Otherwise,
+ increment the exponent by one to account for the integer bit. */
+
+ if (!special_exponent)
+ if (fmt->intbit == floatformat_intbit_no)
+ dto = ldexp (1.0, exponent);
+ else
+ exponent++;
+
+ while (mant_bits_left > 0)
+ {
+ mant_bits = min (mant_bits_left, 32);
+
+ mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits);
+
+ dto += ldexp ((double)mant, exponent - mant_bits);
+ exponent -= mant_bits;
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+
+ /* Negate it if negative. */
+ if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
+ dto = -dto;
+ *to = dto;
+}
+\f
+static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
+ unsigned int,
+ unsigned int,
+ unsigned int,
+ unsigned long));
+
+/* Set a field which starts at START and is LEN bytes long. DATA and
+ TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
+static void
+put_field (data, order, total_len, start, len, stuff_to_put)
+ unsigned char *data;
+ enum floatformat_byteorders order;
+ unsigned int total_len;
+ unsigned int start;
+ unsigned int len;
+ unsigned long stuff_to_put;
+{
+ unsigned int cur_byte;
+ int cur_bitshift;
+
+ /* Start at the least significant part of the field. */
+ cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
+ cur_bitshift =
+ ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
+ *(data + cur_byte) &=
+ ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
+ *(data + cur_byte) |=
+ (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+
+ /* Move towards the most significant part of the field. */
+ while (cur_bitshift < len)
+ {
+ if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
+ {
+ /* This is the last byte. */
+ *(data + cur_byte) &=
+ ~((1 << (len - cur_bitshift)) - 1);
+ *(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
+ }
+ else
+ *(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
+ & ((1 << FLOATFORMAT_CHAR_BIT) - 1));
+ cur_bitshift += FLOATFORMAT_CHAR_BIT;
+ if (order == floatformat_little)
+ ++cur_byte;
+ else
+ --cur_byte;
+ }
+}
+
+#ifdef HAVE_LONG_DOUBLE
+/* Return the fractional part of VALUE, and put the exponent of VALUE in *EPTR.
+ The range of the returned value is >= 0.5 and < 1.0. This is equivalent to
+ frexp, but operates on the long double data type. */
+
+static long double ldfrexp PARAMS ((long double value, int *eptr));
+
+static long double
+ldfrexp (value, eptr)
+ long double value;
+ int *eptr;
+{
+ long double tmp;
+ int exp;
+
+ /* Unfortunately, there are no portable functions for extracting the exponent
+ of a long double, so we have to do it iteratively by multiplying or dividing
+ by two until the fraction is between 0.5 and 1.0. */
+
+ if (value < 0.0l)
+ value = -value;
+
+ tmp = 1.0l;
+ exp = 0;
+
+ if (value >= tmp) /* Value >= 1.0 */
+ while (value >= tmp)
+ {
+ tmp *= 2.0l;
+ exp++;
+ }
+ else if (value != 0.0l) /* Value < 1.0 and > 0.0 */
+ {
+ while (value < tmp)
+ {
+ tmp /= 2.0l;
+ exp--;
+ }
+ tmp *= 2.0l;
+ exp++;
+ }
+
+ *eptr = exp;
+ return value/tmp;
+}
+#endif /* HAVE_LONG_DOUBLE */
+
+
+/* The converse: convert the DOUBLEST *FROM to an extended float
+ and store where TO points. Neither FROM nor TO have any alignment
+ restrictions. */
+
+void
+floatformat_from_doublest (fmt, from, to)
+ CONST struct floatformat *fmt;
+ DOUBLEST *from;
+ char *to;
+{
+ DOUBLEST dfrom;
+ int exponent;
+ DOUBLEST mant;
+ unsigned int mant_bits, mant_off;
+ int mant_bits_left;
+ unsigned char *uto = (unsigned char *)to;
+
+ memcpy (&dfrom, from, sizeof (dfrom));
+ memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
+ if (dfrom == 0)
+ return; /* Result is zero */
+ if (dfrom != dfrom)
+ {
+ /* From is NaN */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
+ fmt->exp_len, fmt->exp_nan);
+ /* Be sure it's not infinity, but NaN value is irrel */
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
+ 32, 1);
+ return;
+ }
+
+ /* If negative, set the sign bit. */
+ if (dfrom < 0)
+ {
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
+ dfrom = -dfrom;
+ }
+
+ /* How to tell an infinity from an ordinary number? FIXME-someday */
+
+#ifdef HAVE_LONG_DOUBLE
+ mant = ldfrexp (dfrom, &exponent);
+#else
+ mant = frexp (dfrom, &exponent);
+#endif
+ put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
+ exponent + fmt->exp_bias - 1);
+
+ mant_bits_left = fmt->man_len;
+ mant_off = fmt->man_start;
+ while (mant_bits_left > 0)
+ {
+ unsigned long mant_long;
+ mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
+
+ mant *= 4294967296.0;
+ mant_long = (unsigned long)mant;
+ mant -= mant_long;
+
+ /* If the integer bit is implicit, then we need to discard it.
+ If we are discarding a zero, we should be (but are not) creating
+ a denormalized number which means adjusting the exponent
+ (I think). */
+ if (mant_bits_left == fmt->man_len
+ && fmt->intbit == floatformat_intbit_no)
+ {
+ mant_long &= 0x7fffffff;
+ mant_bits -= 1;
+ }
+ else if (mant_bits < 32)
+ {
+ /* The bits we want are in the most significant MANT_BITS bits of
+ mant_long. Move them to the least significant. */
+ mant_long >>= 32 - mant_bits;
+ }
+
+ put_field (uto, fmt->byteorder, fmt->totalsize,
+ mant_off, mant_bits, mant_long);
+ mant_off += mant_bits;
+ mant_bits_left -= mant_bits;
+ }
+}